-smooth is a general purpose blurring engine which can dynamically adjust the eccentricity and orientation of a conical diffusion kernel under the control of a tensor field.

In its first form, smooth generates its own tensor field, one geared to reducing noise in the selected images by way of an anisotropic smoothing scheme.

In its second form, invoked when given an explicit tensor field, -smooth implements a variable blurring tool under the control of the tensor field. See "Do Your Own Diffusion Tensor Field" for particular techniques employing this second form.

Even when harnessed in its first form, -smooth does not directly implement anisotropic smoothing. Instead, the command internally invokes -structuretensors and -diffusiontensors, the G'MIC commands for oriented edge detection and the development of a corresponding* smoothing geometry*, manifested through a diffusion tensor field. This field then directs -smooth in its subsequent operation. Thus -smooth is first and formost a smoothing engine which defaults to an anisotropic smoothing tool when not asked to do otherwise.

The tensor field produced by -diffusiontensors has the same dimensions as the operand image, and for each pixel in the operand, the field furnishes a corresponding *tensor*, an object that prescribes a blurring kernel, elliptical in character, tailored specifically for the operand pixel's locale (see -convolve) and constructed to preserve local features while minimizing local aberrations from those features. The non-uniform character of this blurring kernel, adapted to preserving local features, gives rise to the term *anisotropic smoothing*. The tensor establishes the size, eccentricity and orientation of this blurring kernel. See -structuretensors and -diffusiontensors for further details.

Both forms employ one of two regularization schemes. Choosing a positive angular discretization increment induces the Linear Integral Curves (LIC) method, the default. Setting this parameter to zero induces the Iterated Laplacian Method, which change the interpretation of some parameters. Details follow:

**Anisotropic Smoothing - Line Integral Convolution Method***amplitude*(iterations: Laplacian Method) >=0 The command's one required parameter, regulates the amount of diffusion. Values in excess of 100 can cause distortions which are either unpleasant or artistic, depending on one's intents. This is particularly true when the ansiotropy setting also nears unity. When interests run primarily to preserving geometry, but removing noise, values around 1 → 50 generally suffice. Trials should begin with small values; increase as needed. Processing time increases with larger amplitudes, without necessarily inducing an improvement in smoothing quality. The value used in the Moorish Girl image was 10.*sharpness*: >= 0.0 Optional and defaults to 0.7. Increasing values diminishes shape-adapted smoothing in the vicinity of edges, preserving small scale detail, but settings in excess of 1.0 largely suppress anisotropic smoothing and tends to preserve noise. The Moorish Girl image was filtered with a sharpness of 0.1.*anisotropy*: range: 1.0 ≥*a*≥ 0.0. Optional and defaults to 0.3. When large, shape-adapted smoothing dominates; noise is reduced by kernels which become elongated and oriented in parallel to edges. Smaller values permit omnidirectional diffusion to dominate. Ansiotropy values near unity often causes "false edges" to be detected in noise, creating sinuous, hairlike artifacts. This effect becomes especially pronounced for amplitudes around or in excess of 100. The setting for the Moorish Girl was 0.8.*alpha:*Pre-structure blur variance. Gaussian variance σ_{0}≥ 0. Optional and defaults to 0.6 -smooth harnesses. -structuretensors for oriented edge detection. Before calling this command, -smooth applies a conventional isotropic Gaussian blur to the operand image; this parameter sets the variance, σ, for that operation. The setting for the Moorish Girl was 1.0.*sigma:*Post-structure blur filter. Gaussian variance σ_{1}≥ 0. Optional and defaults to 1.1. Following its call to -structuretensors, -smooth blurs the tensor field it obtained from that command; this parameter sets the variance σ, for that operation. Larger values of sigma tend to favor large-scale laminar smoothing over localized 'eddy' smoothing. The setting for the Moorish Girl was 4.0*dl*: spatial discretization increment (dt: 'temporal step' increment – Laplacian Method) > 0. Optional, and defaults to 0.8 pixels. As a practical matter, the constrained Partial Differential Equation (PDE) which -smooth implements evaluates terms along successive spatial (quantified in pixels) and angular steps (quantified in degrees). This parameter sets the size of the spatial step. Smaller values improve the resolution of how -smooth averages values, which can increase the quality of smoothing but at the cost of processing time, which can increase dramatically. Decreasing the spatial step to very small values gives no promise of improved appearance – behind the scenes diminishing return relations are at work – but will certainly increase processing time. Unless artifacts are manifest, often herringbone or 'zebra stripe' patterns, one should stay with the default spatial step size. The Moorish Girl used the default 0.8 value. See "Sampling" for further details.*da*: angular discretization increment, degrees (zero selects Iterated Laplacian Method) > 0°. Optional, and defaults to 30°. (See also, spatial discretization increment, above). This parameter sets the size of the angular step and is incremented in degrees. As with the spatial step, above, smaller values*may*improve the quality of the smoothing, but then again, maybe not. The only guarantee is that processing time will dramatically increase. Where smaller angular steps can matter are in near-homogeneous regions where colors or values change only in very small amounts over distance. If artifacts appear in such areas, decreasing the angular step a few degrees may help. The Moorish Girl used the default angular step of 30°. See "Sampling" below, for further details. Setting this value to 0° changes the diffusion strategy from one based on integral convolution to a Laplacian-based scheme, changing the sense of a number of parameters. See "Iterated Laplacian Method" below.*precision*: Sets precision of the diffusion process > 0. Optional, and defaults to 2.*interpolation:*Among explicitly computed values, -smooth will interpolate values. 0: nearest, -smooth takes the value from the single nearest value. 1: linear -smooth uses a linear ramp between two sample points. 2: chooses a second order Runge-Kutta method.*fast_approx*: At various places in its operation, -smooth samples the standard gaussian curve, or a reasonable approximation of the same that is quick to compute. 1, the default, puts the approximation in play, otherwise (0) the Gaussian itself is used,

