在Canny邊緣檢測法中,首先是在x和y方向求一階導數,然後組合爲4個方向的導數。這些方向導數達到局部最大值的點就是組成邊緣的候選點。
Canny算法中最重要的一個新特點就是其試圖將獨立邊緣的候選像素拼裝成輪廓。輪廓的形成是對這些像素運用滯後性閾值。這意味着有兩個閾值,上限和下限。
如果一個像素的梯度大於上限閾值,則被認爲是邊緣像素,如果低於下限閾值,則被拋棄,如果介於二者之間,只有當其與高於上限閾值的像素連接時纔會被接受。
Canny一般推薦的閾值比例爲2:1 到 3:1之間
void cvCanny(const CvArr * img,CvArr * edges , double lowThresh,double highThresh , int apertureSize = 3);
cvCanny()函數需要輸入一幅灰度圖像,輸出圖也一定是灰度的。接下來兩個參數的下限閾值和上限閾值,最後一個參數是另一箇中孔。通常,這個被Sobel算子用到的中孔是cvCanny()內部使用的。
下面設置高低閾值的比例爲3:2
分別將高閾值設置在(0,50),(50,100),(100,150),(150,200),(200,250)之間
int main(int argc, const char * argv[]) {
/*1、加載一幅灰度圖像*/
const char filename[] = "/Users/linwang/Downloads/Lena.jpg";
IplImage * Img = cvLoadImage(filename,CV_LOAD_IMAGE_GRAYSCALE);
/*2、縮小一倍*/
IplImage *out = cvCreateImage(cvSize(Img->width/2,Img->height/2), Img->depth, Img->nChannels);
cvResize(Img, out);
cvShowImage("Src", out);
/*3、使用30 cvCanny算子*/
IplImage * edges_30 = cvCloneImage(out);
cvCanny(out, edges_30, 20, 30);
cvShowImage("edges_30", edges_30);
/*4、使用75 cvCanny算子*/
IplImage * edges_75 = cvCloneImage(out);
cvCanny(out, edges_75, 50, 75);
cvShowImage("edges_75", edges_75);
/*4、使用120 cvCanny算子*/
IplImage * edges_120 = cvCloneImage(out);
cvCanny(out, edges_120, 80, 120);
cvShowImage("edges_120", edges_120);
/*4、使用120 cvCanny算子*/
IplImage * edges_180 = cvCloneImage(out);
cvCanny(out, edges_180, 120, 180);
cvShowImage("edges_180", edges_180);
/*4、使用120 cvCanny算子*/
IplImage * edges_240 = cvCloneImage(out);
cvCanny(out, edges_240, 180, 240);
cvShowImage("edges_240", edges_240);
cvReleaseImage(&Img);
cvReleaseImage(&out);
cvReleaseImage(&edges_30);
cvReleaseImage(&edges_75);
cvReleaseImage(&edges_120);
cvReleaseImage(&edges_180);
cvReleaseImage(&edges_240);
cvWaitKey(0);
return 0;
}