OpenCV (25): Edge detection (1)

16508600:

Table of contents

1. Principle of edge detection

2. Sobel operator edge detection

3. Scharr operator edge detection

4. Generation of two operators getDerivKernels()


1. Principle of edge detection

       Its principle is to capture the boundaries and contours in the image based on the change of the gray value in the image. The gradient represents the strength and direction of pixel intensity changes in the image. Therefore, finding the pixel with the largest gradient value along the gradient direction can obtain the edge information in the image.

2. Sobel operator edge detection

principle:

        The Sobel operator is a commonly used edge detection operator, which can capture the edge information in the image by calculating the gradient of the image. It calculates the derivatives of the image in the x and y directions separately, and then determines the position and strength of the edge based on the values ​​of the derivatives.

       Specifically, the Sobel operator can perform convolution operations on images through a 3x3 convolution kernel. There are two Sobel convolution kernels, one for edge detection in the horizontal direction (x direction), and the other for edge detection in the vertical direction (y direction). The two convolution kernels are as follows:

For each pixel in the input image, the Sobel operator will use these convolution kernels to calculate its gradient in the horizontal and vertical directions. Then, by combining the magnitudes of the gradients, the total gradient magnitude for each pixel can be calculated. The total gradient size represents the change intensity of the gray value around the pixel point, and the larger change intensity usually corresponds to the edge in the image.

function:

cv::Sobel()The function applies the Sobel operator to the input image for convolution operation.

The prototype of the function is as follows:

CV_EXPORTS_W void Sobel( InputArray src, OutputArray dst, int ddepth,

int dx, int dy, int ksize = 3,

double scale = 1, double delta = 0,

int borderType = BORDER_DEFAULT );

The following is a detailed explanation of the parameters:

  • src: The input image, which can be a single-channel grayscale image or a multi-channel image.

  • dst: The output image, with the same size and type as the input image.

  • ddepth: The data type of the output image, which can be a negative value (such as -1) to indicate that it is consistent with the input image, or it can be a value such as CV_8U, CV_16U, CV_32F, which indicates the depth of the output image.

  • dx and dy: Represents the order of derivatives in the x and y directions, respectively. Possible values ​​are 0, 1 and 2.

  • ksize: The size of the Sobel kernel, must be 1, 3, 5 or 7. The larger the value, the smoother the response of the filter.

  • scale: An optional scaling factor used to adjust the value range of the output image. The default is 1.

  • delta: Optionally specify the delta value to adjust the brightness of the output image. The default is 0.

  • borderType: An optional border extension method to handle cases where the neighborhood extends beyond the border of the image. Defaults to cv::BORDER_DEFAULT.

       Sample code:

void Sobel_f(Mat image){
    Mat gray;
    cvtColor(image,gray,COLOR_BGR2GRAY);
    Mat resultX,resultY,resultXY;
    //X方向一阶边缘
    Sobel(gray,resultX,CV_16S,1,0,1);
    convertScaleAbs(resultX,resultX);

    //Y方向一阶边缘
    Sobel(gray,resultY,CV_16S,0,1,3);
    convertScaleAbs(resultY,resultY);

    //整幅图像的一阶边缘
    resultXY=resultX+resultY;

    //显示图像
    imwrite("/sdcard/DCIM/resultX.png",resultX);
    imwrite("/sdcard/DCIM/resultY.png",resultY);
    imwrite("/sdcard/DCIM/resultXY.png",resultXY);


}

         (X direction) (Y direction) (XY direction)

3. Scharr operator edge detection

principle:

        The Scharr operator is an edge detection operator, which is an improved version of the Sobel operator. The Scharr operator uses a more accurate weight distribution, which can provide better edge detection performance.

        The Scharr operator also calculates the gradient of the image through a convolution operation, similar to the Sobel operator. It contains two convolution kernels, one for edge detection in the horizontal direction (x direction) and the other for edge detection in the vertical direction (y direction).

        The difference of the Scharr operator is that the weight distribution in the convolution kernel is more balanced than that of the Sobel operator to improve the sensitivity to edge signals. This distribution of balanced weights results in more accurate gradient estimates.

        The Scharr operator uses the same principle to calculate the magnitude and direction of the gradient around the pixel. By calculating the gradient in the x and y directions, and determining the position and strength of the edge according to the magnitude and direction of the gradient.

function:

cv::Scharr()function is a function in OpenCV to calculate the Scharr derivative of an image. It is similar to the Sobel operator, but uses a more accurate distribution of weights.

