理論
Canny 邊緣檢測是一種流行的邊緣檢測算法。它是由 John F. Canny 在 1986 年提出。
-
這是一個多階段算法,我們將介紹算法的每一個步驟。
-
降噪
由于邊緣檢測易受圖像中的噪聲影響,因此第一步是使用 5x5 高斯濾波器去除圖像中的噪聲。我們在前面的章節中已經介紹到了這一點。
-
尋找圖像的強度梯度
然后在水平和垂直方向上用 Sobel 內核對平滑后的圖像進行濾波,以獲得水平方向(?編輯)和垂直方向(?編輯)的一階導數。從這兩個圖像中,我們可以找到每個像素的邊緣梯度和方向
漸變方向始終垂直于邊緣。它被四舍五入到表示垂直,水平和兩個對角線方向的四個角度中的一個。
-
非最大抑制
在獲得梯度幅度和方向之后,完成圖像的全掃描以去除可能不構成邊緣的任何不需要的像素。為此,在每個像素處,檢查像素是否是其在梯度方向上的鄰域中的局部最大值。檢查下圖:
A 點位于邊緣(垂直方向)。漸變方向與邊緣垂直。 B 點和 C 點處于梯度方向。因此,用點 B 和 C 檢查點 A,看它是否形成局部最大值。如果是這樣,則考慮下一階段,否則,它被抑制(歸零)。
簡而言之,您得到的結果是具有“細邊”的二進制圖像。
-
滯后閾值
這個階段決定哪些邊緣都是邊緣,哪些邊緣不是邊緣。為此,我們需要兩個閾值,minVal 和 maxVal。強度梯度大于 maxVal 的任何邊緣肯定是邊緣,而 minVal 以下的邊緣肯定是非邊緣,因此被丟棄。位于這兩個閾值之間的人是基于其連通性的分類邊緣或非邊緣。如果它們連接到“可靠邊緣”像素,則它們被視為邊緣的一部分。否則,他們也被丟棄。見下圖:
邊緣 A 高于 maxVal,因此被視為“確定邊緣”。雖然邊 C 低于 maxVal,但它連接到邊 A,因此也被視為有效邊,我們得到完整的曲線。但是邊緣 B 雖然高于 minVal 并且與邊緣 C 的區域相同,但它沒有連接到任何“可靠邊緣”,因此被丟棄。因此,我們必須相應地選擇 minVal 和 maxVal 才能獲得正確的結果。
在假設邊是長線的情況下,該階段也消除了小像素噪聲。
所以我們最終得到的是圖像中的強邊緣。
OpenCV 中的 Canny 邊緣檢測
OpenCV 將以上所有內容放在單個函數中,?cv.Canny()?。我們將看到如何使用它。第一個參數是我們的輸入圖像。第二個和第三個參數分別是我們的 minVal 和 maxVal。第三個參數是 aperture_size。它是用于查找圖像漸變的 Sobel 內核的大小。默認情況下,它是 3.最后一個參數是 L2gradient,它指定用于查找梯度幅度的等式。
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()
結果如圖所示:
apachecn.github.io/opencv-doc-zh/#/