目标
在本章中,我们将了解到:
- Canny边缘检测的概念
- 用于检测的OpenCV函数:cv.Canny()
理论
Canny边缘检测是一种流行的边缘检测算法。它是由John F. Canny在2006年开发的。
- 1.它是一个多阶段的算法,我们将对每个阶段进行分析。
- 2.减少噪音
由于边缘检测容易受到图像中噪音的影响,第一步是用5x5高斯滤波器去除图像中的噪音。我们已经在前几章中看到了这一点。
- 3.寻找图像的强度梯度
然后用Sobel核对水平和垂直方向的平滑图像进行过滤,得到水平方向(Gx)和垂直方向(Gy)的第一导数。从这两幅图像中,我们可以找到每个像素的边缘梯度和方向,如下所示:
E
d
g
e
_
G
r
a
d
i
e
n
t
(
G
)
=
G
x
2
+
G
y
2
Edge\_Gradient(G)\ =\ \sqrt{G_x^2+G_y^2}\
Edge_Gradient(G) = Gx2+Gy2
A
n
g
l
e
(
θ
)
=
tan
−
1
(
G
y
G
x
)
Angle\left( \theta \right) =\tan ^{-1}\left( \frac{G_y}{G_x} \right)
Angle(θ)=tan−1(GxGy)
梯度方向总是垂直于边缘。它被四舍五入为四个角度之一,代表垂直、水平和两个对角线方向。
- 4.非最大限度的压制
在得到梯度大小和方向后,对图像进行全面扫描,以去除任何可能不构成边缘的不必要的像素。为此,在每一个像素点上,检查该像素点是否是梯度方向上其附近的局部最大值。请看下面的图片:
Gradient Direction:梯度方向
edge:边缘
点A在边缘上(垂直方向)。梯度方向是对边缘的法线。B点和C点处于梯度方向。因此,A点与B点和C点一起被检查,看它是否形成一个局部最大值。如果是,它就会被考虑到下一阶段,否则,它就会被压制(归为零)。
简而言之,你得到的结果是一个具有 "薄边缘 "的二进制图像。
- 5.滞后阈值处理
这个阶段决定哪些是真正的边缘,哪些不是。为此,我们需要两个阈值,minVal和maxVal。任何强度梯度大于maxVal的边缘都肯定是边缘,而那些低于minVal的边缘肯定是非边缘,所以被丢弃。那些位于这两个阈值之间的边,根据它们的连接性被分为边和非边。如果它们与 "确定的边缘 "像素相连,它们就被认为是边缘的一部分。否则,它们也会被丢弃。请看下面的图片:
maxVal:即maximum Value,极(最)大值
minVal:即minimum Value,极(最)小值
边A在maxVal之上,所以被认为是 “确定的边”。虽然边C低于maxVal,但它与边A相连,所以它也被认为是有效的边,我们得到了完整的曲线。但是边B,尽管它高于minVal,并且与边C在同一区域,但它没有与任何 "确定的边 "相连,所以它被丢弃了。因此,我们必须相应地选择minVal和maxVal来获得正确的结果,这一点非常重要。
这个阶段还在假设边缘是长线的基础上去除小像素的噪音。
因此,我们最终得到的是图像中的强边缘。
OpenCV中的Canny边缘检测
OpenCV将上述所有内容都放在一个函数中,即cv.Canny()。我们将看到如何使用它。第一个参数是我们的输入图像。第二个和第三个参数分别是我们的minVal和maxVal。第四个参数是aperture_size。它是用于寻找图像梯度的Sobel核的大小。最后一个参数是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∣
默认情况下,它为 “假”。
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()
请看下面的结果:
其他资源
- 1.维基百科上的Canny边缘检测器
- 2.《Canny边缘检测教程》,作者Bill Green,2002年
(Canny Edge Detection Tutorial by Bill Green, 2002.)
练习
写一个小程序来寻找Canny边缘检测,其阈值可以用两个轨迹杆来改变。这样,你就可以了解阈值的影响。