Function prototype:

CV_EXPORTS_W void Scharr( InputArray src, OutputArray dst, int ddepth,

int dx, int dy, double scale = 1, double delta = 0,

int borderType = BORDER_DEFAULT );

The following is a detailed explanation of the parameters:

  • src: The input image, which can be a single-channel grayscale image or a multi-channel image.

  • dst: The output image, with the same size and type as the input image.

  • ddepth: The data type of the output image, which can be a negative value (such as -1), indicating that it is consistent with the input image, or it can be a value such as CV_8U, CV_16U, CV_32F, indicating the depth of the output image.

  • dx and dy: Represents the order of derivatives in the x and y directions, respectively. Possible values ​​are 0, 1 and 2.

  • scale: An optional scaling factor used to adjust the value range of the output image. The default is 1.

  • delta: Optionally specify the delta value to adjust the brightness of the output image. The default is 0.

  • borderType: An optional border extension method to handle cases where the neighborhood extends beyond the border of the image. Defaults to cv::BORDER_DEFAULT.

Sample code:


void Scharr_f(Mat img) {
        Mat image;
    cvtColor(img,image,COLOR_BGR2GRAY);
      cv::Mat grad_x, grad_y; // 存放Scharr滤波器的梯度
    cv::Mat abs_grad_x, abs_grad_y; // 存放梯度的绝对值

    // 计算X方向的Scharr滤波器
    cv::Scharr(image, grad_x, CV_16S, 1, 0);
    cv::convertScaleAbs(grad_x, abs_grad_x);

    // 计算Y方向的Scharr滤波器
    cv::Scharr(image, grad_y, CV_16S, 0, 1);
    cv::convertScaleAbs(grad_y, abs_grad_y);

    // 合并X和Y方向的梯度
    cv::Mat grad;
    cv::addWeighted(abs_grad_x, 0.5, abs_grad_y, 0.5, 0, grad);

    // 显示结果
  imwrite("/sdcard/DCIM/grad.png",grad);
}

Result:  (grad)

4. Generation of two operators getDerivKernels()

getDerivKernels()The function is a function used to generate a one-dimensional convolution kernel in OpenCV, which can be used to calculate the first derivative of the image.

The prototype of the function is as follows:

void cv::getDerivKernels ( OutputArray kx,

OutputArray ky,

int    dx,

int    dy,

int   ksize,

bool   normalize =false,

int   ktype = CV_32F

)

  • kx: the output matrix of row filter coefficients, the size is ksize*1
  • ky: Output matrix of column filter coefficients, size is ksize*1.
  • dx: The order of the derivative in the X direction.
  • dy: The order of the derivative in the Y direction
  • ksize: The size of the filter, the parameter that can be selected is FILTER SCHARR, 1.35 or 7.
  • normalize: Whether to normalize the filter coefficients, the default value is false, indicating that the coefficients are not normalized.
  • ktype: filter coefficient type, you can choose CV 32F or CV 64F, the default parameter is CV 32F.

Sample code:

The following is an example of using getDerivKernels()functions to generate Sobel and Scharr operator convolution kernels:

//生成边缘检测器
void f(){
    cv::Mat sobel_xl, sobel_yl; // 存放分离的Sobel算子
    cv::Mat scharr_x, scharr_y; // 存放分离的Scharr算子
    cv::Mat sobelXl, scharrX; // 存放最终算子

    // 一阶X方向Sobel算子
    cv::getDerivKernels(sobel_xl, sobel_yl, 1, 0, 3);
    sobel_xl = sobel_xl.reshape(1, 1); // 转换为单行矩阵
    sobelXl = sobel_yl * sobel_xl; // 计算滤波器

    // X方向Scharr算子
    cv::getDerivKernels(scharr_x, scharr_y, 1, 0, cv::FILTER_SCHARR);
    scharr_x = scharr_x.reshape(1, 1); // 转换为单行矩阵
    scharrX = scharr_y*scharr_x; // 计算滤波器
    ostringstream ss;
    // 打印生成的卷积核
    ss<< "Sobel X方向卷积核:" << sobelXl << endl;
     ss << "Scharr X方向卷积核:" << scharrX <<endl;

    LOGD("%s",ss.str().c_str());
}

We use getDerivKernels()the function to generate the convolution kernel of the X-direction Sobel operator and the X-direction Scharr operator. Then, we convert it to a single-row matrix and calculate the filters by multiplication.

Guess you like

Origin blog.csdn.net/weixin_63357306/article/details/132725000