**Ansiotropic Smoothing - Iterated Laplacian Method***nb_iterations*: sets the number of iterations of the method. Diffusion increases with a larger number of steps, leading to a better solution up to a limit, especially with a concomittant increase in the temporal step. However, with a large temporal step and a high number of iterations, "checkerboard" stipple patterns invade the image, patches with pixels alternating between positive and negative values. The number of iterations and/or the step size are too large.*sharpness, anisotropy, alpha, sigma:*These parameters are unchanged with this method.*dt:*temporal step (*dl*: spatial discretization increment - L. I. C.) > 0 Sets the step size. As dt is set to larger steps, a greater amount of diffusion occurs in each step, but, beyond a certain step size artifacts appear. See nb_iterations for details.- 0 (
*da*: angular discretion increment - L. I. C) setting this parameter to zero both sets the iterated Laplacian method and signals the end of the parameter list. - precision, interpolation, and fast_approx are not used with the iterated Laplacian method.

**General Smoothing - Line Integral Convolution Method***[tensor field]*When the first parameter is a selector referencing another image on the list, -smooth does not invoke -diffusiontensors but, instead, uses the provided tensor field on the operand images. This can be a means to introduce an alternate diffusion tensor field produced by another algorithm, some functional equivalent of -diffusiontensors, or the tensor field may be of arbitrary character. That said, there are certain constraints placed on this tensor field. See Do Your Own Diffusion Tensor Fields in the Cookbook section.*amplitude*: This parameter sets the diffusion amplitude. It is equvalent to its namesake described in, above.**Anisotropic Smoothing - Line Integral Convolution Method***sharpness, anisotropy, alpha, sigma:*These parameters are not used in general smoothing.*dl - spatial discretization, da - angular discretization, precision, interpolation and fast_appox*are equivalent to their namesakes described in, above.**Anisotropic Smoothing - Line Integral Convolution Method**

**General Smoothing - Iterated Laplacian Method***[tensor field]*-smooth uses the furnished tensor field. Seeabove.**General Smoothing - Line Integral Convolution Method***nb_iterations*: sets the number of iterations of the method. See**Ansiotropic Smoothing - Iterated Laplacian Method***dt:*temporal step: Sets the step size.See**Ansiotropic Smoothing - Iterated Laplacian Method**- 0: zero, signals the end of the parameter list.

