Canny 边缘检测算子 是一种多阶段边缘检测的算法,在 1986 年由 John F. Canny 发明。Canny 同时发展了边缘检测的计算理论,解释了为什么这个技巧会有用。
Canny 算法的发展
Canny 边缘检测是一种从不同的视觉物体中抽取有用结构信息的技巧。它被广泛应用于各种计算机视觉系统中。Canny 发现不同视觉系统中的边缘检测都相对相似。于是他阐述了一种可以在广泛情形下应用的解决方案。边缘检测的一般标准包括:
- 检测低误差率的边缘,意味着在图像中检测出尽可能多的边缘
- 算子检测出的边缘点应该落在边缘的中心
- 图像中给定的边缘应该只被记录一次,如果可能的话,噪音应该不可以增加额外的边。
为了满足这些要求 Canny 使用了变分微积分——一种通过优化泛函寻找函数的技巧。Canny 算子中出现的最优函数由四项指数项给出。但它可以用 Gauss 函数的一阶导数近似。
在目前发展的边缘检测方法中,Canny 边缘检测算法是最严格的算法之一,它的检测效果良好、可靠。由于它满足三个边缘检测的条件以及它容易实现的过程,它是最流行的边缘检测算法之一。
Canny 边缘检测算法的过程
Canny 边缘检测算法的过程可以分解为 5 步:
- 使用 Gauss 滤波光滑图像以去除噪音
- 找出图像的梯度强度
- 用非极大抑制去除边缘检测的伪响应
- 用双阈值确定可能的边缘
- 用迟滞现象跟踪边缘:抑制弱边缘以及不连接的边缘结束检测
Gauss 滤波
由于所有边缘检测结果都很有可能受到噪音影响,去除噪音防止错误检测是基本的任务。为了光滑图像,可以用 Gauss 滤波与图像卷积。这个过程可以轻微地光滑图像,去除明显的噪音。内核大小为
(
2
k
+
1
)
×
(
2
k
+
1
)
(2k+1)\times(2k+1)
(2k+1)×(2k+1) 的 Gauss 内核的方程为
H
i
j
=
1
2
π
σ
2
exp
(
−
(
i
−
(
k
+
1
)
)
2
+
(
j
−
(
k
+
1
)
)
2
2
σ
2
)
,
1
≤
i
,
j
≤
2
k
+
1.
H_{ij} = \frac1{2\pi\sigma^2} \exp\left(-\frac{(i-(k+1))^2+(j-(k+1))^2}{2\sigma^2}\right), \qquad 1 \le i,j \le 2k+1.
Hij=2πσ21exp(−2σ2(i−(k+1))2+(j−(k+1))2),1≤i,j≤2k+1.
这里给出一个
5
×
5
5\times 5
5×5 Gauss 滤波的例子,用于建立相邻图像,
σ
=
1.4
\sigma=1.4
σ=1.4 。(星号表示卷积操作)
B
=
1
159
[
2
4
5
4
2
4
9
12
9
4
5
12
15
12
5
4
9
12
9
4
2
4
5
4
2
]
∗
A
\mathbf B = \frac1{159} \begin{bmatrix} 2 & 4 & 5 & 4 & 2\\4 & 9 & 12 & 9 & 4\\ 5 & 12 & 15 & 12 & 5\\ 4 & 9 & 12 & 9 & 4\\ 2 & 4 & 5 & 4 & 2\end{bmatrix} * \mathbf A
B=1591⎣⎢⎢⎢⎢⎡245424912945121512549129424542⎦⎥⎥⎥⎥⎤∗A
我们需要知道 Gauss 核的大小会影响检测的性能。尺寸越大,对噪音的敏感性越弱。此外,检测边缘的局部误差会随着 Gauss 核尺寸的增加而增加。
5
×
5
5\times5
5×5 对大多数情形是一个好的选择,但也可以根据特殊的情况变化。
找出图像的梯度强度
图片的边缘可能指向这种方向,所以 Canny 算法在模糊的图像上用四个滤波器检测水平、竖直、对角边缘。边缘检测算子(如Roberts、Prewitt、Sobel)返回水平方向 ( G x \mathbf G_x Gx) 和垂直方向 ( G y \mathbf G_y Gy) 的一阶导数。从而,边缘梯度和方向可以由下面两个式子确定 G = G x 2 + G y 2 Θ = atan2 ( G y , G x ) \begin{aligned} \mathbf G &= \sqrt{\mathbf G_x^2 + \mathbf G_y^2}\\ \textbf{$\Theta$} &=\text{atan2}(\mathbf G_y, \mathbf G_x) \end{aligned} GΘ=Gx2+Gy2=atan2(Gy,Gx)这里 G \mathbf G G 用 hypot (斜边) 函数计算,而 atan2 \text{atan2} atan2 是两个参数的正切函数。边缘角度被约化到四个角度之一,即垂直、水平和两条对角线 ( 0 ∘ , 4 5 ∘ , 9 0 ∘ , 13 5 ∘ 0^\circ,45^\circ,90^\circ,135^\circ 0∘,45∘,90∘,135∘)。边缘检测得到的角度落在每一个角度区域的话,都会被设为某一个特定角度,例如 θ \theta θ 在 [ 0 ∘ , 22. 5 ∘ ] [0^\circ,22.5^\circ] [0∘,22.5∘] 或 [ 157. 5 ∘ , 18 0 ∘ ] [157.5^\circ, 180^\circ] [157.5∘,180∘] 会被设为 0 ∘ 0^\circ 0∘。
非极大抑制
非极大抑制是一种边缘压缩技巧。
非极大抑制用于找出“最大”的边缘。在梯度计算之后,提出的边缘仍然很模糊。考虑到准则 3,对边缘应该只有一个响应。因此,非极大抑制可以抑制除了局部极大的所有的梯度值(将其设为 0),意味着最尖锐的强度变化点。对梯度图像中的每一个像素的算法如下:
- 比较当前像素的边强度和正负梯度方向的边强度。
- 如果当前点的边强度比同方向(mask中)所有其他点的边强度都大,则保留;否则抑制。(一个像素如果指向 y y y-方向,则比较与其垂直的上下点)
在一些实现中,算法把连续梯度方向分为一些小的离散方向,然后在上一步的输出上(即边强度和梯度方向)移动 3 × 3 3\times3 3×3 滤波器。在每一个像素上,如果其绝对值比梯度方向的两个邻居的绝对值小,则抑制之。例如:
- 如果取整之后的梯度方向为 0 ∘ 0^\circ 0∘(即边缘是南北方向的),则当这个点的梯度绝对值比东西两个方向的绝对值都要大时,这个点被认为是边缘。
- 如果取整之后的梯度方向是 9 0 ∘ 90^\circ 90∘ (即边缘是东西方向的),则当这个点的梯度绝对值比南北两个方向的绝对值都要大时,这个点被认为是边缘。
- 如果取整之后的梯度方向是 13 5 ∘ 135^\circ 135∘ (即边缘是东北-西南方向的),则当这个点的梯度绝对值比东南-西北两个方向的绝对值都要大时,这个点被认为是边缘。
- 如果取整之后的梯度方向是 4 5 ∘ 45^\circ 45∘ (即边缘是东南-西北方向的),则当这个点的梯度绝对值比东北-西南两个方向的绝对值都要大时,这个点被认为是边缘。
在更精确的实现中,横跨梯度方向的两个相邻像素用线性插值实现。例如,如果梯度方向是在 8 9 ∘ 89^\circ 89∘ 和 18 0 ∘ 180^\circ 180∘ 之间,则 北 和 东北 像素给出一个插值,南 和 东南 给出另一个插值(沿用上一段的习惯)。中间像素的梯度大小必须比这两个点的强度都大才能成为一条边。
注意,方向的符号是无关的,即南北和北南是一样的。
双阈值
在使用非极大抑制时,余下的边缘像素已经给出一个精确地实物边缘的表示。然而,有些边缘像素仍然由噪音和颜色变种导致。为了考虑这种假响应,本质上我们要过滤掉弱梯度值,留下强梯度值。这通过选高低阈值完成。这通过选择高、低阈值实现。如果像素梯度值高于高阈值,则这个点被标记为强边缘,如果一条边的梯度值小于高阈值但高于低阈值,则标记为弱边缘。如果低于低阈值,则被抑制。这两个值由给定的图片按经验取。
用滞后现象跟踪边缘
到这个阶段,强边缘一定是物体边缘,因为他们是物体的真实边缘。然而,关于弱边缘是否是真正的边缘还有一些争议,因为他们有可能是真边缘,有可能是噪音的边缘。为了达到一个精确的效果,后者的因素应该要去除。通常,真实边缘产生的弱边缘与强边缘有着连接,而噪音的边缘是不连通的。为了跟踪边的联通情况,对弱边像素与其 8-联通邻域进行块分析。只要有一个强边像素,弱边像素就被认为是要保留的。
Canny 边缘检测的改进
尽管传统的 Canny 边缘检测可以给出相对简单但精确的方法,但对要求精度更高的问题,传统算法无法应对这样的挑战。主要的缺陷总结如下1:
- Gauss 滤波器可以光滑掉噪声,也可以光滑掉作为高频特征的边缘。这会导致增加丢失弱边缘和出现孤立边缘的概率。
- 对梯度幅度计算,旧的 Canny 边缘检测算法用 2 × 2 2\times2 2×2 小邻域窗的中心计算有限差分均值来表示梯度振幅。这个方法对噪音敏感可能会出现假边缘,而丢失真边缘。
- 在传统的 Canny 边缘检测算法中,有两个固定的全局阈值用来过滤伪边缘。然而,当图片变得越来越复杂时,不同局部区域需要不同的阈值,以找到精确的边缘。此外,全局阈值通过实验手动确定,这对大量图片的检测任务来说会带来巨大的计算量。
- 传统的检测不能给出令人满意每一个边缘只有一个响应的高精度——会产生多点响应。
取代 Gauss 滤波
由于边缘和噪音都属于高频信号,简单的 Gauss 滤波会在两者上都加上平滑效应。然而,为了达到真实边缘检测的高精度,我们期望在噪音上加入更多平滑效应,而在边缘上的平滑效应更少。长沙科技大学的 Bing Wang 和 Shaosheng Fan 发明了自适应滤波算子,滤波器会评价每一个像素灰度值直接的不连续性1。不连续性越强,在该点的滤波算子的权重越小。相对的,如果灰度值的不连续性越小,滤波器中的权重越大。这个自适应滤波器的实现过程可以总结为以下 5 步:
- K = 1 K=1 K=1, 设置循环数为 n n n,边缘振幅系数为 h h h
- 计算梯度值 G x ( x , y ) G_x(x,y) Gx(x,y) 和 G y ( x , y ) G_y(x,y) Gy(x,y)
- 用下面的公式计算权重
d ( x , y ) = G x ( x , y ) 2 + G y ( x , y ) 2 w ( x , y ) = exp ( − d ( x , y ) 2 h 2 ) \begin{aligned} d(x,y) &= \sqrt{G_x(x,y)^2+G_y(x,y)^2}\\ w(x,y) &=\exp\left(-\frac{\sqrt{d(x,y)}}{2h^2}\right) \end{aligned} d(x,y)w(x,y)=Gx(x,y)2+Gy(x,y)2=exp(−2h2d(x,y)) - 自适应滤波算子定义为
f ( x , y ) = 1 N ∑ i = − 1 1 ∑ j = − 1 1 f ( x + i , y + j ) w ( x + i , y + j ) f(x,y) = \frac1N\sum_{i=-1}^1\sum_{j=-1}^1 f(x+i, y+j) w(x+i,y+j) f(x,y)=N1i=−1∑1j=−1∑1f(x+i,y+j)w(x+i,y+j)
用于光滑图像。这里
N = ∑ i = − 1 1 ∑ j = − 1 1 w ( x + i , y + j ) . N = \sum_{i=-1}^1\sum_{j=-1}^1 w(x+i, y+j). N=i=−1∑1j=−1∑1w(x+i,y+j). - 当 K = n K=n K=n,停止迭代,否则 k = k + 1 k=k+1 k=k+1,返回第 2 步。
改进梯度强度和方向计算
梯度大小和方向可以用各种不同的边缘检测算子计算,算子的选择会影响计算结果的质量。最常用的是 3 × 3 3\times 3 3×3 的 Sobel 滤波器。然而,另外一些滤波器如 5 × 5 5\times 5 5×5 的滤波器可能可以更好地降低噪音或者 Scharr 滤波器有着更好的旋转对称性。其他常用的选择是 Prewitt (Zhou2 所使用的) 和 Roberts Cross。
确定双阈值的有效方法
为了解决双阈值难以经验选取的问题,Otsu 方法可以用于图片梯度的非极大抑制的结果,产生高阈值。低阈值通常设为高阈值的 1 / 2 1/2 1/2。由于图片梯度是连续函数,没有适定的极大值,Otsu 方法需要被改为值/计数对,而不是完整的柱状图。
细化边缘
传统的 Canny 边缘检测对前两条准则的要求满足得比较好,它没有严格满足每一条边缘的单响应的要求。一种数学形态学用于细化检测到的边缘由 Mallat 和 Zhong3 提出。
使用曲波
曲波在 Gauss 滤波和梯度估计之间,用于计算一个向量场,其方向和大小用来图片估计边缘的方向和强度,然后再应用 Canny 算法的第 3 到 5 步。曲波将信号在不同尺度上分解为可分成分,然后丢弃掉精细尺度成分以降低噪音4。
Canny 边缘检测的微分几何形式
另一个获得次像素精度边缘的方法是使用微分边缘检测,这需要非极大抑制计算在尺度空间的二阶、三阶导数 (Lindeberg 1998) ——参考边缘计算的文章。
Haralick-Canny 边缘检测的变分形式
变分形式解释 Canny 边缘检测的主要成分,即找到沿梯度方向二阶导数的零点,是极小化 Kronrod-Minkowski 泛函而极大化梯度场在边缘对齐上的积分的结果 (Kimmel-Bruckstein 2003)。参见正则化 Laplace 算子零点和其他最优边界积分子的详细描述。
参数
Canny 算法含有一系列可以调节的参数,影响着算法的计算时间和有效性。
- Gauss 滤波器的大小:Canny 算法阶段的光滑滤波器直接影响了算法结果。小滤波器不至于使得图像太模糊,允许检测出小而尖锐的物体。大滤波器造成更大的模糊,涂抹掉大片区域的一些值。更大的模糊半径适用于检测更大的物体和光滑的边缘——例如彩虹的边缘。
- 阈值:用双阈值结合滞后使得检测比单阈值方法更灵活,但阈值方法的一般问题仍然存在。高阈值可能使重要信息丢失。另外,阈值太低可能会导致检测出无关信息(如噪音)。在所有图片上都给出通用的阈值是困难的。目前没有尝试和试验解决这一问题。
结论
Canny 算法适用于各种环境。它的参数允许算法根据需求检测不同的特征。在 Canny 原始的文章中,最优滤波器的推导最后为有限脉冲响应滤波器,如果光滑需要的量是重要的,在空间域中的计算是很慢的(滤波器在空间域的支集会很大)。因此,通常建议使用 Rachid Deriche 的无限脉冲响应的 Canny 滤波器(Canny-Deriche 检测器),它是递归形式的,可以在较短的固定时间内计算各种需要的光滑。第二种形式适用于在 FPGA,DSP,或更快的嵌入式 PC 上的实时实现。在这种情况下,通常的递归 Canny 算子不能给出一个旋转对称性,这会对在水平和垂直边上造成一些偏差。
参考文献
Li, Q., Wang, B., Fan, S. (2009). An Improved CANNY Edge Detection Algorithm. In 2009 Second International Workshop on Computer Science and Engineering proceedings: WCSE 2009: 28-30 October 2009, Qingdao, China (pp.497-500). Los Alamitos, CA:IEEE Computer Society. ↩︎ ↩︎
Zhou, P., Ye, W., & Wang, Q. (2011). An Improved Canny Algorithm for Edge Detection. Journal of Computational Information Systems, 7(5), 1516-1523. ↩︎
Mallat S., Zhong S., Characterization of Signals from Multi scale Edges. IEEE Trans on PAMI, 1992, 14 (7):710-732. ↩︎
Gebäck, T., Koumoutsakos, P., Edge detection in microscopy images using curvelets, BMC Bioinformatics, 10: 75, 2009. ↩︎