影像的邊緣檢測

abcjob發表於2021-09-09

最近整理一些學習筆記,因為覺得自己基礎不紮實,很多演算法能用卻不知其根源,因此需要不斷去回顧和歸納。這篇先寫寫影像的邊緣檢測。

邊緣檢測就是一個尋找邊緣畫素的過程,這些邊緣一般就是區域性畫素變化比較顯著的一些點,主要存在於目標和目標以及前景背景之間。找到這些邊緣,對於影像分割與目標識別是很有幫助的。

常用的邊緣檢測運算元有很多,這裡以sobel、拉普拉斯運算元和canny運算元為例,做一些比較。

Sobel運算元

Sobel 運算元結合了高斯平滑和微分求導。它是一階導數的邊緣檢測運算元,使用卷積核與影像中的每個畫素點做卷積和運算,然後採用合適的閾值提取邊緣。Soble運算元有兩個卷積核,分別對應的是x與y兩個方向。

計算過程

1.分別在x和y兩個方向求導。

2.在影像的每一點,結合以上兩個結果求出近似梯度:

cv2.Sobel(src, ddepth, dx, dy[, dst[, ksize[, scale[, delta[, borderType]]]]])
  • src是需要處理的影像;

  • ddepth是影像的深度,-1表示採用的是與原影像相同的深度。目標影像的深度必須大於等於原影像的深度;這裡使用了cv2.CV_16S 即16位有符號的資料型別,以防止截斷。 - dx和dy表示的是求導的階數,0表示這個方向上沒有求導,一般為0、1、2。

  • ksize是Sobel運算元的大小,必須為1、3、5、7。

Laplace運算元

拉普拉斯運算元是一種二階導數運算元。在影像中的邊緣區域,畫素值會發生比較大的變化,對這些畫素求導,會看到極值出現,在這些極值位置,其二階導數為0,所以也可以用二階導數來檢測影像邊緣。

Laplacian運算元的定義:

圖片描述

laplace.gif

cv2.Laplacian(src, ddepth[, dst[, ksize[, scale[, delta[, borderType]]]]])
  • src是需要處理的影像;

  • ddepth是影像的深度,解釋同上文sobel。

  • ksize是運算元的大小,必須為1、3、5、7。預設為1。

Canny

Canny運算元的基本思想是尋找梯度的區域性最大值。運算元是比較簡單的,也很容易實現。

一般步驟:
1. 高斯濾波影像去噪。一般情況下,使用高斯平滑濾波器卷積降噪。
2.計算梯度幅值和方向。運用一對卷積陣列(分別作用於x和y方向)
3.非極大值抑制。這一步排除非邊緣畫素, 僅僅保留了一些細線條(候選邊緣)。
4.需要兩個閾值(高閾值和低閾值)檢測和連線邊緣:

如果某一畫素位置的幅值超過高閾值, 這個畫素被保留為邊緣畫素。如果小於低閾值, 該畫素被排除。如果在兩個閾值之間,要看這個畫素的鄰接畫素中有沒有超過高閾值的邊緣畫素。如果有,這畫素就是邊緣,否則就不是。

cv2.Canny(scr, threshold1, threshold2[, edges[, apertureSize[, L2gradient]]])

這裡scr是需要處理的原影像,該影像必須為單通道的灰度圖;   threshold1是閾值1;   threshold2是閾值2。

例項程式碼

下面用Python-OpenCV程式碼比較下上面幾種運算元的效果。

"""
Created on Thu Oct 25 11:25:15 2018
@author: 晚晴風
"""import cv2

img = cv2.imread("pascal_19.jpg")#cannygray = cv2.cvtColor(img,cv2.COLOR_BGR2GRAY)
blur = cv2.GaussianBlur(gray,(3,3),0)#高斯濾波器對影像降噪canny = cv2.Canny(blur,50,150)

cv2.imshow('canny',canny)#sobelgrad_x = cv2.Sobel(img,cv2.CV_16S,1,0,ksize = 3)
grad_y = cv2.Sobel(img,cv2.CV_16S,0,1,ksize = 3)#第二個引數為影像的深度u_x = cv2.convertScaleAbs(grad_x) #轉化成為8點陣圖形CV_8U進行顯示u_y = cv2.convertScaleAbs(grad_y)
sobel_xy = cv2.addWeighted(u_x,0.5,u_y,0.5,0)#兩方向加權求近似梯度cv2.imshow('sobelX',u_x)
cv2.imshow('sobelY',u_y)
cv2.imshow('sobelXY',sobel_xy)#Laplacelap = cv2.Laplacian(img,cv2.CV_16S,ksize = 3)
laplacian = cv2.convertScaleAbs(lap)

cv2.imshow('laplacian',laplacian)
cv2.waitKey(0)
cv2.destroyAllWindows()#釋放視窗

執行之後就可以看到三種運算元的邊緣檢測結果:

原圖:

圖片描述

pascal_19.jpg

Canny運算元:

圖片描述

canny.jpg

Sobel運算元:

圖片描述

sobelXY.jpg

Laplace運算元:

圖片描述

laplacian.jpg

總結:
  • Sobel運算元在邊緣檢測的同時儘量的削弱了噪聲。比較容易實現,受噪聲的影響力比較小。它對於畫素位置的影響作了加權,因此效果更好、應用廣泛。

  • Laplace運算元是一種各向同性運算元,在只關心邊緣的位置而不考慮其周圍的象素灰度差值時比較合適。Laplace運算元對孤立象素的響應要比對邊緣或線的響應要更強烈,因此只適用於無噪聲圖象。存在噪聲情況下,使用Laplacian運算元檢測邊緣之前需要先進行低通濾波。

  • Canny運算元是目前理論上相對最完善的一種邊緣檢測演算法。也存在不足之處: 為了得到較好的邊緣檢測結果,它通常需要使用較大的濾波尺度,這樣容易丟失一些細節。運算元的雙閾值要人為的選取,這需要經驗:)



作者:晚晴風_
連結:


來自 “ ITPUB部落格 ” ,連結:http://blog.itpub.net/4798/viewspace-2819331/,如需轉載,請註明出處,否則將追究法律責任。

相關文章