轉載請說明出處:http://blog.csdn.net/zhubaohua_bupt/article/details/73826080
Canny邊緣檢測算子是John F. Canny於 1986 年開發出來的一個多級邊緣檢測算法。
Canny 的目標是找到一個最優的
邊緣檢測
算法,最優邊緣檢測的含義是:
好的檢測- 算法可以儘量多地標識出圖像中的實際邊緣。
好的定位- 標識出的邊緣要儘量與實際圖像中的實際邊緣儘量接近。
最小響應- 圖像中的邊緣只能標識一次,而且可能存在的圖像噪聲不該標識爲邊緣
——摘自百度百科
最近作了個項目,須要canny邊緣檢測,可是,在平臺上不支持opencv,因此就研究了一下canny邊緣檢測的原理,並用c++實現算法。
1 原理部分
Canny邊緣檢測整個流程共分爲4步,分別是
*濾波、
*梯度及方向角計算(加強)、
*邊緣非極大值抑制、
*雙閾值鏈接,
下面以一個圖像邊緣檢測的流程探討一下每一個部分。
原圖爲
1.1 濾波
1.1.1爲何要濾波?
濾波的目的是爲了平滑一些紋理較弱的非邊緣區域,從而更準確的檢測邊緣。
1.1.2 高斯濾波
常見的濾波算法有均濾波、中值濾波、高斯濾波、雙邊濾波等等。咱們知道,均值濾波能夠模糊圖像;
中值濾波能夠去除椒鹽噪聲; 雙邊濾波能夠保留邊緣,平滑非邊緣區域。canny邊緣檢測使用的高斯濾波,
和均值、雙邊濾波同樣,高斯濾波也是經過對圖像模板卷積實現的,
只不過模板的內容不同。下面探究一下高斯濾波:
高斯濾波的模板(高斯核)是利用高斯函數造成的。
高斯核造成中有一個比較重要的參數,即方差,方差控制着高斯濾波對圖像的平滑程度。方差越大,濾波後的圖像越平滑。
極限狀況下,方差無限大,高斯濾波退化成均值濾波。濾波就說到這裏,關於高斯濾波更詳細的特性能夠自行百度。
1.1.3 高斯核爲3,7時的效果
1.2 梯度及方向角計算
canny利用sobel算子來計算通過濾波後,圖像的梯度和方向角。
高斯核大小分別爲3,7時,sobel效果
1.3 非極大值抑制
在圖像邊緣區域,其附近梯度值每每都很大,爲了知足最小響應標準,canny採用了非極大值抑制,
來去除真實邊緣附近的其餘梯度較大的區域。
非極大值抑制的思想是,沿着梯度方向,若是當前待檢測像素的梯度不是最大值,那麼,此像素就不是邊緣。html
爲了簡化計算,因爲一個像素周圍有八個像素,本文把一個像素的梯度方向離散爲八個方向,以下圖c++
把像素可能的360梯度方向分爲8個扇區,每一個扇區對應一個像素位置。這樣就能夠不利用插值,計算像素沿梯度方向先後的兩個像素值。
這樣,對於一個像素,其先後像素的計算就對應4種狀況,好比像素p的梯度方向角爲12.1度,
那麼該像素沿着梯度方向先後的兩個像素分別爲(i-1,j+1),(i+1,j-1)。算法
高斯核分別爲3,7時 ,通過非極大值抑制後的邊緣函數


1.4 雙閾值鏈接
通過以上3個步驟,咱們已經能夠獲得一個通過非極大值抑制的邊緣圖像,若是沒有什麼特殊要求,這個邊緣圖像就能夠利用了。spa
之因此要有雙閾值鏈接這一步,是由於在獲取圖像邊緣時,咱們但願獲得一些梯度比較大邊緣,即獲得一些特徵較鮮明的邊緣。.net
這樣就必須設定一個閾值highThreshold來卡一下梯度值,只有圖像梯度值大於highThreshold時才認爲這些邊緣特徵鮮明。可是,htm
以下圖, 只設定一個閾值會出現這樣的問題,就是檢測到的邊緣不連續,blog

爲了獲得特徵明顯且連續的邊緣,所以,canny採用了雙閾值鏈接法。開發
即再設定一個低閾值,lowThreshold,用lowThreshold卡一下梯度圖像,記錄所用大於此閾值的像素位置,用來鏈接通過highThreshold閾值後get
不連續的邊緣。鏈接後圖像以下,lowThreshold和highThreshold 一低 一高,爲何叫雙閾值,相信一下就明白了吧。

雙閾值鏈接效果,高斯核分別爲3,7


實現部分見下篇博客
參考:
1 http://blog.csdn.net/yanmy2012/article/details/8110316
2 http://blog.csdn.net/xiajun07061225/article/details/6926108
3 http://www.cnblogs.com/qiqibaby/p/5289977.html
4 http://blog.csdn.net/dcrmg/article/details/52344902