Canny边缘检测算法分为以下四步:
1 图像平滑
因为边缘检测对图像噪声很敏感,所以第一步我们使用
的高斯滤波器平滑图像。
2 求取图像梯度
对平滑后的图像使用Sobel算子来计算水平方向梯度
和竖直方向梯度
,然后我们可以计算图像中每个像素的梯度大小为
,梯度方向为
,梯度方向通常垂直于边缘方向。
3 非极大值抑制
在得到每个像素的梯度大小和方向后,我们遍历每个像素,判断该像素的梯度大小在该像素梯度方向上是否是其邻域中的局部最大值。如下图所示:
点A在边缘上,A的梯度方向垂直于边缘,B和C在A的梯度方向上,因此A和B、C比较来确定A的梯度是否为局部最大值。如果A的梯度为局部最大值,则A进入下一步,否则判断A不是边缘,A被抑制(置为0)。
4 滞后阈值法(双阈值)
这一步我们设置两个阈值
和
。遍历所有像素,梯度大小大于
的像素点被归为“确定边缘”像素,被保留;梯度大小小于
的像素点被认为一定不属于边缘,被丢弃。对于那些梯度大小介于
和
之间的像素点,如果它们连接到“确定边缘”像素,则它们被视为边缘的一部分。否则,它们也会被丢弃。如下图所示:
A在
之上,因此被认为是“确定边缘”。虽然C低于
,但它连接到边A,所以C也被认为是边缘,我们得到了完整的曲线。B虽然在最小值以上,且与C边在同一区域内,但它没有连接到任何“确定边缘”,因此被丢弃。因此,为了得到正确的结果,我们必须相应地选择合适的
和
。
通过以上四步我们就得到了图像的边缘。
OpenCV中Canny()方法的参数与上述描述一致。