該文章來源於:http://blog.csdn.net/hitwengqi/article/details/6877864
Canny是常用的邊緣檢測方法,其特點是試圖將獨立邊的候選像素拼裝成輪廓。
(參考:摘自網絡)
John Canny於1986年提出Canny算子,它與Marr(LoG)邊緣檢測方法類似,也屬於是先平滑後求導數的方法。
John Canny研究了最優邊緣檢測方法所需的特性,給出了評價邊緣檢測性能優劣的三個指標:
1.好的信噪比,即將非邊緣點判定爲邊緣點的概率要低,將邊緣點判爲非邊緣點的概率要低;
2.高的定位性能,即檢測出的邊緣點要儘可能在實際邊緣的中心;
3. 對單一邊緣僅有唯一響應,即單個邊緣產生多個響應的概率要低,並且虛假響應邊緣應該得到最大抑制。
用一句話說,就是希望在提高對景物邊緣的敏感性的同時,可以抑制噪聲的方法纔是好的邊緣提取方法。
Canny算子求邊緣點具體算法步驟如下:
1. 用高斯濾波器平滑圖像.
2. 用一階偏導有限差分計算梯度幅值和方向.
3. 對梯度幅值進行非極大值抑制 .
4. 用雙閾值算法檢測和連接邊緣
-----------------------------具體參考博客經典圖像邊緣檢測 - Canny以及圖象處理中的邊緣檢測 - canny算子-------------------------------------------------------------------------------------------------------
Canny算子格式如下:
Canny
採用 Canny 算法做邊緣檢測
void cvCanny( const CvArr* image, CvArr* edges, double threshold1, double threshold2, int aperture_size=3 );
- image
- 單通道輸入圖像.
- edges
- 單通道存儲邊緣的輸出圖像
- threshold1
- 第一個閾值
- threshold2
- 第二個閾值
- aperture_size
- Sobel 算子內核大小 (見 cvSobel).
函數 cvCanny 採用 CANNY 算法發現輸入圖像的邊緣而且在輸出圖像中標識這些邊緣。threshold1和threshold2 當中的小閾值用來控制邊緣連接,大的閾值用來控制強邊緣的初始分割。
- 注意事項:cvCanny只接受單通道圖像作爲輸入。
- 外部鏈接:經典的canny自調整閾值算法的一個opencv的實現見在OpenCV中自適應確定canny算法的分割門限
/*code*/
注意:cvCanny只接受單通道圖像作爲輸入,因此cvLoadImage的第二給參數表示是否加載有顏色的圖像,因設爲0,表示單通道圖像,故src = cvLoadImage( argv[1], 0 );
否則會出現編譯錯誤,會提示canny.cpp不合法。
- #include <highgui.h>
- #include <cv.h>
- #include <cxcore.h> //人臉識別的一個庫文件
- //Canny:Implements Canny algorithm for edge detection.
- int main( int argc, char** argv )
- {
- IplImage* src = NULL;
- IplImage* dst = NULL;
- //載入圖像,轉換爲灰度圖
- src = cvLoadImage( argv[1], 0 );
- //爲canny邊緣圖像申請空間,1表示單通道灰度圖
- dst = cvCreateImage( cvGetSize( src ), IPL_DEPTH_8U, 1 );
- cvCanny( src, dst, 50, 150, 3 );//邊緣檢測
- cvNamedWindow( "src", 1 );
- cvNamedWindow( "canny", 1 );
- cvShowImage( "src", src );
- cvShowImage( "canny", dst );
- cvWaitKey(0);
- cvReleaseImage( &src );
- cvReleaseImage( &dst );
- cvDestroyAllWindows();
- return 0;
- }
/*result*/
src
canny
由此看出,canny算法得到的輪廓比較清新。