The classic edge detection method is to construct an edge detection operator on a small neighborhood of pixels in the original image. Common Edge Detection methods include the employees, Sobe l operators, Prew itt operators, K irsch operators, Laplacian operators, LOG operators, and C anny operators.
1. Edge Detection Method Based on first-order differentiation
1. The simplest gradient operator is the Roberts operator, which is a 2*2 template and uses local difference to detect steep edges. However, it is sensitive to noise and often has isolated points.
// The Berts operator is used to obtain the edge of the image gradient, input the source image, and output the gradient graph. void Berts (IplImage * src, IplImage * dst) is not commonly used in this method) {// apply for space for The luts image. Because the source image pointer's imageData is used, the copy method dst = cvCloneImage (src); int x, y, I, w, h; int temp, temp1; uchar * ptr = (uchar *) (dst-> imageData); int ptr1 [4] = {0}; int indexx [4] = {0, 1, }; int indexy [4] = {0,}; w = dst-> width; h = dst-> height; for (y = 0; y
2. Prewitt operator and Sobe l operator. Before obtaining the gradient, the two operators first perform the mean of the neighboring area or weighted average, and then perform the differential operation to suppress the noise, but the edge fuzzy phenomenon is prone.
// If the source image is 8 bits, the target image depth must be 16 S or 32 bits to avoid overflow.
Void sobel (IplImage * src, IplImage * dst) {// apply for space for soble differential images. create the image function IplImage * pSobelImg_dx = cvCreateImage (cvGetSize (src ); iplImage * pSobelImg_dy = cvCreateImage (cvGetSize (src),); IplImage * pSobelImg_dxdy = cvCreateImage (cvGetSize (src ); // calculate the differential cvSobel (src, pSobelImg_dx, 1, 0, 3) in two directions using the sobel operator; cvSobel (src, pSobelImg_dy, 0, 1, 3 ); // total gradient = sqrt (horizontal * horizontal + vertical * vertical) int I, j; double v1, v2, v; for (I = 0; I <src-> height; I ++) {for (j = 0; j <src-> width; j ++) {v1 = cvGetReal2D (pSobelImg_dx, I, j); v2 = cvGetReal2D (pSobelImg_dy, i, j); v = sqrt (v1 * v1 + v2 * v2);/* if (v> 100) v = 255; else v = 0; */cvSetReal2D (pSobelImg_dxdy, I, j, v) ;}} cvConvertScale (pSobelImg_dxdy, dst); // convert the image to an 8-bit double min_val = 0, max_val = 0; // obtain the graph and display the maximum and minimum pixel values of the image cvMinMaxLoc (pSobelImg_dxdy, & min_val, & max_val); printf ("max_val = % f \ nmin_val = % f \ n ", max_val, min_val); // normalized cvNormalize (dst, dst, 0,255, CV_MINMAX, 0 );
// Prewitt operator, template convolution formula writing, common methods
Void prewitt (IplImage * src, IplImage * dst) {// defines the prewitt operator template float prewittx [9] = {-, 1,-, 1, 1}; float prewitty [9] = {, 1, 0,-1,-1,-1}; CvMat px; px = cvMat (, CV_32F, prewittx); CvMat py; py = cvMat (3,3, CV_32F, prewitty );
// Apply for the output image space iplimage * dstx = cvcreateimage (cvgetsize (SRC),); iplimage * dsty = cvcreateimage (cvgetsize (SRC );
// Use a template for the image to automatically fill in the border cvfilter2d (SRC, dstx, & PX, cvpoint (-1,-1); cvfilter2d (SRC, dsty, & py, cvpoint (-1,-1 ));
// Calculate the gradient. the norm is 2. Note that the usage method of the learning pointer is int I, j, temp; float tempx, Tempy; // The floating point type is defined to avoid ambiguity caused by SQRT functions. uchar * ptrx = (uchar *) dstx-> imagedata; uchar * ptry = (uchar *) dsty-> imagedata; for (I = 0; I <Src-> width; I ++) {for (j = 0; j <Src-> height; j ++) {tempx = ptrx [I + J * dstx-> widthstep]; // tempx, tempy indicates the pointer pointing to the pixel Tempy = ptry [I + J * dsty-> widthstep]; temp = (INT) SQRT (tempx * tempx + Tempy * Tempy ); /* If (temp> 100) temp = 255; else temp = 0; */DST-> imagedata [I + J * dstx-> widthstep] = temp ;}} double min_val = 0, max_val = 0; // obtain the graph and display the maximum and minimum pixel values in the image cvminmaxloc (DST, & min_val, & max_val ); printf ("max_val = % F \ nmin_val = % F \ n", max_val, min_val); // calculate the gradient, norm is 1 // cvadd (dstx, dsty, DST ); cvsaveimage ("prewittimg.jpg", DST); // Save the image to the file cvreleaseimage (& dstx); cvreleaseimage (& dsty); cvnamedwindow ("Prewitt", 1 ); cvshowimage ("Prewitt", DST );}
// Based on the symmetry of the direction, the Kirsch operator can process only the first four templates to obtain the maximum value. This method is the best method to calculate the pixel gradient around the central pixel. Void kirsch (IplImage * src, IplImage * dst) {dst = cvCloneImage (src); // cvConvert (src, srcMat); // convert the image into a matrix to process int x, y; float a, B, c, d; float p1, p2, p3, p4, p5, p6, p7, p8, p9; uchar * ps = (uchar *) src-> imageData; // ps is the pointer to the input image data. uchar * pd = (uchar *) dst-> imageData; // pd is the pointer to the output image data int w = dst-> width; int h = dst-> height; int step = dst-> widthStep; for (x = 0; x <W-2; x ++) // take (x + 1, y + 1) 9 neighboring pixels Center 1 4 7 {// 2 5 8for (y = 0; y <H-2; y ++) // 3 6 9 {p1 = ps [y * step + x]; p2 = ps [y * step + (x + 1)]; p3 = ps [y * step + (x + 2)]; p4 = ps [(y + 1) * step + x]; p5 = ps [(y + 1) * step + (x + 1)]; p6 = ps [(y + 1) * step + (x + 2)]; p7 = ps [(y + 2) * step + x]; p8 = ps [(y + 2) * step + (x + 1)]; p9 = ps [(y + 2) * step + (x + 2)]; // obtain (I + 1, j + 1) gray around nine points a = fabs (float (-5 * p1-5 * P2-5 * p3 + 3 * p4 + 3 * p6 + 3 * p7 + 3 * p8 + 3 * p9 )); // calculate the gradient value of 4 directions B = fabs (float (3 * p1-5 * P2-5 * p3 + 3 * p4-5 * p6 + 3 * p7 + 3 * p8 + 3 * p9 )); c = fabs (float (3 * p1 + 3 * P2-5 * p3 + 3 * p4-5 * p6 + 3 * p7 + 3 * p8-5 * p9 )); d = fabs (float (3 * p1 + 3 * p2 + 3 * p3 + 3 * p4-5 * p6 + 3 * p7-5 * p8-5 * p9); a = max (, b); // take the maximum value in each direction as the edge strength a = max (a, c); a = max (a, d); pd [(y + 1) * step + (x + 1)] = a;/* if (a> 100) {pd [(y + 1) * step + (x + 1)] = 255;} else pd [(y + 1) * step + (x + 1)] = 0; */} double min_val = 0, max_val = 0; // obtain the graph and display the maximum and minimum pixel values in the image. cvMinMaxLoc (dst, & min_val, & max_val); printf ("max_val = % f \ nmin_val = % f \ n ", max_val, min_val); cvNormalize (dst, dst, 0,255, CV_MINMAX); // normalize cvSaveImage ("KirschImg.jpg", dst ); // Save the image to the file cvNamedWindow ("kirsch", 1); cvShowImage ("kirsch", dst );