12.25 OpenCV-Python Canny邊緣檢測

目標

在本章中,我們將學習

  • Canny邊緣檢測的概念
  • OpenCV函數: cv.Canny()

理論

Canny Edge Detection是一種流行的邊緣檢測算法。它由John F. Canny發明

這是一個多階段算法,我們將經歷每個階段。

降噪

由於邊緣檢測容易受到圖像中噪聲的影響,因此第一步是使用5x5高斯濾波器消除圖像中的噪聲。我們已經在前面的章節中看到了這一點。

查找圖像的強度梯度

然後使用Sobel核在水平和垂直方向上對平滑的圖像進行濾波,以在水平方向(Gx)和垂直方向(Gy)上獲得一階導數。從這兩張圖片中,我們可以找到每個像素的邊緣漸變和方向,如下所示:


OpenCV-Python Canny邊緣檢測 | 十九


漸變方向始終垂直於邊緣。將其舍入為代表垂直,水平和兩個對角線方向的四個角度之一。

非極大值抑制
在獲得梯度大小和方向後,將對圖像進行全面掃描,以去除可能不構成邊緣的所有不需要的像素。為此,在每個像素處,檢查像素是否是其在梯度方向上附近的局部最大值。查看下面的圖片:

OpenCV-Python Canny邊緣檢測 | 十九

點A在邊緣(垂直方向)上。漸變方向垂直於邊緣。點B和C在梯度方向上。因此,將A點與B點和C點進行檢查,看是否形成局部最大值。如果是這樣,則考慮將其用於下一階段,否則將其抑制(置為零)。 簡而言之,你得到的結果是帶有“細邊”的二進制圖像。

磁滯閾值

該階段確定哪些邊緣全部是真正的邊緣,哪些不是。為此,我們需要兩個閾值minVal和maxVal。強度梯度大於maxVal的任何邊緣必定是邊緣,而小於minVal的那些邊緣必定是非邊緣,因此將其丟棄。介於這兩個閾值之間的對象根據其連通性被分類為邊緣或非邊緣。如果將它們連接到“邊緣”像素,則將它們視為邊緣的一部分。否則,它們也將被丟棄。見下圖:

OpenCV-Python Canny邊緣檢測 | 十九

邊緣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>

附加資源

  1. Canny edge detector at Wikipedia:http://en.wikipedia.org/wiki/Cannyedgedetector
  2. Canny Edge Detection Tutorial:http://dasl.unlv.edu/daslDrexel/alumni/bGreen/www.pages.drexel.edu/weg22/cantut.html by Bill Green, 2002.

練習

  1. 編寫一個小應用程序以找到Canny邊緣檢測,該檢測的閾值可以使用兩個跟蹤欄進行更改。這樣,您可以瞭解閾值的影響。


分享到:


相關文章: