演算法|Canny演算法簡介

  • 2019 年 12 月 17 日
  • 筆記

問題描述

1 演算法用途

在處理影像時,有時我們需要影像的邊界或通過邊界得到一定的資訊,如何有效而準確的找到這些邊界並顯示出來就了一個問題,而Canny演算法則可以很好的解決它。

2 演算法主要原理

影像中的邊緣點即是影像中局部區域顏色變化較大或者亮度突然變化的區域,Canny演算法採用非極大值抑制,判斷是否為邊緣點。

2.1 非極大值抑制

它是查找像素點的局部最大值,如果這個像素點是局部最大值,則保留;否則將其刪除(值設置為0)。

解決方案

3 演算法流程

4 步驟詳情和部分Python實現

4.1 平滑影像

平滑影像主要採用高斯濾波的方法:

#創建高斯矩陣sigma1 = sigma2 = 1sum = 0gaussian = np.zeros([5, 5])#創建一個5*5的一維矩陣for i in range(5): for j in range(5): gaussian[i, j] = math.exp(-1 / 2 * (np.square(i-3) / np.square(sigma1) + (np.square(j-3) / np.square(sigma2)))) / (2 * math.pi * sigma1 * sigma2) sum = sum + gaussian[i, j]gaussian = gaussian / sum#創建高斯濾波器w =img.shape[0]h =img.shape[1]new_img = np.zeros([w-5,h-5])#創建一個新的數組,用於存儲高斯濾波之後的影像for i in range(w-5): for j in range(h-5): new_img[i,j] = np.sum(img[i:i+2,j:j+2]*gaussian)#使用卷積的方法進行高斯濾波

4.2 影像增強

增強邊緣的基礎是確定影像各點鄰域強度的變化值。增強演算法可以將影像灰度點鄰域強度值有顯著變化的點凸顯出來。這些點一般通過計算梯度幅度來確定。

數字影像處理中,為了簡便運算可以使用差分近似求取灰度值的梯度值(變化率)。即:使差商(Δf-Δx)近似取代微商(∂f/∂x)。

w1=new_img.shape[0]h1=new_img.shape[1]theta = np.zeros([w1-1, h1-1])dx = np.zeros([w1-1, h1-1])dy = np.zeros([w1-1, h1-1])d = np.zeros([w1-1, h1-1])#創建新數組用於存儲得到的梯度幅度影像for i in range(w1-1): for j in range(h1-1): dx[i,j] = new_img[i, j+1] - new_img [i, j] dy[i,j] = new_img [i+1, j] - new_img [i, j] d[i,j]=np.sqrt(np.square(dx[i,j])+ np.square(dy[i,j])) #計算梯度方向 theta[i, j] = math.atan(dx[i, j] / (dy[i, j] + 0.000000001))

4.3 非極大值抑制

判斷該點是否為局部最大值,只需要比較該點的梯度幅度和梯度方向的兩個亞像素點的梯度幅度大小,而亞像素點梯度幅度可以通過計算梯度方向兩側的像素點的權重得到,如圖:

圖4.3.1 G點和局部像素點示例

weight = |dx| / |dy| ,T1 = weight*G1 + (1-weight)*G2

T2 = weight*G3 + (1-weight)*G4,則只需要確定梯度方向然後進行比較判斷。

4.4 雙閾值確定邊緣

在極大值抑制後,還需要設置一大一小兩個邊界值,認為大於大邊界的點為真邊緣,小於小邊界的為假邊緣,處於中間的像素點如多連接有真邊緣,則也被認定為真邊緣,非則為假邊緣。

結語

在影像增強時,也可以使用一些專門的運算元進行計算,上述程式碼只是採用了較為簡單的方法;同時,在確定邊緣點時,也有不同的思路,因此重點是需要掌握Canny演算法的思路,具體操作可以根據自身對程式碼的掌握程度而確定。

END

實習編輯 | 王文星

責 編 | 饒龍江

Tags: