前面我們用sobel算子和拉普拉斯變換也可以進行邊緣檢測,見我的上一篇blog:
http://blog.csdn.net/lu597203933/article/details/17252285
但這樣得到的二值邊緣圖像有兩大缺點。第一:檢測到的邊緣過粗,這意味着難以實現物體的精確定位。第二:難以找到這樣的閥值,即能足夠低檢測到所有重要的邊緣,同時也不至於包含過多次要的邊緣。
這個正是canny算子要解決的。
Canny算子通常基於sobel算子,有兩個閥值,這樣可以得到兩幅邊緣圖;canny算法組合這兩幅邊緣圖以生成一副“最優”的輪廓圖。如果存在連續的邊緣點,則將低閥值圖像中的邊緣點與高閥值圖像中的邊緣相連接,那麼就保留低閥值圖像中的邊緣點。這種使用雙閥值以得到二值圖像的策略被稱爲磁滯閥值化。
代碼:
結果:
當然你也可以將其與上篇博客中的結果進行比對,發現效果會好很多。
另附上:
Matlab的Canny算子
BW =edge(I,'canny')
用canny算子實現邊緣檢測
BW =edge(I,'canny',thresh)
爲canny算法指定sensitivitythresholds(閾值)。
指定兩個閾值(二維矢量):第一個元素爲低閾值,第二個元素爲高閾值。
指定一個閾值(單個數值):用作高閾值,低閾值爲0.4*高閾值。
未指定閾值(或用[]代替):自動根據圖像的梯度直方圖計算高低閾值。
BW =edge(I,'canny',thresh,sigma)
sigma 表示高斯濾波器的標準差,默認值爲sqrt(2)。濾波器大小根據sigma值自動計算。
[BW,thresh] =edge(I,'canny',...)
用thresh返回兩個閾值。
OpenCV的Canny算子
cvCanny函數頭:
void cvCanny(
const CvArr* img,
CvArr* edges,
double lowThresh,
double highThresh,
int apertureSize = 3
);
image 單通道輸入圖像
edges 單通道圖像,保存圖像邊緣
threshold1 閾值1
threshold2 閾值2
apertureSize Sobel算子的孔徑參數 (參見 cvSobel 函數)
------------------------------
來自:http://hi.baidu.com/windroc/item/2c3afac341a6542cee4665ca
作者:小村長 出處:http://blog.csdn.net/lu597203933 歡迎轉載或分享,但請務必聲明文章出處。 (新浪微博:小村長zack, 歡迎交流!