OpenCV Canny边缘检测

目标

在本章中,我们将了解

  • Canny边缘检测的概念
  • OpenCV函数用于:cv2.Canny()

理论

Canny边缘检测是一种流行的边缘检测算法。它是由约翰·F·坎尼于1986年开发的。这是一个多阶段的算法。

降噪

由于边缘检测对图像中的噪声很敏感,第一步是用5x5高斯滤波器去除图像中的噪声。 

图像强度梯度的求取

然后在水平方向和垂直方向用Sobel核对平滑后的图像进行滤波,得到水平方向的一阶导数(G_x)和垂直方向(G_y)从这两幅图像中,我们可以找到每个像素的边缘梯度和方向如下:

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

梯度方向总是垂直于边缘。它是圆形的四个角之一,代表垂直,水平和两个对角线方向。

非极大抑制

在获得梯度幅值和方向后,对图像进行全面扫描,以消除可能不构成边缘的任何不需要的像素。为此,在每个像素上,检查像素是否是其邻域内沿梯度方向的局部最大值。检查下面的图像:

Non-Maximum Suppression

A点在边缘(垂直方向)。梯度方向是正常的边缘。点B和C呈梯度方向。因此,用点B和点C检查点A,看看它是否形成局部最大值。如果是,则考虑到下一阶段,否则就会被抑制(将为零)。

简而言之,你得到的结果是一幅带有“薄边”的二值图像。

迟滞阈值

这个阶段决定了哪些是边缘,哪些是真正的边,哪些不是边。为此,我们需要两个阈值,MinVal和MaxVal。任何强度梯度大于MaxVal肯定是边,而小于MinVal肯定是非边缘的,所以被丢弃了。处于这两个阈值之间的人根据其连通性分为边缘或非边缘。如果它们连接到“确定边缘”像素,则它们被视为边缘的一部分。否则,它们也会被丢弃。见下图:

Hysteresis Thresholding

边缘A在MaxVal,因此被认为是“确定边缘”。虽然边缘C在MaxVal下面,但是它与边A相连,因此也被认为是有效边,我们得到了这条全曲线。但是边缘B,虽然它在上面MinVal并且与边缘C的区域相同,它没有连接到任何“确定边”,因此被丢弃。所以我们必须相应地选择MinVal和MaxVal,得到正确的结果。

这一阶段也消除了小像素噪声的假设,边缘是长线。所以我们最终得到的是图像中的强边。

OpenCV中的Canny边缘检测

OpenCV将上述所有功能都放在一个函数中,cv2.Canny()。我们会看看如何使用它。第一个参数是我们的输入图像。第二个和第三个参数分别是我们的MinVal和MaxVal。第三个参数是aperture_size。它是用于查找图像梯度的Sobel核的大小。默认情况下是3。最后一个参数是L2gradient ,它指定了求梯度幅值的公式。如果是True,它使用上面提到的更精确的方程,否则它使用这个函数:Edge\_Gradient \; (G) = |G_x| + |G_y|。默认情况下,它是False。

import cv2
import numpy as np
from matplotlib import pyplot as plt

img = cv2.imread('messi5.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()

见以下结果:

Canny Edge Detection

猜你喜欢

转载自blog.csdn.net/rongpeisheng666/article/details/81625102