1. 程式人生 > >三種影象處理的基本邊緣檢測法

三種影象處理的基本邊緣檢測法

三種最基本的邊緣檢測法

1:直接對影象平滑濾波,之後利用sobel運算元計算影象梯度,進行閾值處理,得到影象邊緣圖。這是最基本的邊緣檢測方法。效果當然一般般而且容易產生邊緣斷線。

2:Marr-Hildreth檢測法,Marr和Hildreth兩位前輩證明,

1)灰度變化和影象尺度無關(不管影象是大是小,比如將同一張圖片進行縮放,他的邊緣應該是不會改變的),所以檢測的時候要用不同尺寸的運算元(比如大圖片如果使用很小的運算元,一條線容易變成一個區域被0畫素隔開)。

2)灰度變化會在一階導數引起波峰波谷,在二階導數引起零交叉。

於是證明出滿足這些條件最好的運算元是LOG,也就是先高斯濾波,再拉普拉斯,求得零交叉

,在opencv上對應程式碼

GaussianBlur(src, src, Size(3, 3), 1.5, 1.5);  

Laplacian(src, dst, src.depth(), 3, 1, 0, BORDER_DEFAULT);  

但令人奇怪的是,這兩個函式都沒有輸入閾值的引數,可能opencv在兩個函式內自動計算的吧。

3:Canny運算元也是用的最多的運算元,先高斯濾波,在求梯度幅值影象,然後非最大值抑制,最後雙閾值處理+連線分析進行連線邊緣

非最大值抑制能夠產生更細的邊緣影象,因為求梯度是一階偏導運算,而一階導數求出的邊緣是比較粗的,最後如果還是覺得邊緣很粗的話

可以用形態學細化演算法,注意的是在Canny中選取雙閾值時Canny前輩提示我們用1:3

,或者1:2的效果更好。

Mat grayimg;

Mat flower = imread("D:/picture/orange.jpg");

cvtColor(flower, grayimg, COLOR_BGR2GRAY);

GaussianBlur(grayimg, grayimg, Size(5, 5), 2);

imshow("[高斯濾波]效果圖", grayimg);
Canny(grayimg, grayimg, 30, 60);
imshow("[canny檢測]運算元的邊緣檢測", grayimg);

注意:再求影象的邊緣的時候必須先將影象轉換為灰度影象。原因引用百度知道里的朋友的回答:“

由於邊緣檢測基本是用梯度運算元完成的,梯度是在座標(x,y)處指向f最大變化率的方向的向量,而彩色影象實際是由若干種原色(如RGB)構成的,如果直接檢測彩色影象邊緣也就是對每種色彩單獨檢測,但是各原色在一點處的梯度方向可能不同,從而得到的邊緣也不同,會發生錯誤。要採用計算平均向量可以解決該問題但複雜性提高。
疑惑:在剛薩雷斯的書中,作者提示我們在選取高斯濾波模板(n*n)和標準差(σ)時應該使n為大於等於6σ的最小奇整數,但在實際用opencv函式Gaussianblur()進行效果檢驗的時候發現使n大於標準差的6倍效果並不是最好的,不知道作者這句話是什麼意思。


----------------------分割線----------------------------------------------------------------------------

疑惑解答:最近看到了一篇部落格,裡面就提到了高斯濾波模板之所以選擇6σ的原因,原文如下
高斯模版是圓對稱的,且卷積的結果使原始畫素值有最大的權重,距離中心越遠的相鄰畫素值權重也越小。
在實際應用中,在計算高斯函式的離散近似時,在大概距離之外的畫素都可以看作不起作用,這些畫素的計算也就可以忽略。所以,通常程式只計算(6σ+1)*(6σ+1)就可以保證相關畫素影響。
而且標準差的大小決定影象的平滑程度,大尺度對應影象的概貌特徵,小尺度對應影象的細節特徵。大的標準差對應低分辨的粗糙尺度,反之對應精細尺度。


引用連結:http://blog.csdn.net/xiaowei_cqu/article/details/8067881

http://blog.csdn.net/abcjennifer/article/details/7639681/