You are on page 1of 11

Modified Canny Edge Detection

February 10, 2014


Modied Canny Edge Detection
0.1 Introduction . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 0.2 Code . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . References . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . .

3 10 10

2 | 11

Modified Canny Edge Detection

Modified Canny Edge Detection
0.1 Introduction
In this article we will look at Modified canny edge detection which will provide output corresponding to different thresholds.We will also consider the use of color gradients instead of gray scale gradients 
Canny Edge detection algorithm is optimal edge detection algorithm.  The result is a binary image,where the edge approximate the true edges of the image  Canny edge detection algorithm provides a computational method to achieve 

Robust Detection  Good Localization  Single response to edge 
Canny Edge detection algorithm consists of 5 steps 


Smoothing Computing Gradients Non-Maxima Suppression Double thresholding Hysterisis 

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

Modified Canny Edge Detection

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*); 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; }




//updating discretized orientation ptr2[j+i*width]=ori1;

4 | 11

Modified Canny Edge Detection 
Thus we compute the dominant edge direction about the neighborhood and check if the magnitude of gradient is strongest along neighborhood pixels along the gradient.  If the gradient value is maximum,it is retained else value is set to 0 The result is shown in figure 1d

(a) original image

(b) smoothing

(c) magnitude image

(d) suppressed

(e) lower threshs

(f) higher threshs 

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

Modified Canny Edge Detection 
Thus this can be considered as following edge .To begin with we need a pixel with gradient magnitude greater than higher threshold,and edge following is done till be encounted a neighborhood where all the pixels are lower than the lower threshold .  To check if a neighbour is connected to edge ,we simple check if point is possibly and edge

//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*); 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 *); nMinx=1; nMaxx=s.width-2;

6 | 11

Modified Canny Edge Detection

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; 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

Modified Canny Edge Detection

} }



The output is show in figure 1g

(g) final edge

(h) color edge

(i) color supressed

(j) final cedge 

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

Modified Canny Edge Detection 
Thus we can pass a vector of thresholds to canny as input and get a vector of images at output.  Only the function from the point of hysteris is performed for each pair of threshold.

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

Modified Canny Edge Detection


0.2 Code
The code for modified canny edge detector can be found in the git repository in files ImgProc/edgedetector.cpp and ImgProc/edgedetector.hpp files.

10 | 11


[1] F. John Canny.  A Computational Approach to Edge Detection. In: 8.6 (1986), pp. 679698.


11 | 11