1. 程式人生 > >邊緣檢測之Canny演算法_Qt實現(C++)

邊緣檢測之Canny演算法_Qt實現(C++)

邊緣檢測之Canny演算法_Qt實現(C++)

Canny邊緣檢測演算法的簡單介紹

  Canny的目標是找到一個最優的邊緣檢測演算法,最優邊緣檢測的含義是:

  • 好的檢測 - 演算法能夠儘可能多地標識出影象中的實際邊緣。
  • 好的定位 - 標識出的邊緣要與實際影象中的實際邊緣儘可能接近。
  • 最小響應 - 影象中的邊緣只能標識一次,並且可能存在的影象噪聲不應標識為邊緣。

  為了滿足這些要求Canny使用了變分法,這是一種尋找滿足特定功能的函式的方法。最優檢測使用四個指數函式項的和表示,但是它非常近似於高斯函式的一階導數。

Canny演算法的步驟

  • 1、灰度處理
  • 2、降噪,使用高斯濾波器,以平滑影象,濾除噪聲。
  • 3、計算影象中每個畫素的亮度梯度和方向。
  • 4、應用非極大值抑制(Non-Maximum Suppression),以消除邊緣檢測帶來的雜散響應。
  • 5、應用雙闕值檢測(Double-Threshold)來確定真實的和潛在的邊緣。
  • 6、通過抑制孤立的弱邊緣最終完成邊緣檢測。

Canny演算法詳細步驟

  • 1、灰度處理
      邊緣檢測演算法處理的是灰度影象,如果是rgb影象,需要先轉化為灰度影象。
  • 2、高斯平滑濾波
      任何邊緣檢測演算法都不可能在未經處理的原始資料上很好的處理,所以第一步是對原始資料與高斯濾波器做卷積,得到的影象與原始影象相比有些輕微的模糊。使得單獨的一個畫素噪聲在經過高斯平滑的影象上變得幾乎沒有影響。
      若影象中一個3*3的視窗為A,要濾波的畫素點為e,則經過高斯濾波後,畫素點e的亮度值為:
    e = H A = [ h 11 h 12 h 13 h 21 h 22 h 23 h 31 h 32 h 33 ] [ a a b c d e f g h i ] = s u m [ a h 11 b h 12 c h 13 d h 21 e h 22 f h 23 g h 31 h h 32 i h 33 ]
    其中*為卷積符號,sum表示矩陣中所有元素相加求和。

【注1】:高斯濾波器是一個模為奇數的矩陣,大小為 2 k + 1 2 k + 1 的高斯濾波器的生成方程式如下:
H i j = 1 2 π σ 2 exp ( ( i ( k + 1 ) ) 2 + ( j ( k + 1 ) ) 2 2 σ 2 ) ;
1 i , j ( 2 k + 1 )
下面是一個 σ = 1.4 , k = 1 的高斯卷積核(需要歸一化:即每個元素除以元素和,使最後元素和為一):

H = [ 0.0924 0.1192 0.0924 0.1192 0.1538 0.1192 0.0924 0.1192 0.0924 ]

  • 3、計算梯度強度和方向
      影象中的邊緣可以指向各個方向,因此Canny演算法使用四個運算元來檢測影象中的水平、垂直和對角邊緣。邊緣檢測的運算元(如Roberts,Prewitt,Sobel等)返回水平Gx和垂直Gy方向的一階導數值,由此便可以確定畫素點的梯度G和方向theta 。
    G = G x 2 + G y 2
    θ = arctan G y G x
      其中G為梯度強度, θ 表示梯度方向, arctan 為反正切函式。下面以Sobel運算元為例講述如何計算梯度強度和方向。
      x和y方向的Sobel運算元分別為