The G'MIC pipeline:

`$gmic 256,256,1,1 \ -set[-1] 1,127,127,0,0 \ '(1^0^1)' -resize[-1] [0],[0],[-1],[-1],1 \ -smooth[-2] [-1],100,5.0,45.0 \ -rm[-1] \ -cut[-1] 0,0.004 \ -normalize[-1] 0,255`

makes a picture of the inner workings of the -smooth command; in particular, it illustrates how spatial and angular discretization diffuse an impulse over an image. To be sure, we essentially grabbed a pitchfork and forced -smooth against the wall, subjecting it to a number of severe boundary conditions. It's not pretty, some of the things we have to do in the G'MIC documentation project. I'm sure it will catch up with us. When the time comes, we'll plead that it was all in the interest of Science.

Here's the littany of nasties. We made a one pixel impulse image, a standard stress test of any signal processing system - that's the bit above about setting one pixel at unit one in a field of zero-valued pixels. Next we made a quick-and-dirty tensor field filled entirely with identity matrices - that's the bit above about resizing the one pixel image `'(1^0^1)'`

to the size of the impulse image. We then passed the tensor field of identity tensors off to -smooth and told it to deal with the impulse. If some of this G'MICry seems odd to you, spend some time with gmic_stdlibs.gmic. We learned all our tricks there. Well, most of them.

Here's the deal. The eigenvalues of the identity matrix are 1, one eigenvector runs at 0°, the other at 90° and this tensor gets associated with every pixel in the operand image. All are zero-valued, save one, the one we explicitly set to one at pixel coordinates (127,127). The identity tensor associated with this pixel, with equal, unit-size eigenvectors, induce smooth to diffuse the pixel omnidirectionally out to neighboring pixels.

Ideally, diffusion is a continuous process, but pixels live in the discrete world, as does the machinery of -smooth. The discrete approximation of the diffusion outward involves both spatial and angular steps. We set these steps as parameters to -smooth. In this particular case, the spatial step size is five pixels and the angular step size is 45°.

Consider the central 64 x 64 pixel portion of the image produced by the gmic pipeline, given above, scaled 4 times. The most striking aspect of the image is the radial pattern, arms at 45° degree increments. Less obvious are the distances separating the pixels arrayed along the arms. Center to center distances, along the vertical and horizontal arms are exactly five pixels. This is less true along the diagonals because where pixels *should* go do not align exactly with the unit pixel grid, so, understandably there are errors along the diagonal marks as these pixels shift into pigeonholes where they do not quite belong.

Some of you may be thinking: "Holy cow! this isn't anything close to an approximatioin of diffusion!" Some of you may be thinking of setting the angular step to fractions of a degree and the spatial step to tenths of a pixel. That's a good way to get -smooth to run all night. Recall, now that we deliberately, with malice and forethought, backed -smooth against the wall with a pitchfork of extreme boundary conditions. Most images do not consist of isolated bright pixels in vast fields of black; images generally consist of many non-zero pixels, so the rosette pattern multiplexes throughout typical images. The tensor field of identity matrices is also very untypical; generally, diffusion tensor fields engender rosettes of varying size, eccentricity and orientation, fragmenting the regularity of the pattern surrounding the isolated impulse.

In addition, it is not uncommon to run -smooth in a -repeat … -done loop, generally to beneficial effect. In cases where -smooth generates its own diffusion tensor field, the loop induces the command to recalculate its diffusiontensor field on each pass, and the consequences of the previous run are reinforced in the next. To illustrate, modify the pipeline with this new line, `-repeat 3 smooth[-2] [-1],100,5.0,45.0 -done`. and extract the same central 64 × 64 region for purposes of comparison:

Generally, pixels set to a non-zero value in one pass sprout rosettes in the next pass, the aggregate converging to the ideal diffusion pattern.* *

*Garry Osgood*