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:

dst

=

?

x

o

r

d

e

r

+

the y

o

r

d

e

r

src

?

x

x

o

r

d

e

r

?

the y

the y

o

r

d

e

r

\texttt{dst} = \frac{\partial^{xorder + yorder} \texttt{src}}{\partial x^{xorder} \partial y^{yorder}}

dst=?xxorder?yyorder?xorder + yordersrc?



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

[

?

1

0

1

?

2

0

2

?

1

0

1

]

\begin{bmatrix} -1 & amp; 0 & amp; 1 \ -2 & amp; 0 & amp; 2 \ -1 & amp; 0 & amp; 1\end{bmatrix}

1?2?1?000?121?
?

The kernel in the vertical direction (y axis) is

[

?

1

?

2

?

1

0

0

0

1

2

1

]

\begin{bmatrix} -1 & amp; -2 & amp; -1 \ 0 & amp; 0 & amp; 0 \ 1 & amp; 2 & amp; 1\end{bmatrix}

101202101?
?

Function prototype

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 horizontal edge

Sobel Vertical Edge

Sobel vertical edge
Sobel edge detection results
Sobel edge detection result

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.

Scharr(src,

dst,

depth,

dx,

dy,

scale,

delta,

borderType)

\texttt{Scharr(src, dst, ddepth, dx, dy, scale, delta, borderType)}

Scharr(src, dst, ddepth, dx, dy, scale, delta, borderType)

is equivalent to

Sobel(src,

dst,

depth,

dx,

dy,

-1,

scale,

delta,

borderType)

\texttt{Sobel(src, dst, ddepth, dx, dy, -1, scale, delta, borderType)}

Sobel(src, dst, ddepth, dx, dy, -1, scale, delta, borderType)

The kernel in the horizontal direction (x-axis) is

[

?

3

0

3

?

10

0

10

?

3

0

3

]

\begin{bmatrix} -3 & amp; 0 & amp; 3 \ -10 & amp; 0 & amp; 10 \ -3 & amp; 0 & amp; 3\end{bmatrix}

3?10?3?000?3103?
?

The kernel in the vertical direction (y-axis) is

[

?

3

?

10

3

0

0

0

3

10

3

]

\begin{bmatrix} -3 & amp; -10 & amp; 3 \ 0 & amp; 0 & amp; 0 \ 3 & amp; 10 & amp; 3\end{bmatrix}

30310010?303?
?

Function prototype

void Scharr(InputArray src,
OutputArray dst,
MatType ddepth,
int xorder,
int yorder,
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
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

Scharr horizontal and vertical edges
Scharr edge detection

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