I think it's good to explain Sobel from other places. Post for your reference and future use ~
First, let's start with how the computer detects the edge.
Taking a grayscale image as an example, its theoretical basis is as follows. If an edge appears, the gray scale of the image will change to a certain extent. To facilitate the assumption that the black gradient is white, it represents a boundary, in the gray-scale analysis, the gray-scale function on the edge is a Gini Function Y = kx, and the first derivative of the edge is its slope k, that is, the first derivative of the edge is a constant, the first derivative of the non-edge is zero, so that the first derivative can be used to preliminarily determine the edge of the image. It is usually the derivative of the X and Y directions, that is, the gradient. In theory, computers obtain the edge of an image in this way.
However, when applied to images, you will find that this derivative cannot be obtained, because there is no accurate function that allows you to evaluate the derivative, in addition, it is much more difficult for a computer to solve the analytical solution than to obtain the numerical solution, so it comes to an alternative method to obtain the derivative. It is to use a 3 × 3 window to approximate the image. Take the X-direction derivation as an example. The derivative of a certain point is the sum of the elements in the third row minus the sum of the elements in the first row. In this way, the approximate derivative of a certain point is obtained. In fact, it is also very easy to understand why it almost represents the derivative, the derivative represents a change rate, from the first line to the third line, the gray value subtraction, of course, is a change rate. This is the so-called Prewitt operator. In this way, the derivative of the X direction is obtained. The Y-direction derivative is similar to the X-direction derivative, except that the sum of the elements in the third column is used to subtract the sum of the elements in the first column. Derivative in the Y direction in the X direction
Then the gradient will come out. In this way, you can find a picture.
Another problem is that, because the derivative of the 3x3 center is obtained, a weight is added to the second column. Its weight is 2 and the weight of the first and third columns is 1, okay, this is the Sobel operator. Compared with the Prewitt operator, Sobel
Better anti-noise capability. : In this way, the X-direction derivative of the center is obtained.
For example. X points are obtained by using the Sobel method. Delta X = 1 × 50 + 2 × 30 + 1 × 50-1 × 50 + 2 × 30 + 1 × 50) = 0. This shows that this point is not a boundary.
Well, after understanding the basic theory, let's look at the Sobel function under opencv, void cvsobel (const cvarr * SRC, cvarr * DST, int xorder, int yorder, int aperture_size = 3); SRC: input image; DST output image; xorder: Differential order in the X direction; yorder: Differential order in the Y direction; aperture_size extends the size of the Sobel kernel (the number of the window order), which must be 1 (note that this is a 3 × 1 or 1 × 3 vector rather than a square matrix ),
3, 5, or 7.
The following is a program for Sobel edge detection. The platform is vs08 and A Win32 console application is created.
# Include <cv. h> # include
Run, you will find an error, take a closer look at the problem. In fact, this is a problem, because after the derivative is obtained in the Sobel method, there will be a negative value, there will be a value greater than 255, and your Sobel Image is ipl_depth_8u, that is, the number of 8-bit unsigned digits. Therefore, the number of digits that Sobel creates is not enough. It requires 16-bit signed ones, that is, ipl_depth_16s. Change the sentence "Create Image" to "Sobel = cvcreateimage (cvgetsize (FRAME), ipl_depth_16s, 1);" run ". If no error is reported, but the Sobel Image cannot be displayed, why? The original image is displayed with 8-bit unsigned characters, but now it is 16-Bit Signed. Of course, there will be problems with the display. So we need to convert Sobel into 8-bit unsigned.
Opencv provides a function, that is, cvconvertscaleabs (const cvarr * SRC, cvarr * DST, double scale = 1, double shift = 0); SRC: source image; DST: target image; scale: the coefficient of multiplication before conversion; the coefficient of addition before shift conversion. In this way, you can create a new unsigned image and then convert it. Iplimage * sobel8u = cvcreateimage (cvgetsize (Sobel), ipl_depth_8u, 1 );
Add cvconvertscaleabs (Sobel, sobel8u,) before the image is displayed, so that you can see the effect of cvsobel. You can see what the X direction or y direction is. For the convenience of everyone, I also put the modified program.
# Include <cv. h>
# Include
Void main ()
{
Iplimage * frame, * gray, * Sobel;
Frame = cvloadimage ("E:/p1.jpg ");//
Attach Images
Gray = cvcreateimage (cvgetsize (FRAME), frame-> depth, 1 );//
Allocate image space
Sobel = cvcreateimage (cvgetsize (FRAME), ipl_depth_16s, 1 );
Cvnamedwindow ("frame ");
Cvnamedwindow ("gray ");
Cvnamedwindow ("Sobel ");
Cvcvtcolor (frame, gray, cv_bgr2gray );//
Convert to grayscale
Cvsobel (Gray, Sobel, 1, 0, 3 );
Iplimage * sobel8u = cvcreateimage (cvgetsize (Sobel), ipl_depth_8u, 1 );
Cvconvertscaleabs (Sobel, sobel8u, 1, 0 );
Cvshowimage ("frame", frame );//
Show images
Cvshowimage ("gray", gray );
Cvshowimage ("Sobel", sobel8u );
Cvwaitkey (0 );//
Wait
Cvreleaseimage (& frame );//
Release space (it is very important for video processing. Not releasing will cause memory
Leakage)
Cvreleaseimage (& gray );
Cvreleaseimage (& Sobel );
Cvdestroywindow ("frame ");
Cvdestroywindow ("gray ");
Cvdestroywindow ("Sobel ");