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:
A 2D kernel, correlated (the default) or convolved:
filter2d(), withbehaviour='corr'or'conv'.correlate2d()andconvolve2d()fixbehaviour. They give the same output for a kernel that is its own 180-degree rotation.A kernel that is the outer product of two 1D kernels:
filter2d_separable().A large 2D kernel:
fft_conv(), which returns the result offilter2d()through FFTs.A volume:
filter3d(),correlate3d()andconvolve3d().
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, andpadding='valid'drops the border instead of padding it. To blur with a Gaussian or box kernel, usegaussian_blur2d()orbox_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_typetakes thetorch.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 period2 * (n - 1)on an axis of lengthn > 1and repeats the pixel whenn = 1;'circular'wraps with periodn. 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=Truedivides each kernel by the sum of its absolute values, so a zero-sum derivative kernel keeps its sign.border_type,paddingandbehaviourare 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 withpadding='valid'. Default:"reflect"normalized (
bool, optional) – whether to L1-normalize the kernel. Default:Falsepadding (
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:
- Returns:
the filtered image. With
padding='same'it has the input’s shape(B, C, H, W). Withpadding='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
correlate2d():behaviourfixed to'corr'.convolve2d():behaviourfixed to'conv'.filter2d_separable(): two 1D kernels, for a kernel that is their outer product.filter3d(): the same filter for volumes.fft_conv(): the same filter computed with FFTs, for large kernels.
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)isfilter2d()withbehaviour='corr': each output pixel is the sum of the kernel times the pixels under it. It equalsconvolve2d()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 withpadding='valid'. Default:"reflect"normalized (
bool, optional) – whether to L1-normalize the kernel. Default:Falsepadding (
str, optional) –'same'pads the input so the output keeps its size,'valid'does not pad. Default:"same"
- Return type:
- Returns:
the correlated image. With
padding='same'it has the input’s shape(B, C, H, W). Withpadding='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 nopadding.filter2d(): both in one function, throughbehaviour.
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 loseskH - 1rows andkW - 1columns:>>> 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
HandW.out = convolve2d(input, kernel)isfilter2d()withbehaviour='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 withpadding='valid'. Default:"reflect"normalized (
bool, optional) – whether to L1-normalize the kernel. Default:Falsepadding (
str, optional) –'same'pads the input so the output keeps its size,'valid'does not pad. Default:"same"
- Return type:
- Returns:
the convolved image. With
padding='same'it has the input’s shape(B, C, H, W). Withpadding='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 nopadding.filter2d(): both in one function, throughbehaviour.
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 loseskH - 1rows andkW - 1columns:>>> 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 withkernel_xalongWand then withkernel_yalongH. It isfilter2d()with the outer-product kernel.- Convention:
See the Convention block on
filter2d(). The outer-product kernel iskernel_y[:, :, None] * kernel_x[:, None, :], and the even-size anchor is the same. There is nobehaviourargument: the kernels are always correlated.normalized=Truenormalizes each 1D kernel.
- Parameters:
input (
Tensor) – image with shape(B, C, H, W).kernel_x (
Tensor) – kernel alongW, with shape(1, kW)or(B, kW).kernel_y (
Tensor) – kernel alongH, with shape(1, kH)or(B, kH).border_type (
str, optional) – padding mode,'constant','reflect','replicate'or'circular'; unused withpadding='valid'. Default:"reflect"normalized (
bool, optional) – whether to L1-normalize each kernel. Default:Falsepadding (
str, optional) –'same'pads the input so the output keeps its size,'valid'does not pad. Default:"same"
- Returns:
(B, C, H, W)withpadding='same'.- Return type:
the filtered image, with the shape
filter2d()returns for the samepadding
See also
filter2d(): any 2D kernel, withbehaviourand a kernel that need not be separable.gaussian_blur2d(): a Gaussian blur fromkernel_sizeandsigma, 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)isfilter3d()withbehaviour='corr'. It equalsconvolve3d()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:
- 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, throughbehaviour.correlate2d(): the same for images, withpaddingand 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,HandW.out = convolve3d(input, kernel)isfilter3d()withbehaviour='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:
- 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, throughbehaviour.convolve2d(): the same for images, withpaddingand 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 byborder_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_typeis'replicate', wherefilter2d()defaults to'reflect'. There is nopaddingargument: 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:Falsebehaviour (
str, optional) –'corr'correlates,'conv'flips the kernel first. Default:"corr"
- Return type:
- Returns:
the filtered volume, with shape
(B, C, D, H, W).
See also
correlate3d():behaviourfixed to'corr'.convolve3d():behaviourfixed to'conv'.filter2d(): the same filter for images, withpaddingand a'reflect'default border.
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, asfilter2d()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 inputfft_convreturns the same result, to roundoff. A NaN or inf in a channel of the input makes that channel’s whole output non-finite, wherefilter2d()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 withpadding='valid'. Default:"reflect"normalized (
bool, optional) – whether to L1-normalize the kernel. Default:Falsepadding (
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:
- Returns:
the filtered image. With
padding='same'it has the input’s shape(B, C, H, W). Withpadding='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.]]]])