整理于知乎:canny中的非极大抑制
和csdn:canny算子原理
(1)去噪
第一步是对原始数据与高斯 mask 作卷积,得到的图像与原始图像相比有些轻微的模糊(blurred)。
(2)用一阶偏导的有限差分来计算梯度的幅值和方向。
(3)对梯度幅值进行非极大值抑制。
仅仅得到全局的梯度并不足以确定边缘,因此为确定边缘,必须保留局部梯度最大的点,而抑制非极大值。(non-maxima suppression,NMS)
解决方法:利用梯度的方向。
(4)用双阈值算法检测并连接边缘。
解决方法:双阈值算法。双阈值算法对非极大值抑制后的图象作用两个阈值τ1和τ2,且2τ1≈τ2。从而可以得到两个阈值边缘图象N1[i,j]和N2[i,j](操作是:分别 <τ1,pixel=0,得到N1[i,j]; <τ2,pixel=0,得到N2[i,j])。由于N2[i,j]使用高阈值得到,因而含有很少的假边缘,但有间断(不闭合,因为阈值可能相对太大了...)。双阈值法要在N2[i,j]中把边缘连接成轮廓,当到达轮廓的端点时,该算法就在N1[i,j]的8邻点位置寻找可以连接到轮廓上的边缘,这样,算法不断地在N1[i,j]中收集边缘,直到将N2[i,j]连接起来为止(以N2为基础,利用N1辅助,完成N2中轮廓线的连接...对着N1,把N2里面需要补全的补上.)。
现在解释一下(3)的非最大拟制原理:
进行非最大抑制就是:寻找局部的像素最大值点,可以剔除很多非边缘点。
在理解的过程中需要注意以下两点:
1.中非最大抑制是回答这样一个问题:“当前的梯度值在梯度方向上是一个局部最大值吗?”所以,要把当前位置的梯度值与梯度方向上两侧的梯度值进行比较。
2.梯度方向垂直于边缘方向。但实际上,我们只能得到C点邻域的8个点的值,而dTmp1和dTmp2
并不在其中,要得到这两个值就需要对dTmp1和dTmp2两点进行线性插值,也即根据图1中的g1和g2对dTmp1进行插值,根据g3和g4对dTmp2进行插值(以得到dTmp1、dTmp2两个位置处的像素值),这要用到其梯度方向,这也是Canny算法中要求解梯度方向矩阵Thita的原因(算法的第二步)。
完成非极大值抑制后,会得到一个二值图像,非边缘的点灰度值均为0,可能为边缘的局部灰度极大值点可设置其灰度为128或者其他。