python Canny邊緣檢測演算法的實現

2022-10-03 22:09:27 字數 3106 閱讀 4516

影象邊緣資訊主要集中在高頻段,通常說影象銳化或檢測fiach邊緣,實質就是高頻濾波。我們知道微分運算是求訊號的變化率,具有加強高頻分量的作用。在空域運算中來說,對影象的銳化就是計算微分。對於數字影象的離散訊號,微分運算就變成計算差分或梯度。影象處理中有多種邊緣檢測(梯度)運算元,常用的包括普通一階差分,robert運算元(交叉差分),sobel運算元等等,是基於尋找梯度強度。拉普拉斯運算元(二階差分)是基於過零點檢測。通過計算梯度,設定閥值,得到邊緣影象。

canny邊緣檢測運算元是一種多級檢測演算法。2023年由john f. canny提出,同時提出了邊緣檢測的三大準則:

canny演算法出現以後一直是作為一種標準的邊緣檢測演算法,此後也出現了各種基於canny演算法的改進演算法。時至今日,canny演算法及其各種變種依舊是一種優秀的邊緣檢測演算法。而且除非前提條件很適合,你很難找到一種邊緣檢測運算元能顯著地比canny運算元做的更好。

關於各種差分運算元,還有canny運算元的簡單介紹,這裡就不羅嗦了,網上都可以找得到。直接進入canny演算法的實現。canny演算法分為以下幾步。

1. 高斯模糊。

這一步很簡單,類似於log運算元(laplacian of gaussian)作高斯模糊一樣,主要作用就是去除雜訊。因為雜訊也集中於高頻訊號,很容易被識別為偽邊緣。應用高斯模糊去除雜訊,降低偽邊緣的識別。但是由於影象邊緣資訊也是高頻訊號,高斯模糊的半徑選擇很重要,過大的半徑很容易讓一些弱邊緣檢測不到。

2. 計算梯度幅值和方向。

影象的邊緣可以指向不同方向,因此經典canny演算法用了四個梯度運算元來分別計算水平,垂直和對角線方向的梯度。但是通常都不用四個梯度運算元來分別計算四個方向。常用的邊緣差分運算元(如rober,prewitt,sobel)計算水平和垂直方向的差分gx和gy。這樣就可以如下計算梯度模和方向:

梯度角度 範圍從弧度 - 到 ,然後把它近似到四個方向,分別代表水平,垂直和兩個對角線方向(0,45,90,135)。可以以i/8(i=1,3,5,7)分割,落在每個區域的梯度角給乙個特定值,代表四個方向之一。

這裡我選擇sobel運算元計算梯度。sobel演算法很簡單,到處都可以找到,就不列出**來了。相對於其他邊緣運算元,sobel運算元得出來的邊緣粗大明亮。

下圖是對上面半徑2的高斯模糊影象l通道(hsl)應用sobel運算元的梯度模圖,沒有施加任何閥值。

sobel運算元,無閥值

3. 非最大值抑制。

非最大值抑制是一種邊緣細化方法。通常得出來的梯度fiach邊緣不止乙個畫素寬,而是多個畫素寬。就像我們所說sobel運算元得出來的邊緣粗大而明亮,從上面lena圖的sobel結果可以看得出來。因此這樣的梯度圖還是很「模糊」。而準則3要求,邊緣只有乙個精確的點寬度。非最大值抑制能幫助保留區域性最大梯度而抑制所有其他梯度值。這意味著只保留了梯度變化中最銳利的位置。演算法如下:

注意,方向的正負是不起作用的,比如東南方向和西北方向是一樣的,都認為是對角線的乙個方向。前面我們把梯度方向近似到水平,垂直和兩個對角線四個方向,所以每個畫素根據自身方向在這四個方向之一進行比較,決定是否保留。這一部分的**也很簡單,列出如下。pmodule,pdirection分別記錄了上一步梯度模值和梯度方向。

pmoddrow = pmodule + width + 1;

pdirdrow = pdirection + width + 1;

pstrongdrow = pstrong + width + 1;

for (i = 1; i < hend - 1; i++)

pstrongd++;

pmodd++;

pdird++;

} pstrongdrow += width;

pmoddrow += width;

