Filtering API#

Filter an image with your own kernel. The box, Gaussian and motion blurs and laplacian() are built on filter2d(), filter2d_separable() and filter3d(); use gaussian_blur2d() or box_blur() for a Gaussian or box kernel.

Which function to use:

Filtering conventions give the kernel anchor, the border modes and the scipy and OpenCV equivalents.

kornia.filters.filter2d(input, kernel, border_type='reflect', normalized=False, padding='same', behaviour='corr')[source]#

Filter an image with a 2D kernel, by correlation or convolution.

out = filter2d(input, kernel) correlates each channel of a (B, C, H, W) image with a (1, kH, kW) or (B, kH, kW) kernel. behaviour='conv' convolves instead, and padding='valid' drops the border instead of padding it. To blur with a Gaussian or box kernel, use gaussian_blur2d() or box_blur().

Convention:
  • The default behaviour='corr' is cross-correlation, \(out[y, x] = \sum_{i, j} k[i, j] \, input[y + i - a_y, x + j - a_x]\), anchored at \((a_y, a_x)\) = ((kH - 1) // 2, (kW - 1) // 2): the centre of an odd kernel and, for an even size, the tap before the middle. behaviour='conv' flips the kernel on both axes and keeps the anchor.

  • border_type takes the torch.nn.functional.pad() mode names, and the default 'reflect' mirrors about the edge pixel without repeating it. Filtering maps the modes and the anchor onto scipy and OpenCV. Reflect and circular borders extend to any positive axis length: reflection repeats with period 2 * (n - 1) on an axis of length n > 1 and repeats the pixel when n = 1; 'circular' wraps with period n. Working backend padding calls retain their native path.

  • A (1, kH, kW) kernel is shared by the whole batch, and a (B, kH, kW) kernel gives each sample its own, shared by the sample’s channels; there are no per-channel kernels. Any other kernel batch raises. An empty batch accepts either a shared kernel or an empty per-sample kernel and retains the usual output spatial size, dtype promotion and gradient connections to both input and kernel.

  • normalized=True divides each kernel by the sum of its absolute values, so a zero-sum derivative kernel keeps its sign.

  • border_type, padding and behaviour are case-insensitive: 'REFLECT', 'SAME' and 'CONV' are 'reflect', 'same' and 'conv'.

  • For a floating input, the kernel is cast to the input’s dtype and device and stays differentiable, and the output has the input’s dtype.

  • An integer or bool input is filtered in float32 and the output is float32, on the input’s scale: a uint8 image is not rescaled to \([0, 1]\), and the result is not rounded or clamped back to the integer range (#5155).

Parameters:
  • input (Tensor) – image with shape (B, C, H, W).

  • kernel (Tensor) – kernel with shape (1, kH, kW) or (B, kH, kW).

  • border_type (str, optional) – padding mode, 'constant', 'reflect', 'replicate' or 'circular'; unused with padding='valid'. Default: "reflect"

  • normalized (bool, optional) – whether to L1-normalize the kernel. Default: False

  • padding (str, optional) – 'same' pads the input so the output keeps its size, 'valid' does not pad. Default: "same"

  • behaviour (str, optional) – 'corr' correlates, 'conv' flips the kernel first. Default: "corr"

Return type:

Tensor

Returns:

the filtered image. With padding='same' it has the input’s shape (B, C, H, W). With padding='valid' it has shape (B, C, H - kH + 1, W - kW + 1), and its pixel (0, 0) is the 'same' output at the anchor (a_y, a_x).

See also

Example

>>> input = torch.tensor([[[
...    [0., 0., 0., 0., 0.],
...    [0., 0., 0., 0., 0.],
...    [0., 0., 5., 0., 0.],
...    [0., 0., 0., 0., 0.],
...    [0., 0., 0., 0., 0.],]]])
>>> kernel = torch.ones(1, 3, 3)
>>> filter2d(input, kernel, padding='same')
tensor([[[[0., 0., 0., 0., 0.],
          [0., 5., 5., 5., 0.],
          [0., 5., 5., 5., 0.],
          [0., 5., 5., 5., 0.],
          [0., 0., 0., 0., 0.]]]])
kornia.filters.correlate2d(input, kernel, border_type='reflect', normalized=False, padding='same')[source]#

Correlate an image with a 2D kernel, without flipping the kernel.

out = correlate2d(input, kernel) is filter2d() with behaviour='corr': each output pixel is the sum of the kernel times the pixels under it. It equals convolve2d() for a kernel that is its own 180-degree rotation.

Convention:

See the Convention block on filter2d().

Parameters:
  • input (Tensor) – image with shape (B, C, H, W).

  • kernel (Tensor) – kernel with shape (1, kH, kW) or (B, kH, kW).

  • border_type (str, optional) – padding mode, 'constant', 'reflect', 'replicate' or 'circular'; unused with padding='valid'. Default: "reflect"

  • normalized (bool, optional) – whether to L1-normalize the kernel. Default: False

  • padding (str, optional) – 'same' pads the input so the output keeps its size, 'valid' does not pad. Default: "same"

Return type:

Tensor

Returns:

the correlated image. With padding='same' it has the input’s shape (B, C, H, W). With padding='valid' it has shape (B, C, H - kH + 1, W - kW + 1).

See also

  • convolve2d(): the same with the kernel flipped.

  • correlate3d(): the same for volumes, with a 'replicate' default border and no padding.

  • filter2d(): both in one function, through behaviour.

Example

Correlating an impulse gives the kernel rotated by 180 degrees; convolve2d() gives the kernel itself.

>>> input = torch.zeros(1, 1, 5, 5)
>>> input[..., 2, 2] = 1.0
>>> kernel = torch.arange(1.0, 10.0).reshape(1, 3, 3)
>>> correlate2d(input, kernel)
tensor([[[[0., 0., 0., 0., 0.],
          [0., 9., 8., 7., 0.],
          [0., 6., 5., 4., 0.],
          [0., 3., 2., 1., 0.],
          [0., 0., 0., 0., 0.]]]])

With padding='valid' the output loses kH - 1 rows and kW - 1 columns:

>>> correlate2d(input, kernel, padding='valid').shape
torch.Size([1, 1, 3, 3])
kornia.filters.convolve2d(input, kernel, border_type='reflect', normalized=False, padding='same')[source]#

Convolve an image with a 2D kernel, flipping the kernel along H and W.

out = convolve2d(input, kernel) is filter2d() with behaviour='conv': a bright pixel in the image leaves a copy of the kernel in the output, not its rotation.

Convention:

See the Convention block on filter2d().

Parameters:
  • input (Tensor) – image with shape (B, C, H, W).

  • kernel (Tensor) – kernel with shape (1, kH, kW) or (B, kH, kW).

  • border_type (str, optional) – padding mode, 'constant', 'reflect', 'replicate' or 'circular'; unused with padding='valid'. Default: "reflect"

  • normalized (bool, optional) – whether to L1-normalize the kernel. Default: False

  • padding (str, optional) – 'same' pads the input so the output keeps its size, 'valid' does not pad. Default: "same"

Return type:

Tensor

Returns:

the convolved image. With padding='same' it has the input’s shape (B, C, H, W). With padding='valid' it has shape (B, C, H - kH + 1, W - kW + 1).

See also

  • correlate2d(): the same without flipping the kernel.

  • convolve3d(): the same for volumes, with a 'replicate' default border and no padding.

  • filter2d(): both in one function, through behaviour.

Example

Convolving an impulse gives the kernel itself; correlate2d() gives it rotated by 180 degrees.

>>> input = torch.zeros(1, 1, 5, 5)
>>> input[..., 2, 2] = 1.0
>>> kernel = torch.arange(1.0, 10.0).reshape(1, 3, 3)
>>> convolve2d(input, kernel)
tensor([[[[0., 0., 0., 0., 0.],
          [0., 1., 2., 3., 0.],
          [0., 4., 5., 6., 0.],
          [0., 7., 8., 9., 0.],
          [0., 0., 0., 0., 0.]]]])

With padding='valid' the output loses kH - 1 rows and kW - 1 columns:

>>> convolve2d(input, kernel, padding='valid').shape
torch.Size([1, 1, 3, 3])
kornia.filters.filter2d_separable(input, kernel_x, kernel_y, border_type='reflect', normalized=False, padding='same')[source]#

Filter an image with two 1D kernels, one along x and one along y.

out = filter2d_separable(input, kernel_x, kernel_y) correlates each channel of a (B, C, H, W) image with kernel_x along W and then with kernel_y along H. It is filter2d() with the outer-product kernel.

Convention:

See the Convention block on filter2d(). The outer-product kernel is kernel_y[:, :, None] * kernel_x[:, None, :], and the even-size anchor is the same. There is no behaviour argument: the kernels are always correlated. normalized=True normalizes each 1D kernel.

Parameters:
  • input (Tensor) – image with shape (B, C, H, W).

  • kernel_x (Tensor) – kernel along W, with shape (1, kW) or (B, kW).

  • kernel_y (Tensor) – kernel along H, with shape (1, kH) or (B, kH).

  • border_type (str, optional) – padding mode, 'constant', 'reflect', 'replicate' or 'circular'; unused with padding='valid'. Default: "reflect"

  • normalized (bool, optional) – whether to L1-normalize each kernel. Default: False

  • padding (str, optional) – 'same' pads the input so the output keeps its size, 'valid' does not pad. Default: "same"

Returns:

(B, C, H, W) with padding='same'.

Return type:

the filtered image, with the shape filter2d() returns for the same padding

See also

  • filter2d(): any 2D kernel, with behaviour and a kernel that need not be separable.

  • gaussian_blur2d(): a Gaussian blur from kernel_size and sigma, which builds the kernels itself.

Example

>>> input = torch.tensor([[[
...    [0., 0., 0., 0., 0.],
...    [0., 0., 0., 0., 0.],
...    [0., 0., 5., 0., 0.],
...    [0., 0., 0., 0., 0.],
...    [0., 0., 0., 0., 0.],]]])
>>> kernel = torch.ones(1, 3)
>>> filter2d_separable(input, kernel, kernel, padding='same')
tensor([[[[0., 0., 0., 0., 0.],
          [0., 5., 5., 5., 0.],
          [0., 5., 5., 5., 0.],
          [0., 5., 5., 5., 0.],
          [0., 0., 0., 0., 0.]]]])
kornia.filters.correlate3d(input, kernel, border_type='replicate', normalized=False)[source]#

Correlate a volume with a 3D kernel, without flipping the kernel.

out = correlate3d(input, kernel) is filter3d() with behaviour='corr'. It equals convolve3d() for a kernel that flipping all three axes leaves unchanged.

Convention:

See the Convention block on filter3d().

Parameters:
  • input (Tensor) – volume with shape (B, C, D, H, W).

  • kernel (Tensor) – kernel with shape (1, kD, kH, kW) or (B, kD, kH, kW).

  • border_type (str, optional) – padding mode, 'constant', 'reflect', 'replicate' or 'circular'. Default: "replicate"

  • normalized (bool, optional) – whether to L1-normalize the kernel. Default: False

Return type:

Tensor

Returns:

the correlated volume, with the input’s shape (B, C, D, H, W).

See also

  • convolve3d(): the same with the kernel flipped.

  • filter3d(): both in one function, through behaviour.

  • correlate2d(): the same for images, with padding and a 'reflect' default border.

Example

Correlation applies the kernel as given. A single tap at the kernel’s first corner, index (0, 0, 0) in (D, H, W), makes each output voxel copy the input voxel one step back along all three axes. An impulse at the centre (1, 1, 1) of a 3x3x3 volume therefore lands in the volume’s last corner, (2, 2, 2). convolve3d() puts it in the first corner, (0, 0, 0).

>>> input = torch.zeros(1, 1, 3, 3, 3)
>>> input[0, 0, 1, 1, 1] = 1.0  # the impulse, at the centre of the volume
>>> kernel = torch.zeros(1, 3, 3, 3)
>>> kernel[0, 0, 0, 0] = 1.0  # the tap, at the kernel's first corner
>>> output = correlate3d(input, kernel)
>>> output[0, 0].nonzero()  # (D, H, W) index of the one non-zero output voxel
tensor([[2, 2, 2]])
kornia.filters.convolve3d(input, kernel, border_type='replicate', normalized=False)[source]#

Convolve a volume with a 3D kernel, flipping the kernel along D, H and W.

out = convolve3d(input, kernel) is filter3d() with behaviour='conv': a bright voxel in the volume leaves a copy of the kernel in the output, not its mirror image through the centre.

Convention:

See the Convention block on filter3d().

Parameters:
  • input (Tensor) – volume with shape (B, C, D, H, W).

  • kernel (Tensor) – kernel with shape (1, kD, kH, kW) or (B, kD, kH, kW).

  • border_type (str, optional) – padding mode, 'constant', 'reflect', 'replicate' or 'circular'. Default: "replicate"

  • normalized (bool, optional) – whether to L1-normalize the kernel. Default: False

Return type:

Tensor

Returns:

the convolved volume, with the input’s shape (B, C, D, H, W).

See also

  • correlate3d(): the same without flipping the kernel.

  • filter3d(): both in one function, through behaviour.

  • convolve2d(): the same for images, with padding and a 'reflect' default border.

Example

Convolution flips the kernel along all three axes, which moves a tap at the kernel’s first corner, index (0, 0, 0) in (D, H, W), to its last corner. Each output voxel then copies the input voxel one step ahead along all three axes, so an impulse at the centre (1, 1, 1) of a 3x3x3 volume lands in the volume’s first corner, (0, 0, 0). correlate3d() puts it in the last corner, (2, 2, 2).

>>> input = torch.zeros(1, 1, 3, 3, 3)
>>> input[0, 0, 1, 1, 1] = 1.0  # the impulse, at the centre of the volume
>>> kernel = torch.zeros(1, 3, 3, 3)
>>> kernel[0, 0, 0, 0] = 1.0  # the tap, at the kernel's first corner
>>> output = convolve3d(input, kernel)
>>> output[0, 0].nonzero()  # (D, H, W) index of the one non-zero output voxel
tensor([[0, 0, 0]])
kornia.filters.filter3d(input, kernel, border_type='replicate', normalized=False, behaviour='corr')[source]#

Filter a volume with a 3D kernel, by correlation or convolution.

out = filter3d(input, kernel) correlates each channel of a (B, C, D, H, W) volume with a (1, kD, kH, kW) or (B, kD, kH, kW) kernel, after padding it by border_type. behaviour='conv' convolves instead.

Convention:
  • See the Convention block on filter2d(), applied to the (D, H, W) axes with the anchor ((kD - 1) // 2, (kH - 1) // 2, (kW - 1) // 2).

  • The default border_type is 'replicate', where filter2d() defaults to 'reflect'. There is no padding argument: the output always has the input’s shape.

Parameters:
  • input (Tensor) – volume with shape (B, C, D, H, W).

  • kernel (Tensor) – kernel with shape (1, kD, kH, kW) or (B, kD, kH, kW).

  • border_type (str, optional) – padding mode, 'constant', 'reflect', 'replicate' or 'circular'. Default: "replicate"

  • normalized (bool, optional) – whether to L1-normalize the kernel. Default: False

  • behaviour (str, optional) – 'corr' correlates, 'conv' flips the kernel first. Default: "corr"

Return type:

Tensor

Returns:

the filtered volume, with shape (B, C, D, H, W).

See also

Example

>>> input = torch.tensor([[[
...    [[0., 0., 0., 0., 0.],
...     [0., 0., 0., 0., 0.],
...     [0., 0., 0., 0., 0.],
...     [0., 0., 0., 0., 0.],
...     [0., 0., 0., 0., 0.]],
...    [[0., 0., 0., 0., 0.],
...     [0., 0., 0., 0., 0.],
...     [0., 0., 5., 0., 0.],
...     [0., 0., 0., 0., 0.],
...     [0., 0., 0., 0., 0.]],
...    [[0., 0., 0., 0., 0.],
...     [0., 0., 0., 0., 0.],
...     [0., 0., 0., 0., 0.],
...     [0., 0., 0., 0., 0.],
...     [0., 0., 0., 0., 0.]]
... ]]])
>>> kernel = torch.ones(1, 3, 3, 3)
>>> filter3d(input, kernel)
tensor([[[[[0., 0., 0., 0., 0.],
           [0., 5., 5., 5., 0.],
           [0., 5., 5., 5., 0.],
           [0., 5., 5., 5., 0.],
           [0., 0., 0., 0., 0.]],

          [[0., 0., 0., 0., 0.],
           [0., 5., 5., 5., 0.],
           [0., 5., 5., 5., 0.],
           [0., 5., 5., 5., 0.],
           [0., 0., 0., 0., 0.]],

          [[0., 0., 0., 0., 0.],
           [0., 5., 5., 5., 0.],
           [0., 5., 5., 5., 0.],
           [0., 5., 5., 5., 0.],
           [0., 0., 0., 0., 0.]]]]])
kornia.filters.fft_conv(input, kernel, border_type='reflect', normalized=False, padding='same', behaviour='corr')[source]#

Filter an image with a 2D kernel through the FFT, for large kernels.

out = fft_conv(input, kernel) filters each channel of a (B, C, H, W) image with a (1, kH, kW) or (B, kH, kW) kernel, as filter2d() does, by multiplying in the frequency domain. Its cost barely grows with the kernel size, so it pays off only for large kernels.

Convention:
  • See the Convention block on filter2d(): for the same arguments and a finite real input fft_conv returns the same result, to roundoff. A NaN or inf in a channel of the input makes that channel’s whole output non-finite, where filter2d() keeps it to the pixels whose window reaches it.

  • An integer or bool input is filtered in float32 and the output is float32, as in filter2d().

  • A float16 or bfloat16 input is transformed in float32 on every device, and the result is cast back to the input’s dtype.

Parameters:
  • input (Tensor) – image with shape (B, C, H, W).

  • kernel (Tensor) – kernel with shape (1, kH, kW) or (B, kH, kW).

  • border_type (str, optional) – padding mode, 'constant', 'reflect', 'replicate' or 'circular'; unused with padding='valid'. Default: "reflect"

  • normalized (bool, optional) – whether to L1-normalize the kernel. Default: False

  • padding (str, optional) – 'same' pads the input so the output keeps its size, 'valid' does not pad. Default: "same"

  • behaviour (str, optional) – 'corr' correlates, 'conv' flips the kernel first. Default: "corr"

Return type:

Tensor

Returns:

the filtered image. With padding='same' it has the input’s shape (B, C, H, W). With padding='valid' it has shape (B, C, H - kH + 1, W - kW + 1).

See also

  • filter2d(): the same filter as a direct sliding window.

Example

>>> input = torch.tensor([[[[
...     0., 0., 0., 0., 0.],
...     [0., 0., 0., 0., 0.],
...     [0., 0., 5., 0., 0.],
...     [0., 0., 0., 0., 0.],
...     [0., 0., 0., 0., 0.],
... ]]])
>>> kernel = torch.ones(1, 3, 3)
>>> fft_conv(input, kernel, padding="same")
tensor([[[[0., 0., 0., 0., 0.],
          [0., 5., 5., 5., 0.],
          [0., 5., 5., 5., 0.],
          [0., 5., 5., 5., 0.],
          [0., 0., 0., 0., 0.]]]])