ConvolutionKernel Class
An immutable convolution matrix for ImageProcessingExtensions.Convolve.
public sealed class ConvolutionKernelRemarks
The matrix is applied as written, without being flipped: the weight at column x and row y multiplies the pixel x - Width / 2 columns to the right of and y - Height / 2 rows below the pixel being computed, so the top-left weight applies to the top-left neighbor. Both dimensions are odd, which makes the middle weight the one of the pixel itself.
The weights are used as given: they are not normalized. A matrix whose weights add up to 1 keeps the overall brightness; divide the weights by their sum to obtain one.
A separable matrix, whose every weight is the product of a weight of a column and a weight of a row (ConvolutionKernel.CreateSeparable, or a matrix the constructor recognizes as one, see ConvolutionKernel.IsSeparable), is applied in two passes: every row is filtered by the row weights, then the filtered rows are combined by the column weights, in double precision without rounding in between. The time then grows with the sum of the dimensions of the matrix instead of their product.
Constructors
| Name | Description |
|---|---|
| ConvolutionKernel(int, int, ReadOnlySpan<double>) | Initializes a new instance of the ConvolutionKernel class. |
ConvolutionKernel(int, int, ReadOnlySpan<double>)
ConvolutionKernel.csInitializes a new instance of the ConvolutionKernel class.
public ConvolutionKernel(int width, int height, ReadOnlySpan<double> values)Parameters
widthint- The number of columns. Must be positive and odd.
heightint- The number of rows. Must be positive and odd.
valuesReadOnlySpan<double>- The weights, row by row from the top-left one (
widthtimesheightfinite values). They are copied.
Exceptions
ArgumentOutOfRangeExceptionwidthorheightis not positive or is even.ArgumentExceptionvaluesdoes not hold exactlywidthtimesheightvalues, or a value is not finite.
Properties
| Name | Description |
|---|---|
| Emboss | Gets the emboss matrix [-2, -1, 0; -1, 1, 1; 0, 1, 2], which lights the image from the bottom right. Its weights add up to 1, so flat areas keep their color. |
| Height | Gets the number of rows. |
| IsSeparable | Gets a value indicating whether the matrix is applied in two passes, a row then a column. It is the case of a matrix created by ConvolutionKernel.CreateSeparable, and of a matrix given weight by weight whose every weight is exactly, in double precision, the product of a weight of its largest weight's column, divided by that weight, and a weight of its row (a box, a binomial or a Sobel matrix): finding the factors costs one pass over the weights. |
| Laplacian3x3 | Gets the Laplacian of the four nearest neighbors, the sum of the second derivatives [1, -2, 1] of both directions: [0, 1, 0; 1, -4, 1; 0, 1, 0], as cv2.Laplacian with ksize = 1. Its weights add up to zero, and it is negative on the bright side of an edge. |
| Laplacian5x5 | Gets the 5x5 Laplacian, the sum of the second derivatives [1, 0, -2, 0, 1] of each direction smoothed by [1, 4, 6, 4, 1] across it (the second derivatives of the 5x5 Sobel operator), as cv2.Laplacian with ksize = 5: [2, 4, 4, 4, 2; 4, 0, -8, 0, 4; 4, -8, -24, -8, 4; 4, 0, -8, 0, 4; 2, 4, 4, 4, 2]. Its weights add up to zero. |
| LaplacianOfGaussian | Gets the 5x5 Laplacian of Gaussian, the Laplacian of a slightly blurred image, which responds less to noise: [0, 0, 1, 0, 0; 0, 1, 2, 1, 0; 1, 2, -16, 2, 1; 0, 1, 2, 1, 0; 0, 0, 1, 0, 0]. Its weights add up to zero. It is the classic 5x5 approximation with the sign of the Laplacian (negative in the middle, like ConvolutionKernel.Laplacian3x3); the "Mexican hat" form of that approximation is its negation. |
| PrewittX | Gets the horizontal Prewitt operator, the derivative [-1, 0, 1] of the rows averaged across them: [-1, 0, 1; -1, 0, 1; -1, 0, 1]. |
| PrewittY | Gets the vertical Prewitt operator, ConvolutionKernel.PrewittX transposed: [-1, -1, -1; 0, 0, 0; 1, 1, 1]. |
| ScharrX | Gets the horizontal Scharr operator, a Sobel operator whose smoothing [3, 10, 3] makes the response closer to the same for every direction of the edge: [-3, 0, 3; -10, 0, 10; -3, 0, 3], as cv2.Scharr with dx = 1 and dy = 0. |
| ScharrY | Gets the vertical Scharr operator, ConvolutionKernel.ScharrX transposed: [-3, -10, -3; 0, 0, 0; 3, 10, 3]. |
| Sharpen3x3 | Gets the sharpen matrix [0, -1, 0; -1, 5, -1; 0, -1, 0]: the pixel minus the Laplacian of its four nearest neighbors. Its weights add up to 1, so flat areas keep their color. |
| SobelX | Gets the horizontal Sobel operator, the derivative [-1, 0, 1] of the rows smoothed by [1, 2, 1] across them: [-1, 0, 1; -2, 0, 2; -1, 0, 1]. It responds to vertical edges, positively where the right side is brighter, as cv2.Sobel with dx = 1 and dy = 0. |
| SobelY | Gets the vertical Sobel operator, ConvolutionKernel.SobelX transposed: [-1, -2, -1; 0, 0, 0; 1, 2, 1]. It responds to horizontal edges, positively where the bottom side is brighter. |
| Width | Gets the number of columns. |
Emboss
ConvolutionKernel.csGets the emboss matrix [-2, -1, 0; -1, 1, 1; 0, 1, 2], which lights the image from the bottom right. Its weights add up to 1, so flat areas keep their color.
public static ConvolutionKernel Emboss { get; }Property value
Height
ConvolutionKernel.csIsSeparable
ConvolutionKernel.csGets a value indicating whether the matrix is applied in two passes, a row then a column. It is the case of a matrix created by ConvolutionKernel.CreateSeparable, and of a matrix given weight by weight whose every weight is exactly, in double precision, the product of a weight of its largest weight's column, divided by that weight, and a weight of its row (a box, a binomial or a Sobel matrix): finding the factors costs one pass over the weights.
public bool IsSeparable { get; }Property value
Laplacian3x3
ConvolutionKernel.csGets the Laplacian of the four nearest neighbors, the sum of the second derivatives [1, -2, 1] of both directions: [0, 1, 0; 1, -4, 1; 0, 1, 0], as cv2.Laplacian with ksize = 1. Its weights add up to zero, and it is negative on the bright side of an edge.
public static ConvolutionKernel Laplacian3x3 { get; }Property value
Laplacian5x5
ConvolutionKernel.csGets the 5x5 Laplacian, the sum of the second derivatives [1, 0, -2, 0, 1] of each direction smoothed by [1, 4, 6, 4, 1] across it (the second derivatives of the 5x5 Sobel operator), as cv2.Laplacian with ksize = 5: [2, 4, 4, 4, 2; 4, 0, -8, 0, 4; 4, -8, -24, -8, 4; 4, 0, -8, 0, 4; 2, 4, 4, 4, 2]. Its weights add up to zero.
public static ConvolutionKernel Laplacian5x5 { get; }Property value
LaplacianOfGaussian
ConvolutionKernel.csGets the 5x5 Laplacian of Gaussian, the Laplacian of a slightly blurred image, which responds less to noise: [0, 0, 1, 0, 0; 0, 1, 2, 1, 0; 1, 2, -16, 2, 1; 0, 1, 2, 1, 0; 0, 0, 1, 0, 0]. Its weights add up to zero. It is the classic 5x5 approximation with the sign of the Laplacian (negative in the middle, like ConvolutionKernel.Laplacian3x3); the "Mexican hat" form of that approximation is its negation.
public static ConvolutionKernel LaplacianOfGaussian { get; }Property value
PrewittX
ConvolutionKernel.csGets the horizontal Prewitt operator, the derivative [-1, 0, 1] of the rows averaged across them: [-1, 0, 1; -1, 0, 1; -1, 0, 1].
public static ConvolutionKernel PrewittX { get; }Property value
PrewittY
ConvolutionKernel.csGets the vertical Prewitt operator, ConvolutionKernel.PrewittX transposed: [-1, -1, -1; 0, 0, 0; 1, 1, 1].
public static ConvolutionKernel PrewittY { get; }Property value
ScharrX
ConvolutionKernel.csGets the horizontal Scharr operator, a Sobel operator whose smoothing [3, 10, 3] makes the response closer to the same for every direction of the edge: [-3, 0, 3; -10, 0, 10; -3, 0, 3], as cv2.Scharr with dx = 1 and dy = 0.
public static ConvolutionKernel ScharrX { get; }Property value
ScharrY
ConvolutionKernel.csGets the vertical Scharr operator, ConvolutionKernel.ScharrX transposed: [-3, -10, -3; 0, 0, 0; 3, 10, 3].
public static ConvolutionKernel ScharrY { get; }Property value
Sharpen3x3
ConvolutionKernel.csGets the sharpen matrix [0, -1, 0; -1, 5, -1; 0, -1, 0]: the pixel minus the Laplacian of its four nearest neighbors. Its weights add up to 1, so flat areas keep their color.
public static ConvolutionKernel Sharpen3x3 { get; }Property value
SobelX
ConvolutionKernel.csGets the horizontal Sobel operator, the derivative [-1, 0, 1] of the rows smoothed by [1, 2, 1] across them: [-1, 0, 1; -2, 0, 2; -1, 0, 1]. It responds to vertical edges, positively where the right side is brighter, as cv2.Sobel with dx = 1 and dy = 0.
public static ConvolutionKernel SobelX { get; }Property value
SobelY
ConvolutionKernel.csGets the vertical Sobel operator, ConvolutionKernel.SobelX transposed: [-1, -2, -1; 0, 0, 0; 1, 2, 1]. It responds to horizontal edges, positively where the bottom side is brighter.
public static ConvolutionKernel SobelY { get; }Property value
Width
ConvolutionKernel.csIndexers
| Name | Description |
|---|---|
| this[int, int] | Gets a weight. |
this[int, int]
ConvolutionKernel.csGets a weight.
Parameters
xint- The column, from 0 (left) to
ConvolutionKernel.Width- 1. yint- The row, from 0 (top) to
ConvolutionKernel.Height- 1.
Property value
Exceptions
ArgumentOutOfRangeExceptionxoryis out of range.
Methods
| Name | Description |
|---|---|
| CreateMotionBlur(double, double) | Creates the matrix of a motion blur: a straight segment of length pixels through the center, at degrees from the horizontal, as the trail of a camera or a subject that moved while the shutter was open. Apply it with ImageProcessingExtensions.Convolve. |
| CreateSeparable(ReadOnlySpan<double>, ReadOnlySpan<double>) | Creates a separable matrix: the weight at column x and row y is columnWeights[y] * rowWeights[x]. It is applied in two passes (every row filtered by rowWeights, then the filtered rows combined by columnWeights), so the time grows with the sum of the two lengths instead of their product. |
CreateMotionBlur(double, double)
ConvolutionKernel.csCreates the matrix of a motion blur: a straight segment of length pixels through the center, at degrees from the horizontal, as the trail of a camera or a subject that moved while the shutter was open. Apply it with ImageProcessingExtensions.Convolve.
public static ConvolutionKernel CreateMotionBlur(double length, double degrees)Parameters
lengthdouble- The length of the segment, in pixels: at least 1 and at most 2000. A length of 1 keeps the image as it is.
degreesdouble- The angle of the segment, in degrees.
Returns
ConvolutionKernel The matrix.
Exceptions
ArgumentOutOfRangeExceptionlengthis not between 1 and 2000.ArgumentExceptiondegreesis not a finite number.
Remarks
The weight of a pixel is the length of the part of the segment inside its square, divided by the length of the segment, so the weights add up to 1 and the brightness is kept: a horizontal segment of 5 pixels is the row [1, 1, 1, 1, 1] / 5, and a segment of 3 pixels at 45 degrees gives sqrt(2) / 3 to the center and (3 - sqrt(2)) / 6 to each of the two diagonal neighbors. The segment is centered, so the blur does not move the image. The matrix is as small as the segment allows: its width and height are odd.
As for ImageProcessingExtensions.Rotate, a positive angle turns clockwise on the screen (the vertical axis points down); a segment and its opposite are the same, so 0 and 180 give the same matrix.
CreateSeparable(ReadOnlySpan<double>, ReadOnlySpan<double>)
ConvolutionKernel.csCreates a separable matrix: the weight at column x and row y is columnWeights[y] * rowWeights[x]. It is applied in two passes (every row filtered by rowWeights, then the filtered rows combined by columnWeights), so the time grows with the sum of the two lengths instead of their product.
public static ConvolutionKernel CreateSeparable(ReadOnlySpan<double> rowWeights, ReadOnlySpan<double> columnWeights)Parameters
rowWeightsReadOnlySpan<double>- The weights of a row, from left to right: an odd number of finite values. They are copied.
columnWeightsReadOnlySpan<double>- The weights of a column, from top to bottom: an odd number of finite values. They are copied.
Returns
ConvolutionKernel The matrix.
Exceptions
ArgumentException- A span is empty or holds an even number of values, or a value is not finite.