OpenCvSharp function: Sobel edge detection, Scharr edge detection, GetDerivKernels to obtain the filter coefficient of the image derivative
Sobel edge detection
Function description
Compute derivatives of first, second, third, or mixed images using extended Sobel operators. When the kernel size ksize is not 1, use the separable kernel of ksize X ksize to derive the derivative; when it is 1, use a 3 X 1 or 1 X 3 kernel (without Gaussian smoothing) only for the first-order or second-order x Axis or y same derivative. When ksze = FILTER_SCHARR (ie -1), use the Scharr 3×3 kernel to obtain more accurate results, see below for details This function computes the image derivative by convolving the image with an appropriate kernel:
The Sobel operator combines Gaussian smoothing and differentiation, and has a certain ability to make noise. Commonly used parameters are (xorder = 1, yorder = 0, ksize = 3) or (xorder = 0, yorder = 1, ksize = 3) to calculate the image derivative of the first x or y. The kernel in the horizontal direction (x-axis) is
void Sobel(InputArray src,
OutputArray dst,
MatType ddepth,
int xorder,
int yorder,
int ksize = 3,
double scale = 1.0,
double delta = 0.0,
BorderTypes borderType = BorderTypes. Reflect101)
Parameter Description
parameter
Description
InputArray src
Input image, usually a grayscale image
OutputArray dst
Output image. The size and number of channels are consistent with the input image
MatType ddepth
The desired output depth, For details, see Depth combinations table
int xorder
order of derivative x
int yorder
order of derivative y
int ksize
Core size, must be -1, 1, 3, 5 or 7 (use Scharr 3X3 when -1)
double scale
Optional scaling factor for computed derivative values, defaults to 1.
double delta
Add this value to the calculation result, which can be understood as brightening ( positive number) or dimmed (negative number)
BorderTypes borderType
The pixels outside the border are taken Value method, does not support Wrap
Example image
Sobel Horizontal Edge
Sobel Vertical Edge
Sobel edge detection results
GetDerivKernels obtains the filter coefficient of the image derivative
Function description
Get the filter coefficients used to compute the image derivative. When ksize=FILTER_SCHARR (ie -1), it returns a 3 x 3 Scharr core, otherwise it returns a Soble core. Usually the result is used in SepFilter2D.
Function prototype
void GetDerivKernels(OutputArray kx,
OutputArray ky,
int dx,
int dy,
int ksize,
bool normalize = false,
MatType? ktype = null)
Parameter description
?Parameter?
Description
OutputArray kx
The output matrix of row filter coefficients, the type is ktype
OutputArray ky
Column filter coefficients The output matrix of the type is ktype
int dx
The order of the derivative x
int dy
order of derivative y
int ksize
Core size, can be -1,1,3,5,7
bool normalize
Whether to normalize (scale down) the filter coefficients. In theory, the coefficients should have denominators
=
2
k
the s
i
z
e
?
2
?
d
x
?
d
the y
?
2
=2^{ksize*2-dx-dy-2}
=2ksize?2?dx?dy?2. Set to true if filtering floating point images. Set to False if it is an 8-bit image and the result is 16-bit. The default is False
MatType? ktype
The type of filter coefficient. CV_32F or CV_64F. CV_32F when null
Scharr edge detection
Function Description
Use the Scharr operator to calculate the x and y axis first derivatives of the image.
Output image. The size and number of channels are consistent with the input image
MatType ddepth
The desired output depth, For details, see Depth combinations table
int xorder
order of derivative x
int yorder
order of derivative y
double scale
Optional scaling factor for computed derivative values, defaults to 1.
double delta
Add this value to the calculation result, which can be understood as brightening ( positive number) or dimmed (negative number)
BorderTypes borderType
The pixels outside the border are taken Value method, does not support Wrap
Example image
Sobel and Canny
Sobel edge detection: high efficiency, certain anti-noise, but not accurate enough for texture details, Canny edge detection: the accuracy is higher than Sobel, and the most efficient is not as high as Sobel
Code sample
Mat src;
string winName = "Sobel & amp; Scharr Demo";
string funType = "S";
public void Run(ParamBase paramBase)
{<!-- -->
//Test the result of GetDerivKernels
using var dx = new Mat();
using var dy = new Mat();
Cv2. GetDerivKernels(dx, dy, 1, 0, -1, false);
//Console output dx, dy
Utils. Dump(dx);
Utils. Dump(dy);
// popup file selection dialog
if (!Utils.SelectFile(out string fileName)) fileName = ImagePath.Lena;
//var fileName = ImagePath. Lena;
src = Cv2.ImRead(fileName, ImreadModes.Color);
if (src.Empty()) throw new Exception($"There is an error opening the image: {<!-- -->fileName}");
//Gaussian filter
Cv2.GaussianBlur(src, src, new Size(3, 3), 0, 0);
//Generally perform Sobel or SChar edge detection on grayscale images
Cv2.CvtColor(src, src, ColorConversionCodes.BGR2GRAY);
Cv2.NamedWindow(winName, WindowFlags.Normal);
Cv2.CreateTrackbar("kSize 2n-1", winName, 4, KSizeOnChanged);
Cv2.SetTrackbarPos("kSize 2n-1", winName, 2);
Cv2.CreateTrackbar("scale n/10", winName, 100, SCaleOnChanged);
Cv2.SetTrackbarPos("scale n/10", winName, 10);
Cv2.CreateTrackbar("Delta n-50", winName, 100, DeltaOnChanged);
Cv2.SetTrackbarPos("Delta n-50", winName, 50);
bool loop = true;
while (loop)
{<!-- -->
var c = (Char)Cv2. WaitKey(50);
switch(c)
{<!-- -->
case 's':
case 'S':
funType= "S";
OnChanged();
break;
case 'c':
case 'C':
funType = "C";
OnChanged();
break;
case 'q':
case 'Q':
case (Char)27:
loop = false;
break;
default:
break;
}
}
Cv2. DestroyAllWindows();
}
private void OnChanged()
{<!-- -->
using var gradX = new Mat();
using var gradY = new Mat();
string text = "";
if (funType == "S")
{<!-- -->
Cv2.SetWindowTitle(winName, "Sobel press S/C to switch, Esc to exit");
Cv2.Sobel(src, gradX, MatType.CV_16S, 1, 0, kSize, scale, delta);
Cv2.Sobel(src, gradY, MatType.CV_16S, 0, 1, kSize, scale, delta);
text = $"kSize={<!-- -->kSize},scale={<!-- -->scale.ToString("0.0")},delta={<!-- --> delta}";
}
else
{<!-- -->
Cv2.SetWindowTitle(winName, "Scharr press S/C to switch, Esc to exit");
Cv2.Scharr(src, gradX, MatType.CV_16S, 1, 0, scale, delta);
Cv2.Scharr(src, gradY, MatType.CV_16S, 0, 1, scale, delta);
text = $"scale={<!-- -->scale.ToString("0.0")},delta={<!-- -->delta}";
}
Cv2. ConvertScaleAbs(gradX, gradX);
Cv2.ImShow("horizontal edge", gradX);
Cv2.ConvertScaleAbs(gradY, gradY);
Cv2.ImShow("Vertical edge", gradY);
using var dst = new Mat();
//Merge horizontal and vertical images
Cv2.AddWeighted(gradX, 0.5, gradY, 0.5, 0, dst);
Utils. PutText(dst, text);
Cv2. ImShow(winName, dst);
}
int kSize = 3;
private void KSizeOnChanged(int pos, IntPtr userData)
{<!-- -->
kSize = pos * 2 - 1;
OnChanged();
}
double scale = 1;
private void SCaleOnChanged(int pos,IntPtr userData)
{<!-- -->
scale = pos / 10.0D;
OnChanged();
}
double delta = 0;
private void DeltaOnChanged(int pos, IntPtr userData)
{<!-- -->
delta = pos - 50;
OnChanged();
}
OpenCvSharp function examples (directory) refer to https://docs.opencv.org/4.7.0/d2/d2c/tutorial_sobel_derivatives.html