Using Sobel operator in OpenCv

Sobel edge detection operator

1. Basic principles

    The Sobel operator is an edge detection operator of the first order derivative. During the implementation of the algorithm, the 3×3 template is used as the kernel to perform convolution and operation with each pixel in the image, and then an appropriate threshold is selected to extract the edge.

    Using a 3×3 neighborhood avoids computing gradients at interpolated points between pixels. The Sobel operator is also a gradient magnitude, that is, the partial derivatives Sx and Sy can be realized by convolution templates. Its template is as follows:

  

    Sx = (Z1 + 2*Z2 + Z3)-(Z7 + 2*Z8 + Z9);

    And = (Z1 + 2*Z4 + Z7)-(Z3 + 2*Z6 + Z9);

2. Algorithm advantages and disadvantages

    The advantage of the Sobel operator algorithm is that the calculation is simple and the speed is fast. However, since only the templates in two directions are used , it can only detect the edges in the horizontal and vertical directions, so the edge detection effect of this algorithm is not very ideal for images with complex textures .

3. Sobel edge detection based on OpenCv

 Development platform VC6.0, OpenCv1.0.
   函数cvSobel(constCvArr*src,CvArr*dst, int xorder, int yorder, int aperture_size=3)
   src: input image;
    dst: output image;
    xorder: the order of difference in the x direction;
    yorder: the order of difference in the y direction;
    aperture_size: The size of the extended Sobel kernel (ie, the window order), must be 1 (this is a 3×1 or 1×3 vector instead of a square matrix), 3, 5 or 7.

code show as below:

#include <cv.h>
#include <highgui.h>
void main()
{
    IplImage *frame,*gray,*sobel;
    frame=cvLoadImage("car.bmp");//加载图像
    gray=cvCreateImage(cvGetSize(frame),frame->depth,1);//分配图像空间
    sobel=cvCreateImage(cvGetSize(frame),frame->depth,1);
    cvCvtColor(frame,gray,CV_BGR2GRAY);//转为灰度
    cvSobel(gray,sobel,1,0,3);
    cvNamedWindow("frame");
    cvNamedWindow("gray");
    cvNamedWindow("sobel");
    cvShowImage("frame",frame);//显示图像
    cvShowImage("gray",gray);
    cvShowImage("sobel",sobel);
    cvWaitKey(0);//等待
    cvReleaseImage(&frame);//释放空间(对视频处理很重要,不释放会构成内存败露)
    cvReleaseImage(&gray);
    cvReleaseImage(&sobel);
    cvDestroyWindow("frame");
    cvDestroyWindow("gray");
    cvDestroyWindow("sobel");
}

    After running, no grammatical errors were found. In fact, there is still a problem if you look carefully. Because after calculating the derivative in the Sobel way, there will be negative values, and there will be values ​​greater than 255, and the image of the Sobel you built is IPL_DEPTH_8U, which is an 8-bit unsigned number, so the number of bits of the image created by Sobel is not enough, it needs 16 bits Signed, that is, IPL_DEPTH_16S. Change to sobel=cvCreateImage(cvGetSize(frame),IPL_DEPTH_16S,1); After running, it is found that no error is reported, but the Sobel image cannot be displayed. What is the reason? The original image display is 8-bit unsigned, but now it is 16-bit signed. Of course, there will be problems with the display. So also convert Sobel to 8-bit unsigned.

    OpenCv里有cvConvertScaleAbs( const CvArr* src, CvArr* dst, double scale=1, double shift=0 );

    src: source image; dst: target image; scale: coefficient multiplied before transformation; coefficient added before shift transformation.

    This can be achieved by creating a new unsigned image and then converting it.

    IplImage *sobel8u=cvCreateImage(cvGetSize(sobel),IPL_DEPTH_8U,1);

    Then add cvConvertScaleAbs(sobel,sobel8u,1,0) before displaying the image; so that you can see the effect of cvSobel. You can see the effect of derivation in the X direction or Y direction. The modified procedure is as follows:

#include <cv.h>
#include <highgui.h>
void main()
{
   IplImage *frame,*gray,*sobel;
   frame=cvLoadImage("car.jpg");//加载图像
   gray=cvCreateImage(cvGetSize(frame),frame->depth,1);//分配图像空间
   sobel=cvCreateImage(cvGetSize(frame),IPL_DEPTH_16S,1);
   cvNamedWindow("frame");
   cvNamedWindow("gray");
   cvNamedWindow("sobel");
   cvCvtColor(frame,gray,CV_BGR2GRAY);//转为灰度
   cvSobel(gray,sobel,1,0,3);
 
   IplImage *sobel8u=cvCreateImage(cvGetSize(sobel),IPL_DEPTH_8U,1);
   cvConvertScaleAbs(sobel,sobel8u,1,0);
   cvShowImage("frame",frame);//显示图像
   cvShowImage("gray",gray);
   cvShowImage("sobel",sobel8u);
   cvWaitKey(0);//等待
   cvReleaseImage(&frame);//释放空间(对视频处理很重要,不释放会造成内存泄露)
   cvReleaseImage(&gray);
   cvReleaseImage(&sobel);
   cvDestroyWindow("frame");
   cvDestroyWindow("gray");
   cvDestroyWindow("sobel");
}

The experimental results are as follows:

original image


Sobel diagram of 16S (nothing)


Sobel edge map



Guess you like

Origin blog.csdn.net/beijingmake209/article/details/41073819