目標
在本章中,我們將學習
- Canny邊緣檢測的概念
- OpenCV函數: cv.Canny()
理論
Canny Edge Detection是一種流行的邊緣檢測算法。它由John F. Canny發明
這是一個多階段算法,我們將經歷每個階段。
降噪
由於邊緣檢測容易受到圖像中噪聲的影響,因此第一步是使用5x5高斯濾波器消除圖像中的噪聲。我們已經在前面的章節中看到了這一點。
查找圖像的強度梯度
然後使用Sobel核在水平和垂直方向上對平滑的圖像進行濾波,以在水平方向(Gx)和垂直方向(Gy)上獲得一階導數。從這兩張圖片中,我們可以找到每個像素的邊緣漸變和方向,如下所示:
漸變方向始終垂直於邊緣。將其舍入為代表垂直,水平和兩個對角線方向的四個角度之一。
非極大值抑制
在獲得梯度大小和方向後,將對圖像進行全面掃描,以去除可能不構成邊緣的所有不需要的像素。為此,在每個像素處,檢查像素是否是其在梯度方向上附近的局部最大值。查看下面的圖片:
點A在邊緣(垂直方向)上。漸變方向垂直於邊緣。點B和C在梯度方向上。因此,將A點與B點和C點進行檢查,看是否形成局部最大值。如果是這樣,則考慮將其用於下一階段,否則將其抑制(置為零)。 簡而言之,你得到的結果是帶有“細邊”的二進制圖像。
磁滯閾值
該階段確定哪些邊緣全部是真正的邊緣,哪些不是。為此,我們需要兩個閾值minVal和maxVal。強度梯度大於maxVal的任何邊緣必定是邊緣,而小於minVal的那些邊緣必定是非邊緣,因此將其丟棄。介於這兩個閾值之間的對象根據其連通性被分類為邊緣或非邊緣。如果將它們連接到“邊緣”像素,則將它們視為邊緣的一部分。否則,它們也將被丟棄。見下圖:
邊緣A在maxVal之上,因此被視為“確定邊緣”。儘管邊C低於maxVal,但它連接到邊A,因此也被視為有效邊,我們得到了完整的曲線。但是邊緣B儘管在minVal之上並且與邊緣C處於同一區域,但是它沒有連接到任何“確保邊緣”,因此被丟棄。因此,非常重要的一點是我們必須相應地選擇minVal和maxVal以獲得正確的結果。
在邊緣為長線的假設下,該階段還消除了小像素噪聲。
因此,我們最終得到的是圖像中的強邊緣。
OpenCV中的Canny Edge檢測
OpenCV將以上所有內容放在單個函數cv.Canny()中。我們將看到如何使用它。第一個參數是我們的輸入圖像。第二個和第三個參數分別是我們的minVal和maxVal。第三個參數是perture_size。它是用於查找圖像漸變的Sobel內核的大小。默認情況下為3。最後一個參數是L2gradient,它指定用於查找梯度幅度的方程式。如果為True,則使用上面提到的更精確的公式,否則使用以下函數:$Edge_Gradient ; (G) = |Gx| + |Gy|$。默認情況下,它為False。
<code>import numpy as np
import cv2 as cv
from matplotlib import pyplot as plt
img = cv.imread('messi5.jpg',0)
edges = cv.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()/<code>
附加資源
- Canny edge detector at Wikipedia:http://en.wikipedia.org/wiki/Cannyedgedetector
- Canny Edge Detection Tutorial:http://dasl.unlv.edu/daslDrexel/alumni/bGreen/www.pages.drexel.edu/weg22/cantut.html by Bill Green, 2002.
練習
- 編寫一個小應用程序以找到Canny邊緣檢測,該檢測的閾值可以使用兩個跟蹤欄進行更改。這樣,您可以瞭解閾值的影響。
閱讀更多 人工智能遇見磐創 的文章