## convolution

convolution — convolve and correlate images

## Stability Level

Stable, unless otherwise indicated

## Synopsis

    #include <vips/vips.h>

    int                 im_aconvsep                         (VipsImage *in,
                                                             VipsImage *out,
                                                             DOUBLEMASK *mask,
                                                             int n_layers);
    int                 im_aconv                            (VipsImage *in,
                                                             VipsImage *out,
                                                             DOUBLEMASK *mask,
                                                             int n_layers,
                                                             int cluster);
    int                 im_conv                             (VipsImage *in,
                                                             VipsImage *out,
                                                             INTMASK *mask);
    int                 im_conv_f                           (VipsImage *in,
                                                             VipsImage *out,
                                                             DOUBLEMASK *mask);
    int                 im_convsep                          (VipsImage *in,
                                                             VipsImage *out,
                                                             INTMASK *mask);
    int                 im_convsep_f                        (VipsImage *in,
                                                             VipsImage *out,
                                                             DOUBLEMASK *mask);
    int                 im_compass                          (VipsImage *in,
                                                             VipsImage *out,
                                                             INTMASK *mask);
    int                 im_gradient                         (VipsImage *in,
                                                             VipsImage *out,
                                                             INTMASK *mask);
    int                 im_lindetect                        (VipsImage *in,
                                                             VipsImage *out,
                                                             INTMASK *mask);
    int                 im_sharpen                          (VipsImage *in,
                                                             VipsImage *out,
                                                             int mask_size,
                                                             double x1,
                                                             double y2,
                                                             double y3,
                                                             double m1,
                                                             double m2);
    int                 im_grad_x                           (VipsImage *in,
                                                             VipsImage *out);
    int                 im_grad_y                           (VipsImage *in,
                                                             VipsImage *out);
    int                 im_fastcor                          (VipsImage *in,
                                                             VipsImage *ref,
                                                             VipsImage *out);
    int                 im_spcor                            (VipsImage *in,
                                                             VipsImage *ref,
                                                             VipsImage *out);
    int                 im_gradcor                          (VipsImage *in,
                                                             VipsImage *ref,
                                                             VipsImage *out);
    int                 im_contrast_surface                 (VipsImage *in,
                                                             VipsImage *out,
                                                             int half_win_size,
                                                             int spacing);
    int                 im_addgnoise                        (VipsImage *in,
                                                             VipsImage *out,
                                                             double sigma);

## Description

These operations convolve an image in some way, or are operations based on simple convolution, or are useful with convolution.

## Details

### im_aconvsep ()

    int                 im_aconvsep                         (VipsImage *in,
                                                             VipsImage *out,
                                                             DOUBLEMASK *mask,
                                                             int n_layers);

Perform an approximate separable convolution of `in` with `mask`.

The mask must be 1xn or nx1 elements. The output image always has the same VipsBandFmt as the input image.

The image is convolved twice: once with `mask` and then again with `mask` rotated by 90 degrees.

Larger values for `n_layers` give more accurate results, but are slower. As `n_layers` approaches the mask radius, the accuracy will become close to exact convolution and the speed will drop to match. For many large masks, such as Gaussian, `n_layers` need be only 10% of this value and accuracy will still be good.

See also: `im_convsep_f()`, `im_create_dmaskv()`.

`in` : | input image
`out` : | output image
`mask` : | convolution mask
`n_layers` : | number of layers for approximation
Returns : | 0 on success, -1 on error

### im_aconv ()

    int                 im_aconv                            (VipsImage *in,
                                                             VipsImage *out,
                                                             DOUBLEMASK *mask,
                                                             int n_layers,
                                                             int cluster);

Perform an approximate convolution of `in` with `mask`.

The output image always has the same VipsBandFmt as the input image.

Larger values for `n_layers` give more accurate results, but are slower. As `n_layers` approaches the mask radius, the accuracy will become close to exact convolution and the speed will drop to match. For many large masks, such as Gaussian, `n_layers` need be only 10% of this value and accuracy will still be good.

