三天不練手生,一月不看傻眼。
原理
Canny邊緣檢測是一種非常流行的邊緣檢測算法,是John F.Canny在1986年提出的。它是一個由很多步構成的算法,我們接下來會逐步介紹:
(1) 噪聲去除
由於邊緣檢測很容易受到噪聲影響,所以第一步是使用5x5的高斯濾波器去除噪聲。
(2) 計算圖像梯度
對平滑後的圖像使用 Sobel 算子,計算水平方向和豎直方向的一階導數(圖像梯度)。根據得到的這兩幅梯度圖(Gx和Gy)找到邊界的梯度和方向,公式如下:
梯度方向被歸爲四類:垂直、水平、兩個對角線。
梯度的方向通常是與邊界垂直。
(3) 非極大值抑制
在獲得梯度的方向和大小之後,應該對整幅圖像做一個掃描,去除那些非邊界上的點。對每一個像素進行檢查,看這個點的梯度是不是周圍具有相同梯度方向的點中最大的。如下圖所示:
A點在邊界上,梯度方向是邊界的法向量。點B和點C在梯度方向上面,所以拿點A來檢測點B和C是否形成了本地最大值,如果形成最大值,那麼就進行下一步,否則進行抑制(賦值爲0)。
簡單的說,得到了二值圖像的邊界,現在得到的是一個包含“窄邊界”的二值圖像。
(4) 滯後閾值
現在要確定哪些邊界纔是真正的邊界。這時我們需要設置兩個閾值:minVal和maxVal。
當圖像的灰度梯度高於maxVal時被認爲是真的邊界,那些低於 minVal 的邊界會被拋棄。如果介於兩者之間的話,就要看這個點是否與某個被確定爲真正的邊界點相連,如果是就認爲它也是邊界點,如果不是就拋棄。如下圖:
A高於閾值maxVal,所以是真正的邊界點。C雖然低於maxVal但高於minVal,並且與A相連,所以也被認爲是真正的邊界點。而B就會被拋棄,因爲它不僅低於maxVal而且不與真正的邊界點相連。所以選擇合適的maxVal和minVal對於能否得到好的結果非常重要。在這一步一些小的噪聲點也會被除去,因爲我們假設邊界都是一些長的線段。
OpenCV中的Canny邊界檢測
返回頂部
在OpenCV中只需要一個函數:cv2.Canny(),就可以完成以上幾步。
Canny(image, threshold1, threshold2, edges=None, apertureSize=None, L2gradient=None)
讓我們看如何使用這個函數:
第一個參數是輸入圖像;
第二和第三個分別是minVal和maxVal;
第四個參數用來設置Sobel卷積核的大小,默認值爲3;
最後一個參數是L2gradient,它可以用來設定求梯度大小的方程:如果設爲True,就會使用我們上面提到過的方程(L2範數);否則使用方程:
代替,默認值爲False。
代碼示例一(在一起)
import cv2
from matplotlib import pyplot as plt
img = cv2.imread('3.jpg', 0)
edges = cv2.Canny(img, 100, 200)
plt.subplot(121)
plt.imshow(img, cmap='gray')
plt.title('Original Image')
plt.xticks([])
plt.yticks([])
plt.subplot(122)
plt.imshow(edges, cmap='gray')
plt.title('Edge Image')
plt.xticks([])
plt.yticks([])
plt.show()
代碼示例二(乘風破浪)
返回頂部
(小練習——滾動條調節minVal和maxVal)
import cv2
def nothing(x):
pass
if __name__ == '__main__':
img = cv2.imread('chengfengpolang.jpg')
edges = img
cv2.namedWindow('Original')
cv2.namedWindow('Canny')
cv2.createTrackbar('Min', 'Canny', 0, 100, nothing)
cv2.createTrackbar('Max', 'Canny', 100, 200, nothing)
while True:
cv2.imshow('Original', img)
cv2.imshow('Canny', edges)
minVal = cv2.getTrackbarPos('Min', 'Canny')
maxVal = cv2.getTrackbarPos('Max', 'Canny')
edges = cv2.Canny(img, minVal, maxVal)
if cv2.waitKey(1) & 0xFF == ord('q'):
break
cv2.destroyAllWindows()
隨想
那些以局外人心態來指責中國程序員做不出來MatLab、編程語言的同胞們,自己的工作是否做到自己滿意?有空可以學學編程,練練腦子。
正如那些批判國足的人們,可以下場踢踢足球,流流汗。
不過,中國的程序員和國足們,確實也該努力去披荊斬棘、乘風破浪!!!
歡迎關注,敬請點贊!
返回頂部