3.7. 精明的边缘检测

3.7.1. 目标

在本章中,我们将学习

  • Canny边缘检测的概念

  • OpenCV函数: 卡尼()

3.7.2. 理论

Canny边缘检测是一种流行的边缘检测算法。它是由约翰坎尼在1986年开发的。这是一个多阶段的算法,我们将经历每个阶段。

  1. 降噪

由于边缘检测容易受到图像中噪声的影响,第一步是使用5x5高斯滤波器去除图像中的噪声。我们已经在前面的章节中看到了这一点。

  1. 求图像的强度梯度

然后用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)\]

渐变方向始终垂直于边。四个角中的一个表示垂直、水平和两个对角线方向。

  1. Non-maximum Suppression

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

点A在边缘(垂直方向)。梯度方向垂直于边缘。B点和C点在梯度方向上。所以A点和B点和C点一起检查,看看它是否形成了一个局部最大值。如果是,则考虑下一阶段,否则,将抑制(置零)。

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

  1. 滞后阈值

这个阶段决定哪些是边,哪些不是边。为此,我们需要两个阈值, \(minVal\)\(maxVal\) . 强度梯度大于 \(maxVal\) 一定是边缘和下面的 \(minVal\) 一定要无边,所以丢弃。介于这两个阈值之间的是基于连通性的边缘或非边缘分类。如果它们连接到“确定边缘”像素,则它们被视为边缘的一部分。否则,它们也会被丢弃。见下图:

边缘A在 \(maxVal\) ,因此被认为是“可靠的边缘”。尽管边缘C在下面 \(maxVal\) ,它连接到边A,所以这也被认为是有效边,我们得到了完整的曲线。但是边缘B,虽然它在上面 \(minVal\) 与边缘C的区域相同,它没有连接到任何“确定边缘”,因此被丢弃。所以我们必须选择 \(minVal\)\(maxVal\) 从而得到正确的结果。

在假设边缘是长线的情况下,该阶段还去除小像素噪声。

所以我们最终得到的是图像中的强边。

3.7.3. OpenCV中的Canny边缘检测

OpenCV将以上所有内容放在一个函数中, 卡尼() . 我们将看看如何使用它。第一个参数是我们的输入图像。第二和第三个论点是 \(minVal\)\(maxVal\) 分别是。第三个论点是 \(aperture_size\) . 它是用于查找图像梯度的Sobel核的大小。默认为3。最后一个参数是 \(L2gradient\) 它指定用于查找渐变大小的公式。如果是的话 True ,则使用上述方程式,更准确,否则使用此函数: \(Edge\_Gradient \; (G) = |G_x| + |G_y|\) . 默认情况下,它是 False .

>>> %matplotlib inline
>>>
>>> import cv2
>>> import numpy as np
>>> from matplotlib import pyplot as plt
>>>
>>> img = cv2.imread('/cvdata/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()
>>> cv2.__version__

结果如下:

3.7.4. 额外资源

  1. 机敏边缘探测器 Wikipedia

  2. Canny Edge Detection Tutorial 比尔·格林,2002年。

3.7.5. 练习

  1. 编写一个小应用程序来查找Canny边缘检测,它的阈值可以使用两个轨迹栏来改变。这样,您就可以了解阈值的效果。