Smaller values of `cluster` will give more accurate results, but be slower and use more memory. 10% of the mask radius is a good rule of thumb.

See also: `im_convsep_f()`, `im_create_dmaskv()`.

`in` : | input image
`out` : | output image
`mask` : | convolution mask
`n_layers` : | number of layers for approximation
`cluster` : | cluster lines closer than this distance
Returns : | 0 on success, -1 on error

### im_conv ()

    int                 im_conv                             (VipsImage *in,
                                                             VipsImage *out,
                                                             INTMASK *mask);

Convolve `in` with `mask` using integer arithmetic. The output image always has the same VipsBandFmt as the input image.

Each output pixel is calculated as sigma[i]{pixel[i] * mask[i]} / scale + offset, where scale and offset are part of `mask`. For integer `in`, the division by scale includes round-to-nearest.

Convolutions on unsigned 8-bit images are calculated with the processor's vector unit, if possible. Disable this with --vips-novector or IM_NOVECTOR.

See also: `im_conv_f()`, `im_convsep()`, `im_create_imaskv()`.

`in` : | input image
`out` : | output image
`mask` : | convolution mask
Returns : | 0 on success, -1 on error

### im_conv_f ()

    int                 im_conv_f                           (VipsImage *in,
                                                             VipsImage *out,
                                                             DOUBLEMASK *mask);

Convolve `in` with `mask` using floating-point arithmetic. The output image is always `IM_BANDFMT_FLOAT` unless `in` is `IM_BANDFMT_DOUBLE`, in which case `out` is also `IM_BANDFMT_DOUBLE`.

Each output pixel is calculated as sigma[i]{pixel[i] * mask[i]} / scale + offset, where scale and offset are part of `mask`.

See also: `im_conv()`, `im_convsep_f()`, `im_create_dmaskv()`.

`in` : | input image
`out` : | output image
`mask` : | convolution mask
Returns : | 0 on success, -1 on error

### im_convsep ()

    int                 im_convsep                          (VipsImage *in,
                                                             VipsImage *out,
                                                             INTMASK *mask);

Perform a separable convolution of `in` with `mask` using integer arithmetic. See `im_conv()` for a detailed description.

The mask must be 1xn or nx1 elements. The output image always has the same VipsBandFmt as the input image.

The image is convolved twice: once with `mask` and then again with `mask` rotated by 90 degrees. This is much faster for certain types of mask (gaussian blur, for example) than doing a full 2D convolution.

See also: `im_convsep_f()`, `im_conv()`, `im_create_imaskv()`.

`in` : | input image
`out` : | output image
`mask` : | convolution mask
Returns : | 0 on success, -1 on error

### im_convsep_f ()

    int                 im_convsep_f                        (VipsImage *in,
                                                             VipsImage *out,
                                                             DOUBLEMASK *mask);

Perform a separable convolution of `in` with `mask` using floating-point arithmetic.

The mask must be 1xn or nx1 elements. The output image is always `IM_BANDFMT_FLOAT` unless `in` is `IM_BANDFMT_DOUBLE`, in which case `out` is also `IM_BANDFMT_DOUBLE`.

The image is convolved twice: once with `mask` and then again with `mask` rotated by 90 degrees. This is much faster for certain types of mask (gaussian blur, for example) than doing a full 2D convolution.

Each output pixel is calculated as sigma[i]{pixel[i] * mask[i]} / scale + offset, where scale and offset are part of `mask`.

See also: `im_convsep()`, `im_conv()`, `im_create_dmaskv()`.

`in` : | input image
`out` : | output image
`mask` : | convolution mask
Returns : | 0 on success, -1 on error

### im_compass ()

    int                 im_compass                          (VipsImage *in,
                                                             VipsImage *out,
                                                             INTMASK *mask);

`in` is convolved 8 times with `mask`, each time `mask` is rotated by 45 degrees. Each output pixel is the largest absolute value of the 8 convolutions.