pdirdrow += width;

}下圖是非最大值抑制的結果。可見邊緣寬度已經大大減小。但是這個影象中因為沒有應用任何閥值,還含有大量小梯度模值的點,也就是圖中很暗的地方。下面,閥值要上場了。

非最大值抑制結果

4. 雙閥值。

一般的邊緣檢測演算法用乙個閥值來濾除雜訊或顏色變化引起的小的梯度值,而保留大的梯度值。canny演算法應用雙閥值,即乙個高閥值和乙個低閥值來區分邊緣畫素。如果邊緣畫素點梯度值大於高閥值,則被認為是強邊緣點。如果邊緣梯度值小於高閥值,大於低閥值,則標記為弱邊緣點。小於低閥值的點則被抑制掉。這一步演算法很簡單。

5. 滯後邊界跟蹤。

至此,強邊緣點可以認為是真的邊緣。弱邊緣點則可能是真的邊緣,也可能是雜訊或顏色變化引起的。為得到精確的結果,後者引起的弱邊緣點應該去掉。通常認為真實邊緣引起的弱邊緣點和強邊緣點是連通的,而由雜訊引起的弱邊緣點則不會。所謂的滯後邊界跟蹤演算法檢查乙個弱邊緣點的8連通領域畫素,只要有強邊緣點存在,那麼這個弱邊緣點被認為是真的邊緣保留下來。

這個演算法搜尋所有連通的弱邊緣,如果一條連通的弱邊緣的任何乙個點和強邊緣點連通,則保留這條弱邊緣,否則抑制這條弱邊緣。搜尋時可以用廣度優先或者深度優先演算法,我在這裡實現了應該是最容易的深度優先演算法。一次連通一條邊緣的深度優先演算法如下:

pmoddrow = pmodule + width + 1;

pdirdrow = pdirection + width + 1;

pstrongdrow = pstrong + width + 1;

for (i = 1; i < hend - 1; i++)

pstrongd++;

pmodd++;

pdird++;

} pstrongdrow += width;

pmoddrow += width;

pdirdrow += width;

}下面是對lena圖計算canny邊緣檢測的梯度模圖和二值化圖,高斯半徑2,高閥值100,低閥值50。

canny檢測梯度模圖                        canny檢測梯度二值圖

作為對比,下面是用一階差分和sobel運算元對原圖計算的結果,閥值100。由於一階差分的梯度值相對較小,我對一階差分的梯度值放大了一定倍數,使得它和sobel的梯度值保持同樣的水平。

一階差分梯度模圖                        一階差分梯度二值圖

sobel梯度模圖                          sobel梯度二值圖

很明顯,canny邊緣檢測的效果是很顯著的。相比普通的梯度演算法大大抑制了雜訊引起的偽邊緣,而且是細化過的邊緣,易於後續處理。對於對比度較低的影象,通過調節引數,canny演算法也能有很好的效果。

Canny邊緣檢測

1.canny邊緣檢測基本原理 1 圖象邊緣檢測必須滿足兩個條件 一能有效地抑制雜訊 二必須盡量精確確定邊緣的位置。2 根據對訊雜比與定位乘積進行測度,得到最優化逼近運算元。這就是canny邊緣檢測運算元。3 類似與marr log 邊緣檢測方法,也屬於先平滑後求導數的方法。2.canny邊緣檢測演...

Canny邊緣檢測

canny運算元是邊緣檢測運算元中最常用的一種,是公認效能優良的一種運算元,常被其它邊緣檢測運算元作為標準運算元進行優劣分析。canny演算法基本可以分為3個步驟 平滑 梯度計算 基於梯度值及梯度方向的候選點過濾 1 平滑 影象梯度的計算對雜訊很敏感,因此必須首先對其進行低通濾波。在這裡使用5 5的...

Sobel 邊緣檢測

sobel邊緣檢測演算法 索貝爾運算元 sobel operator 主要用作邊緣檢測,在技術上,它是一離散性差分運算元,用來運算影象亮度函式的灰度之近似值。在影象的任何一點使用此運算元,將會產生對應的灰度向量或是其法向量 sobel 卷積因子為 該運算元包含兩組 3x3的矩陣,分別為橫向及縱向,將...