【翻譯:OpenCV-Python教程】坎尼邊緣檢測

⚠️由於自己的拖延症,3.4.3翻到一半,OpenCV發佈了4.0.0了正式版,所以接下來是按照4.0.0翻譯的。

⚠️除了版本之外,其他還是照舊,Canny Edge Detection,原文

目標

在這一節,我們將學到:

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

理論

坎尼邊緣檢測是一個很受歡迎的邊緣檢測算法。它是被 John F. Canny 發明的:

  1. 它是一個多階段的算法,我們將會把每個階段都過一遍。
  2. 降低噪聲

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

  3. 找到圖像的強烈梯度

    (通過上一步高斯)平滑後的圖像,在通過索貝爾內核在水平和垂直方向濾波,來獲取兩個方向的一階導數(Gx)和(Gy)。從這兩個圖像我們可以找到每個像素邊緣的梯度和方向,如下:

    Edge\_Gradient \;(G) = \sqrt{G_x^2 + G_y^2} \\Angle \; (\theta) = \tan^{-1} \bigg(\frac{G_y}{G_x}\bigg)

    梯度方向總是垂直於邊緣。圓角爲代表垂直、水平和兩個對角線方向的四個角之一。

  4. 非極大值抑制

    在獲取到了梯度的幅值和方向之後,對圖像進行全掃描,去除可能不構成邊緣的不需要的像素。要達到這個目的,遍歷每個像素,如果像素是梯度方向上其鄰域內的局部最大值,則該像素點通過檢測。查看下面的圖示:

    nms.jpg

    點A處於邊緣之上(在垂直方向上的邊緣)。梯度方向垂直於邊緣,點B和點C在梯度方向上,因此點A得通過點B和點C在水平方向上來檢測。如果如此(A點確實是局部最大值得話),那麼就進入下個環節,否則就抑制A點(把A點設置爲0(這樣A點就和經過前幾步處理的背景色一樣了))。

    簡單來說,你這一步得到的結果就是一張具有“細邊”的二元圖像。

  5. 滯後閾值法

    這一個步驟,決定了(之前計算出來通過檢測的點組成的)所有的邊緣,哪些是真正的邊緣,哪些不是。要達到這個目的,我們需要最大、最小兩個閾值。任何強度梯度大於最大閾值的邊被認爲是邊緣,小於最小閾值的邊一定是非邊邊緣,所以丟棄掉。位於這兩個閾值之間的邊界,根據它們的連通性分爲邊緣和非邊緣。如果它們被連接到“確定邊緣”像素,它們被認爲是邊緣的一部分。否則,它們也會被丟棄。見下圖:

    hysteresis.jpg

    邊緣A在最大閾值之上,因爲我們認爲它是確定邊緣。儘管邊緣C在最大閾值之下(同時在最小閾值之上),但它與A邊緣是連通的,所以C也被認爲是有效的邊緣我們也得到了完整的弧線。而B邊雖然在最小閾值之上,處於和C邊相同的區域,但卻並未與(像A邊這樣的)確定邊緣連通,所以它就被丟棄了。因此,我們必須相應地選擇最大閾值和最小閾值來得到正確的結果,這是非常重要的。

    加入邊緣是長線段的話,這一個步驟還會消除一些小像素的噪聲。

因此我們最終得到的是圖像中的強邊界。

OpenCV裏的坎尼邊緣檢測

OpenCV 把上面的所有步驟放進了同一個方法中,cv.Canny()。我們來看看怎麼使用它。第一個參數是輸入圖像。第二和第三個參數分別是我們的最大和最小閾值。第三個參數是孔徑大小,它是用於尋找圖像梯度的索貝爾內核的大小,默認情況下是3。最後 L2gradient 參數指定了求梯度大小的方程。如果爲True,則使用之前講的公式,算出來更準確。否則使用這個函數:邊梯度(G) = |Gx| + |Gy|。默認情況下,這個值是False。

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()

看看以下結果:

canny1.jpg

 

額外資源

Exercises

  • 寫一個小應用來做坎尼邊緣檢測,用兩個拖動條來控制最大最小閾值,這樣你就可以理解這兩個閾值對結果造成的影響。

上篇:【翻譯:OpenCV-Python教程】圖像梯度

下篇:【翻譯:OpenCV-Python教程】圖像金字塔

發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章