See also: `im_lindetect()`, `im_gradient()`, `im_conv()`.

`in` : | input image
`out` : | output image
`mask` : | convolution mask
Returns : | 0 on success, -1 on error

### im_gradient ()

    int                 im_gradient                         (VipsImage *in,
                                                             VipsImage *out,
                                                             INTMASK *mask);

`in` is convolved with `mask` and with `mask` after a 90 degree rotation. The result is the sum of the absolute value of the two convolutions.

See also: `im_lindetect()`, `im_gradient()`, `im_conv()`.

`in` : | input image
`out` : | output image
`mask` : | convolution mask
Returns : | 0 on success, -1 on error

### im_lindetect ()

    int                 im_lindetect                        (VipsImage *in,
                                                             VipsImage *out,
                                                             INTMASK *mask);

`in` is convolved four times with `mask`, each time `mask` is rotated by 45 degrees. Each output pixel is the largest absolute value of the four convolutions.

See also: `im_compass()`, `im_gradient()`, `im_conv()`.

`in` : | input image
`out` : | output image
`mask` : | convolution mask
Returns : | 0 on success, -1 on error

### im_sharpen ()

    int                 im_sharpen                          (VipsImage *in,
                                                             VipsImage *out,
                                                             int mask_size,
                                                             double x1,
                                                             double y2,
                                                             double y3,
                                                             double m1,
                                                             double m2);

Selectively sharpen the L channel of a LAB image. Works for `IM_CODING_LABQ` and LABS images.

The operation performs a gaussian blur of size `mask_size` and subtracts from `in` to generate a high-frequency signal. This signal is passed through a lookup table formed from the five parameters and added back to `in`.

The lookup table is formed like this:

                          ^
                       y2 |- - - - - -----------
                          |         /
                          |        / slope m2
                          |    .../
                  -x1     | ...   |
      -------------------...---------------------->
                  |   ... |      x1
                  |... slope m1
                  /       |
                 / m2     |
                /         |
               /          |
              /           |
             /            |
      ______/ _ _ _ _ _ _ | -y3
                          |

For printing, we recommend the following settings:

       mask_size == 7
       x1 == 1.5
       y2 == 20         (don't brighten by more than 20 L*)
       y3 == 50         (can darken by up to 50 L*)

       m1 == 1          (some sharpening in flat areas)
       m2 == 2          (more sharpening in jaggy areas)

If you want more or less sharpening, we suggest you just change the m1 and m2 parameters.

The `mask_size` parameter changes the width of the fringe and can be adjusted according to the output printing resolution. As an approximate guideline, use 3 for 4 pixels/mm (CRT display resolution), 5 for 8 pixels/mm, 7 for 12 pixels/mm and 9 for 16 pixels/mm (300 dpi == 12 pixels/mm). These figures refer to the image raster, not the half-tone resolution.

See also: `im_conv()`.

`in` : | input image
`out` : | output image
`mask_size` : | how large a mask to use
`x1` : | flat/jaggy threshold
`y2` : | maximum amount of brightening
`y3` : | maximum amount of darkening
`m1` : | slope for flat areas
`m2` : | slope for jaggy areas
Returns : | 0 on success, -1 on error.

### im_grad_x ()

    int                 im_grad_x                           (VipsImage *in,
                                                             VipsImage *out);

Find horizontal differences between adjacent pixels.

Generates an image where the value of each pixel is the difference between it and the pixel to its right. The output has the same height as the input and one pixel less width. One-band integer formats only. The result is always `IM_BANDFMT_INT`.

This operation is much faster than (though equivalent to) `im_conv()` with the mask [[-1, 1]].

See also: `im_grad_y()`, `im_conv()`.

`in` : | input image
`out` : | output image
Returns : | 0 on success, -1 on error

### im_grad_y ()

    int                 im_grad_y                           (VipsImage *in,
                                                             VipsImage *out);

Find vertical differences between adjacent pixels.

Generates an image where the value of each pixel is the difference between it and the pixel below it. The output has the same width as the input and one pixel less height. One-band integer formats only. The result is always `IM_BANDFMT_INT`.

This operation is much faster than (though equivalent to) `im_conv()` with the mask [[-1], [1]].

See also: `im_grad_x()`, `im_conv()`.

`in` : | input image
`out` : | output image
Returns : | 0 on success, -1 on error

### im_fastcor ()

    int                 im_fastcor                          (VipsImage *in,
                                                             VipsImage *ref,
                                                             VipsImage *out);

Calculate a fast correlation surface.

`ref` is placed at every position in `in` and the sum of squares of differences calculated. One-band, 8-bit unsigned images only. The output image is always `IM_BANDFMT_UINT`. `ref` must be smaller than or equal to `in`. The output image is the same size as the input.

See also: `im_spcor()`.

`in` : | input image
`ref` : | reference image
`out` : | output image
Returns : | 0 on success, -1 on error

### im_spcor ()

    int                 im_spcor                            (VipsImage *in,
                                                             VipsImage *ref,
                                                             VipsImage *out);

Calculate a correlation surface.

`ref` is placed at every position in `in` and the correlation coefficient calculated. One-band, 8 or 16-bit images only. `in` and `ref` must have the same VipsBandFmt. The output image is always `IM_BANDFMT_FLOAT`. `ref` must be smaller than or equal to `in`. The output image is the same size as the input.

The correlation coefficient is calculated as:

             sumij (ref(i,j)-mean(ref))(inkl(i,j)-mean(inkl))
    c(k,l) = ------------------------------------------------
             sqrt(sumij (ref(i,j)-mean(ref))^2) *
                         sqrt(sumij (inkl(i,j)-mean(inkl))^2)

where inkl is the area of `in` centred at position (k,l).

from Niblack "An Introduction to Digital Image Processing", Prentice/Hall, pp 138.

See also: `im_gradcor()`, `im_fastcor()`.

`in` : | input image
`ref` : | reference image
`out` : | output image
Returns : | 0 on success, -1 on error

### im_gradcor ()

    int                 im_gradcor                          (VipsImage *in,
                                                             VipsImage *ref,
                                                             VipsImage *out);

Calculate a correlation surface.

`ref` is placed at every position in `in` and a correlation coefficient calculated. One-band, integer images only. `in` and `ref` must have the same VipsBandFmt. The output image is always `IM_BANDFMT_FLOAT`. `ref` must be smaller than `in`. The output image is the same size as the input.

The method takes the gradient images of the two images then takes the dot-product correlation of the two vector images. The vector expression of this method is my (tcv) own creation. It is equivalent to the complex-number method of:

ARGYRIOU, V. et al. 2003. Estimation of sub-pixel motion using gradient cross correlation. Electronics Letters, 39 (13).

See also: `im_spcor()`.

`in` : | input image
`ref` : | reference image
`out` : | output image
Returns : | 0 on success, -1 on error

### im_contrast_surface ()

    int                 im_contrast_surface                 (VipsImage *in,
                                                             VipsImage *out,
                                                             int half_win_size,
                                                             int spacing);

Generate an image where the value of each pixel represents the contrast within a window of half_win_size from the corresponsing point in the input image. Sub-sample by a factor of spacing.

See also: `im_spcor()`, `im_gradcor()`.

`in` : | input image
`out` : | output image
`half_win_size` : | window radius
`spacing` : | subsample output by this
Returns : | 0 on success, -1 on error.

### im_addgnoise ()

    int                 im_addgnoise                        (VipsImage *in,
                                                             VipsImage *out,
                                                             double sigma);

Add gaussian noise with mean 0 and variance sigma to `in`. The noise is generated by averaging 12 random numbers, see page 78, PIETGEN, 1989.

See also: `im_gaussnoise()`.

`in` : | input image
`out` : | output image
`sigma` : | standard deviation of noise
Returns : | 0 on success, -1 on error