4.6 Canny算法

Canny算法是John F.Canny于1986年开发出来的一个多级边缘检测算法。虽然Canny算法年代久远,但可以说它是边缘检测的一种经典算法,因此被广泛使用。

Canny的目标是找到一个最优的边缘检测算法,其含义如下:

①最优检测。该算法能够尽可能多地标识出图像中的实际边缘,漏检真实边缘的概率和误检非边缘的概率都要尽可能小。

②最优定位准则。检测到的边缘点的位置距离实际边缘点的位置最近,或者是由于噪声影响引起检测出的边缘偏离物体的真实边缘的程度最小。

③检测点与边缘点一一对应。算子检测的边缘点与实际边缘点应该是一一对应。

为了满足这些要求,Canny使用了变分法(calculus of variations),这是一种寻找优化特定功能函数的方法。最优检测使用四个指数函数项表示,非常近似于高斯函数的一阶导数。

Canny边缘检测算法可以分为以下5个步骤:

①应用高斯滤波来平滑图像,目的是去除噪声。

②找寻图像的强度梯度(intensity gradients)。

③应用非最大抑制(non-maximum suppression)技术来消除边误检(本来不是但检测出来是)。

④应用双阈值的方法来确定可能的边界。

⑤利用滞后技术来跟踪边界。

以下分别说明各个步骤。

(1)图像平滑(去噪声)

去噪声处理是目标提取的重要步骤,第5章专门介绍各种图像去噪声处理方法。Canny算法的第一步是对原始数据与高斯滤波器(详细内容见第5章)作卷积,得到的平滑图像与原始图像相比有些轻微的模糊(blurred)。这样,单独的一个像素噪声在经过高斯平滑的图像上变得几乎没有影响。以下为一个5×5高斯滤波器(高斯核的标准偏差σ=2),其中A为原始图像,B为平滑后图像。图4.11是原图像及高斯平滑结果图像。

图4.11 原图像及高斯平滑图像

(2)寻找图像中的强度梯度(梯度运算)

Canny算法的基本思想是找寻一幅图像中灰度强度变化最强的位置,即梯度方向。平滑后的图像中每个像素点的梯度可以由4.2节的Sobel算子等获得。以Sobel算子为例,首先分别计算水平(x)和垂直(y)方向的梯度fxfy;然后利用式(4.2)来求得每一个像素点的梯度强度值G。把平滑后图像中的每一个点用G代替,可以获得图4.12的梯度强度图像。从图4.12可以看出,在变化剧烈的地方(边界处),将获得较大的梯度强度值G,对应的像素值较大。然而,由于这些边界通常非常粗,难以标定边界的真正位置,因此还必须存储梯度方向[式(4.3)],进行非极大抑制处理。也就是说这一步需要存储两块数据,一是梯度的强度信息,另一个是梯度的方向信息。

图4.12 梯度强度图像

(3)非极大抑制(non-maximum suppression)

这一步的目的是将模糊(blurred)的边界变得清晰(sharp)。通俗地讲,就是保留了每个像素点上梯度强度的极大值,而删掉其他的值。

以梯度强度图像为对象,对每个像素点进行如下操作:

a.将其梯度方向近似为0、45、90、135、180、225、270、315中的一个,即上下左右和45°方向。

b.比较该像素点和其梯度方向(正负)的像素值的大小。

c.如果该像素点的像素值最大,则保留,否则抑制(即置为0)。

为了更好地解释这个概念,看下图4.13。

图中的数字代表了像素点的梯度强度,箭头方向代表了梯度方向。以第二排第三个像素点为例,由于梯度方向向上,则将这一点的强度(7)与其上下两个像素点的强度(5和4)比较,由于这一点强度最大,则保留。

对图4.12进行非极大抑制处理结果如图4.14所示。

图4.13 强度示意图

图4.14 对图4.12进行非极大抑制处理结果

(4)双阈值(double thresholding)处理

经过非极大抑制后的图像中仍然有很多噪声点。Canny算法中应用了一种叫双阈值的技术,即设定一个高阈值和低阈值,图像中的像素点如果大于高阈值则认为必然是边界(称为强边界,strong edge),将其像素值变为255;小于低阈值则认为必然不是边界,将其像素值变为0,两者之间的像素被认为是边界候选点(称为弱边界,weak edge),像素值不变。

高阈值和低阈值的设定,采用第3章介绍的p参数法,一般分别设定直方图下位(黑暗部分)80%和40%的位置会获得较好的处理效果。也可以调整阈值的设定值,看看是否处理效果会更好。

在实际执行时,这一步只是通过比例计算出高阈值和低阈值的具体数值,并不改变图4.14的像素值。

(5)滞后边界跟踪

对双阈值处理后的图像进行滞后边界跟踪处理,具体步骤如下:

①同时扫描非极大抑制图像I(图4.14)和梯度强度图像G(图4.12),当某像素pxy)在I图像不为0,而在G图像上大于高阈值、小于255时,将pxy)在I图像和G图像上都设为255(白色),将该像素点设为qxy),跟踪以qxy)为开始点的轮廓线。

②考察qxy)在I图像和G图像的8邻近区域,如果某个8邻域像素sxy)在I图像大于零,而在G图像上大于低阈值,则在G图像上设该像素为白色,并将该像素设为qxy)。

③循环进行步骤②,直到没有符合条件的像素为止。

④循环执行步骤①~③,直到扫描完整个图像为止。

⑤扫描G图像,将不为白色的像素置0。

至此,完成Canny算法的边缘检测。图4.15是滞后边界跟踪的结果。

图4.15 Canny微分处理结果

Canny算法包含许多可以调整的参数,它们将影响到算法的计算时间与实效。

高斯滤波器的大小:第一步所有的平滑滤波器将会直接影响Canny算法的结果。较小的滤波器产生的模糊效果也较少,这样就可以检测较小、变化明显的细线。较大的滤波器产生的模糊效果也较多,将较大的一块图像区域涂成一个特定点的颜色值。这样带来的结果就是对于检测较大、平滑的边缘更加有用,例如彩虹的边缘。

双阈值:使用两个阈值比使用一个阈值更加灵活,但是它还是有阈值存在的共性问题。设置的阈值过高,可能会漏掉重要信息;阈值过低,将会把枝节信息看得很重要。很难给出一个适用于所有图像的通用阈值。目前还没有一个经过验证的实现方法。