Canny边缘检测
目标
在本篇文章中,我们将学习到以下内容:
- Canny边缘检测的概念
- OpenCV函数: cv.Canny()
理论
Canny Edge Detection是一种流行的边缘检测算法。它由John F. Canny提出,具有以下特点:
- 这是一个多阶段算法,我们将经历每个阶段。
- 具有降噪效果,由于边缘检测容易受到图像中噪声的影响,因此第一步是使用5x5高斯滤波器消除图像中的噪声。我们已经在前面的章节中看到了这一点。
- 使用Sobel核在水平和垂直方向上对平滑的图像进行滤波,以在水平方向(Gx)和垂直方向(Gy)上获得一阶导数。从上一篇OpenCV基于Python图像梯度处理文章可知,我们可以找到每个像素的边缘渐变和方向,关系式如下所示:
E d g e _ G r a d i e n t ( G ) = G x 2 + G y 2 A n g l e ( θ ) = tan − 1 ( G y G x ) Edge\_Gradient \; (G) = \sqrt{G_x^2 + G_y^2} \\ Angle \; (\theta) = \tan^{-1} \bigg(\frac{G_y}{G_x}\bigg) Edge_Gradient(G)=Gx2+Gy2Angle(θ)=tan−1(GxGy)
渐变方向始终垂直于边缘,其代表垂直,水平和两个对角线方向的四个角度之一,接下来引入非极大值抑制及磁滞阈值两个概念。
1. 非极大值抑制
在获得梯度大小和方向后,将对图像进行全面扫描,以去除可能不构成边缘的所有不需要的像素。为此,在每个像素处,检查像素是否是其在梯度方向上附近的局部最大值,观察下面的图片:

点A在边缘(垂直方向)上。渐变方向垂直于边缘。点B和C在梯度方向上。因此,将A点与B点和C点进行检查,看是否形成局部最大值。如果是这样,则考虑将其用于下一阶段,否则将其抑制(置为零)。 简而言之,你得到的结果是带有“细边”的二进制图像。
2. 磁滞阈值
该阶段确定哪些边缘全部是真正的边缘,哪些不是。为此,我们需要两个阈值 minVal和 maxVal。强度梯度大于 maxVal的任何边缘必定是边缘,而小于 minVal 的那些边缘必定是非边缘,因此将其丢弃。介于这两个阈值之间的对象根据其连通性被分类为边缘或非边缘。如果将它们连接到“边缘”像素,则将它们视为边缘的一部分。否则,它们也将被丢弃。如下图所示:

边缘A在 maxVal 之上,因此被视为“确定边缘”。尽管边C低于 maxVal ,但它连接到边A,因此也被视为有效边,我们得到了完整的曲线。但是边缘B尽管在minVal之上并且与边缘C处于同一区域,但是它没有连接到任何“确保边缘”,因此被丢弃。因此,非常重要的一点是我们必须相应地选择 minVal 和 maxVal以获得正确的结果。
在边缘为长线的假设下,该阶段还消除了小像素噪声。
因此,我们最终得到的是图像中的强边缘。
OpenCV中的Canny Edge检测
OpenCV将以上所有内容放在单个函数cv.Canny()中。第一个参数是我们的输入图像。第二个和第三个参数分别是我们的 minVal和 maxVal 。第三个参数是perture_size ,它是用于查找图像渐变的Sobel内核的大小,默认情况下为3。最后一个参数是L2gradient,它指定用于查找梯度幅度的方程式。如果为 True ,则使用上面提到的更精确的公式,否则使用以下函数:
E
d
g
e
_
G
r
a
d
i
e
n
t
(
G
)
=
∣
G
x
∣
+
∣
G
y
∣
Edge\_Gradient \; (G) = |G_x| + |G_y|
Edge_Gradient(G)=∣Gx∣+∣Gy∣默认情况下,它为False。
下面我们代码演示如何使用它:
import numpy as np
import cv2 as cv
from matplotlib import pyplot as plt
img = cv.imread('./data/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()
Canny算子边缘检测结果如下图所示:

附加参考资源
1.Canny edge detector at Wikipedia:http://en.wikipedia.org/wiki/Canny_edge_detector
2.Canny Edge Detection Tutorial:http://dasl.unlv.edu/daslDrexel/alumni/bGreen/www.pages.drexel.edu/_weg22/can_tut.html by Bill Green, 2002.
本文详细介绍了Canny边缘检测算法,包括非极大值抑制和磁滞阈值的概念,并展示了如何使用OpenCV的cv.Canny()函数进行边缘检测。通过实例解释了如何设置阈值和Sobel内核大小,以获得高质量的边缘检测结果。

438

被折叠的 条评论
为什么被折叠?



