Canny边缘检测是一种多级边缘检测算法。于1986年由John F. Canny在论文《A Computational Approach to Edge Detection》中提出。
Canny边缘检测是从不同视觉对象中提取有用的结构信息并大大减少要处理的数据量的一种技术,目前已广泛应用于各种计算机视觉系统。Canny发现,在不同视觉系统上对边缘检测的要求较为类似,因此,可以实现一种具有广泛应用意义的边缘检测技术。边缘检测的一般标准包括:
-
以低的错误率检测边缘,也即意味着需要尽可能准确的捕获图像中尽可能多的边缘。
-
检测到的边缘应精确定位在真实边缘的中心。
-
图像中给定的边缘应只被标记一次,并且在可能的情况下,图像的噪声不应产生假的边缘。
为了满足这些要求,Canny使用了变分法。Canny检测器中的最优函数使用四个指数项的和来描述,它可以由高斯函数的一阶导数来近似。
在目前常用的边缘检测方法中,Canny边缘检测算法是具有严格定义的,可以提供良好可靠检测的方法之一。由于它具有满足边缘检测的三个标准和实现过程简单的优势,成为边缘检测最流行的算法之一。
完成一个Canny边缘检测算法可以分为以下四步:
-
1.利用高斯滤波去噪。噪声会影响边缘检测的准确性,因此要先将噪声过滤掉。
-
2.计算梯度幅值和方向。
-
3.非极大值抑制。
-
4.应用双阈值确定真实的和可能的边缘。
1、 高斯滤波
边缘检测非常容易受到图像噪声的影响,因此为了避免检测到错误的边缘信息,可以先用高斯滤波器去除图像噪声。
大小为的高斯卷积核M的方程式为:
假设为src原图像,dst为高斯滤波后的图像,M为5×5的高斯卷积核(M不固定):(*表示卷积运算)
注意:选择高斯核的大小会影响检测器的性能。尺寸越大,检测器对噪声的灵敏度越低。此外,随着高斯滤波器核大小的增加,用于检测边缘的定位误差将略有增加。一般5×5的核是比较不错的。
2、 计算梯度强度和方向
梯度的方向与边缘的方向总是垂直的。图像中的边缘可以指向各个方向,通常会取水平(左、右)、垂直(上、下)、对角线(左上、右上、左下、右下)等八个不同的方向计算梯度。
接下来使用边缘检测的算子(如Roberts,Sobel,Scharr等)来计算图像中的水平、垂直和对角方向的梯度。得到水平和垂直方向的一阶导数值,由此便可以确定像素点的梯度的大小和方向 。如下图:
角度的确定:
得到的角度一般不在前边指定的放个方向上,我们需要将角度分类到八个方向中。假设有四条线,分别是0,45,90,135度线(0度和180重合,是一条线)。需要对通过(2)式求出的进行近似,分类到这四条线分成的八个区域中。
比如计算出的,则应将其归类到的区域,就是垂直向上方向。
八个区域如下图:
3、 非极大值抑制(NMS)
在每一点上,邻域中心与沿着其对应的梯度方向的两个像素相比,若中心像素()为最大值,则保留,否则中心置0,这样可以抑制非极大值,保留局部梯度最大的点,以得到细化的边缘。
-
如果该点是方向上的局部最大值,则保留该点
-
如果不是,则将其置为0
对图像进行梯度计算后,仅仅基于梯度值提取的边缘仍然很模糊。对边缘有且应当只有一个准确的响应。而非极大值抑制则可以帮助将局部最大值之外的所有梯度值抑制为0。非极大值抑制是一种边缘稀疏技术,非极大值抑制的作用在于“瘦”边。直观上地看,对第二步得到的图片,边缘由粗变细了。
经过上述处理后,对于同一个方向的若干边缘点,基本上只保留了一个,因此实现了边缘细化的目的。
如下图,A,B,C三点中,梯度方向上A点的局部梯度值最大,所以保留A点,其余两点被抑制。
4、 用双阈值算法检测和连接边缘
经过上述步骤后,图像内的强边缘已经在当前获取的边缘内,但是,一些虚边缘也在内。
我们设置两个阈值,高阈值maxVal和低阈值minVal,根据当前边缘点的梯度值与这两个阈值的关系,判断边缘的属性:
-
如果当前边缘点的梯度值大于或等于maxVal,,则将当前边缘标记为强边缘。
-
如果当前边缘点的梯度值介于maxVal与minVal之间,则将当前边缘标记为虚边缘。
-
如果当前边缘点的梯度值小于minVal,,则抑制当前边缘。
对得到的虚边缘,再做以下处理:
-
与强边缘相连,该边缘为边缘
-
与强边缘无连接,该边缘为弱边缘,将其抑制
可以肯定的是,强边缘必然是边缘点,因此必须将maxVal设置的足够高,以要求像素点的梯度值足够大(变化足够剧烈),而弱边缘可能是边缘,也可能是噪声,当虚边缘与强边缘相连时,就认为该虚边缘点是边缘点,以此来实现对强边缘的补充。
实际中maxVal:minVal=2:1的比例效果比较好,其中maxVal可以指定,也可以设计算法来自适应的指定,比如定义梯度直方图的前30%的分界线为maxVal。