Professional Documents
Culture Documents
Modified Canny Edge Detection
Modified Canny Edge Detection
Pi19404
February 10, 2014
Contents
Contents
Modied Canny Edge Detection
0.1 Introduction . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 0.2 Code . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . References . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . .
3
3 10 10
2 | 11
The first step is to perform Gaussian Smoothing to eliminate the noise in the image The gaussian filter is optimal filter in the sense that in increases the SNR and provide the best localization characteristics.This have been proved in the paper ??. After gaussian smoothing edge detection is performed to obtain the gradients along the x and y directions.
3 | 11
void smoothing(Mat src,Mat &dst,int aperture) { cv::GaussianBlur(src,src,Size(aperture,aperture),1); } smoothing(src,src,aperture); Mat dx,dy; cv::Sobel(src,dx,CV_32F,1,0,aperture,1, 0, cv::BORDER_REPLICATE); cv::Sobel(src,dy,CV_32F,0,1,aperture,1, 0, cv::BORDER_REPLICATE); cv::cartToPolar(dx,dy,fmag,fori,true);
Next step is non maxima suppression,which selects the locally dominant gradient Let us extract the edge orientation and resolve it into one of orientation at 0,45,90,135.
//pointer to orientation image float *ptr2=(float*)ori.data; for(int i=1;i<height-1;i++) { for(int j=1;j<width-1;j++) { float ori1=ptr2[j+i*width]; for(int k=0;k<4;k++) { float i1=(k*45)+45; float i2=i1-45; float i3=(k*45)+180; float i4=i3+45; float ori2=((int)(ori1+(45.0/2))); if(ori2 >360) ori2=ori2-360; //checking orienation of 0,45,90,135 if((ori2 < i1 && ori2 >=i2 ) ||(ori2 >= i3 && ori2 <=i4)) { ori1=k*45; break; }
4 | 11
(b) smoothing
(d) suppressed
The input to canny edge detection algorithm is a pair of thresholds,lower and higher threshold. Any pixel in the image greater than lower threshold is considered to be an edge pixel and marked accordingly.The thresholded images are shown in figure 1e and figure 1f. The pixels indicated in figure 1f indicate points which are surely edges. The pixels indicated in figure 1e may be an edge.
cv::threshold(fmag,hout,higher,255,CV_THRESH_BINARY); cv::threshold(fmag,lout,lower,255,CV_THRESH_BINARY);
If any pixels in the image are connected to these edge pixels and have gradient greater than higher threshold,they are also marked as edge pixels.
5 | 11
//function to check if point is connected to edge bool check_color(Point p) { int x=p.x; int y=p.y; if(x<nMinx || x >nMaxx || y<nMiny || y >nMaxy) return false; float *pl=(float*)lout.data; float val2=pl[x+y*s.width]; int val=getPixel(p); if(val>0) return false; //check if pixel is possibly an edge if(val2>0) return true; else return false; return false; }
This process is called hysterisis thresholding. We will use a stack based implementation of connceted component analysis.
//main function for performing connected component anaysis //starting from higher threshold images void connectedComponent(Mat hout) { float *ptr1=(float *)hout.data; nMinx=1; nMaxx=s.width-2;
6 | 11
nMiny=1; nMaxy=s.height-2; for(int i=nMiny;i<nMaxy;i++) { for(int j=nMinx;j<nMaxx;j++) { if(ptr1[j+i*s.width]>0 ) { stackfill(j,i); } } } //function which perform edge following void stackfill(int x,int y) { points.push(Point(x,y)); while(points.empty()==false) { //pop elements from top of stack Point p=points.top(); points.pop(); setPixel(p); //add neighbors to the stack for(int i=-1;i<=1;i++) { for(int j=-1;j<=1;j++) { if(i==0 && j==0) continue; Point p1=Point(p.x+i,p.y+j); //check if pixel is a edge if(check_color(p1)==true) { points.push(p1); } }
7 | 11
} }
Robust edge detection is typically a difficult task in real time environment due to varying illumination,shadows etc. The gradient computation is performed on a grayscale image As a modification to canny ,gradients are computed for each of channels of color image individually. Orientation corresponding to dominant orientation is retained. Non maxima supression is performed on this final image The output is seen in figure 1h,1j and ?? It can be seen that much better edge image is obtained using color gradients. It may also be required that we perform thresholding at different levels
8 | 11
void canny(Mat src,vector<Mat> &dst,vector<double> lower,vector<double> hi { Mat fmag,fori,disp; s=Size(src.cols,src.rows); //perform gaussian smoothing //cvtColor(src,src,CV_BGR2GRAY); smoothing(src,src,aperture); //computing the color gradients if(src.channels()>1) colorGradient(src,fmag,fori,aperture); else { Mat dx,dy; //computing gradients along x and y direction cv::Sobel(src,dx,CV_32F,1,0,aperture,1, 0, cv::BORDER_REPLICATE); cv::Sobel(src,dy,CV_32F,0,1,aperture,1, 0, cv::BORDER_REPLICATE); //compute magnitude and orientation of gradient cv::cartToPolar(dx,dy,fmag,fori,true); } //perform non maxima suppression nonMaxima(fmag,fori); Mat hout; dst.resize(lower.size()); //applying multiple thresholds for(int i=0;i<lower.size();i++) { //apply lower and higher gradient thresholds cv::threshold(fmag,hout,lower[i],255,CV_THRESH_BINARY); cv::threshold(fmag,lout,higher[i],255,CV_THRESH_BINARY); connectedComponent(hout); lout.copyTo(dst[i]); }
9 | 11
0.2 Code
The code for modified canny edge detector can be found in the git repository https://github.com/pi19404/OpenVision/ in files ImgProc/edgedetector.cpp and ImgProc/edgedetector.hpp files.
10 | 11
Bibliography
Bibliography
[1] F. John Canny. A Computational Approach to Edge Detection. In: 8.6 (1986), pp. 679698.
doi: http://doi.acm.org/10.1145/11274.11275.
11 | 11