opencv算法之Canny边缘检测
背景
对Canny边缘检测算法有更深入的学习和总结
Canny边缘检测的一般标准
Canny边缘检测器是由John F. Canny在1986年提出,Canny被称为最优检测器,其目标满足以下三个主要标准:
(1)低错误率:边缘检测器应该只对边缘有响应,而且应该找到所有的边缘像素,不应该错过任何边缘像素。
(对已有的边界能够有很好的检测,也即意味着需要尽可能准确的捕获图像中尽可能多的边缘。)
(2)局部性(Localization)(良好的定位):边缘检测器检测到的边缘像素距离实际边缘的距离应该越小越好。
(即检测到的边缘像素和实际边缘像素之间的距离必须最小化,即检测到的边缘应精确定位在真实边缘的中心。)
(3)最小响应:如果在一处只存在一个边缘像素,那么边缘检测器不应该识别出多个边缘像素。
(即每边只有一个响应,图像中给定的边缘应只被标记一次,并且在可能的情况下,图像的噪声不应产生假的边缘。)
理论
Canny假定阶梯型边缘会受到高斯白噪声的影响。
边缘检测器被假定为一个卷积过滤器f,f应该平滑噪声并定位边缘。
问题在于,要找到一种过滤器能够在满足三个标准的上达到最优。
理论阐释
在一个维度上,过滤器f对一个边缘G的响应由以下卷积积分给出:
G可以在x和y方向求导。
Canny的边缘检测最优化过滤器近似为G’,因此利用G’对输入图像进行卷积操作,即使在存在噪声的情况下,我们也可以得到一个增强边缘的图像E,这个图像被集成为边缘图像模型的一部分。
注意:
如果M中的像素为边缘像素,那么这些像素的值就会比较大;如果不是,则比较小。因此可以利用阈值操作将边缘像素展示为白色,并将背景展示为黑色。这样做并不能获得非常好的结果,而是必须部分根据每一个像素上梯度的方向来对图像进行阈值操作。
基本的思想是:
每一个边缘像素都关联了一个方向,在一个边缘像素上的梯度的大小应该比在边缘两侧的像素上的梯度大小要大。
以几何图像的方式阐释canny边缘检测过程
Canny算法主要步骤
Canny算法主要包含5个步骤,具体如下:
(1)过滤噪声
使用高斯滤波器算法,平滑图像,滤除噪声
高斯核如下:
(2)计算图像中每个像素点的梯度强度和方向
将图像转为灰度空间,计算图像梯度
利用Sobel算子计算x, y两个方向的梯度,返回水平Gx和垂直Gy的一阶导数值。以此来计算梯度强度G和梯度方向。
如下所示
其次,计算梯度的强度和方向:
其中,梯度的方向被四舍五入到[0, 45, 90, 135]这几个角度;
(3)非极大值抑制算子(NMS)
抑制那些梯度不够大的像素点,只保留最大的像素点,以消除边缘检测带来的杂散影响。
非极大值抑制是一种边缘稀疏技术,作用在于瘦边。在对图片进行梯度计算之后,仅仅基于梯度值提取的边缘仍然比较模糊。根据标准,对边缘有且应当只有一个准确的响应。而非极大值抑制可以帮助将将局部最大值之外的所有梯度值抑制为0
对梯度图像中每个像素进行非极大值抑制的算法步骤为:
(1) 将当前像素的梯度强度与沿正负梯度方向上的两个像素进行比较。
(2) 如果当前像素的梯度值与另外两个像素值相比最大,则该像素点保留为边缘点,否则该像素点被抑制。
通常为了更加精确的计算,在跨梯度方向的两个相邻像素之间使用线性插值来得到要比较的像素梯度。
如Fig1所示,将梯度分为8个方向,分别为E、NE、N、NW、W、SW、S、SE。其中0代表[0° ,45°], 1代表[45° ,90°],2代表[-90° ,-45°],3代表[-45° ,0°]。
像素点P的梯度方向为θ,则像素点P1和P2的梯度线性插值为:
因此非极大值抑制的伪代码如下:
需要注意的是,如何标志方向并不重要,重要的是梯度方向的计算要和梯度算子的选取保持一致。
(4)双阈值算法检测边缘
应用双阈值检测来确定真正的边缘和潜在的边缘。
在施加非极大值抑制之后,剩余的像素可以更准确地表示图像中的实际边缘。然而,仍然存在由于噪声和颜色变化引起的一些边缘像素。为了解决这些杂散响应,必须用弱梯度值过滤边缘像素,并保留具有高梯度值的边缘像素,可以通过选择高低阈值来实现。
如果边缘像素的梯度值高于高阈值,则将其标记为强边缘像素;
如果边缘像素的梯度值小于高阈值并且大于低阈值,则将其标记为弱边缘像素;
如果边缘像素的梯度值小于低阈值,则会被抑制。
阈值的选择取决于给定输入图像的内容。
1 | 经过NMS算法后,设置两个阈值T1,T2,通常T1是T2的1/2或者1/3; |
双阈值检测的伪代码如下:
(5)滞后阈值(即连接边缘)
通过抑制孤立的弱边缘最终完成边缘检测。
到目前为止,被划分为强边缘的像素点已经被确定为边缘,因为它们是从图像中的真实 边缘中提取出来的。
然而,对于弱边缘像素,将会有一些争论,因为这些像素可以从真实边缘提取也可以是因噪声或颜色变化引起的。为了获得准确的结果,应该抑制由后者引起的弱边缘。
通常,由真实边缘引起的弱边缘像素将连接到强边缘像素,而噪声响应未连接。为了跟踪边缘连接,通过查看弱边缘像素及其8个邻域像素,只要其中一个为强边缘像素,则该弱边缘点就可以保留为真实的边缘。
1 | 针对弱边缘,需要进一步判定其是否的真正的边缘像素点? |
这部分的伪代码如下:
函数原型
Canny边缘检测的函数原型如下
1 | void Canny( InputArray image, OutputArray edges, |
参数解释
1 | src:输入图像,必须是8-bits; |
算法源码
canny边缘检测算法源码
https://github.com/ThranduilELFKING/study-openCV/tree/main/canny
参考链接
https://blog.csdn.net/weixin_46196863/article/details/112209430
https://www.cnblogs.com/chenzhen0530/p/14690472.html
https://www.cnblogs.com/chenzhen0530/p/14660498.html
https://www.cnblogs.com/skyfsm/p/6879265.html
https://www.yanxishe.com/columnDetail/18324