深入解析 Canny 边缘检测:原理、步骤与实践应用全攻略

摘要:本文全面且深入地探讨了 Canny 边缘检测。详细阐述了其包括去噪(重点分析高斯核选取及不同大小核的影响)、计算梯度、非极大值抑制、双阈值确定边缘等核心步骤,并结合实际案例与代码(如使用 cv2.Canny 对 pig.JPG 图片处理)展示其在不同阈值设置下的效果差异及原因,助力读者深入理解并掌握 Canny 边缘检测技术在图像处理领域的应用要点与原理精髓。

如果你觉得本文对你有帮助,请点赞收藏关注,我会持续创作更多跟OpenCV相关的文章

深入解析 Canny 边缘检测:原理、步骤与实践应用全攻略

Canny边缘检测步骤

第一步:去噪

一般是使用高斯滤波,高斯滤波的特点是靠近中心的权值比较大,远离的权值较小。平滑一些纹理较弱的非轮廓区域,我用画图板给大家画一个例子,使用高斯滤波核对下面这张图的红色像素点进行计算:

高斯卷积核的如下:

两个矩阵乘法/56 = 138.

核越大对于噪声的敏感度就越低,通常来说5x5的核足以满足大多数情况

因为边缘的方向是由切向量来定义的,所以梯度的方向与边缘的方向垂直。

高斯核的选取

小核的局限性:小高斯核(如 3x3)在抑制噪声方面的能力相对较弱。虽然它能够较好地保留图像的细节和边缘的精确位置,但在实际应用中,很多图像都含有一定程度的噪声。如果噪声没有得到有效抑制,就会在边缘检测过程中产生大量的伪边缘。这些伪边缘会干扰真正边缘信息的提取,导致边缘检测结果不准确。

用 5x5 的高斯核可以在一定程度上有效地平滑图像,减少噪声的影响。例如,在一幅含有椒盐噪声(图像上随机出现的黑白像素点)的图像中,5x5 的高斯核能够将这些噪声点周围的像素值进行加权平均,使得噪声引起的像素值突变得到缓解。这样,在后续的边缘检测步骤(如计算梯度幅值和方向)中,就不容易因为噪声的干扰而错误地检测出边缘。

高斯核越大,边缘信息对于噪声的敏感度就越低,核越大定位错误也会增加。

虽然较大的高斯核(如 5x5)可能会导致边缘定位出现一些误差,但在很多实际应用场景中,这种误差是可以接受的。因为边缘检测的主要目的通常是获取物体的大致轮廓,而不是精确到像素级别的边缘位置。例如,在一个工业零件检测的场景中,只需要知道零件的大致边缘位置来判断其形状是否符合标准,少量的边缘定位误差不会对整体的检测结果产生重大影响。

相比于小核可能产生的大量伪边缘,大核导致的边缘定位错误相对来说是次要的。如果使用小核,大量的伪边缘会使得后续的边缘连接、轮廓提取等操作变得非常复杂,甚至无法准确地获取物体的完整轮廓。而使用 5x5 的核可以在减少伪边缘的同时,虽然会有一定的定位错误,但仍然能够提供相对清晰和准确的边缘轮廓。

第二步:计算梯度

G = (Gx^2 +Gy ^2)**(1/2)

方向 = arctan2(Gy,Gx)

梯度的方向与边缘垂直,就近取值为(左右上下、左上 左下 右上右下)八种,因此在计算梯度的时候,我们会得到角度和梯度两个值,请看下图:

第三步:非极大值抑制

获得梯度的幅度和方向以后,遍历所有像素点,去掉所有非边缘的点,判断当前仙姑私单是否式周围中具有相同梯度方向的最大值,如果不是最大值就抑制该点。通过非极大值抑制实现边缘细化的目的

第四步:双阈值确定边缘

第四步又分为两小步;

第一步:设置两个阈值 max min 如果梯度>= max那么标记为强边缘,如果在 max>梯度>min,那么标记为弱边缘,如果梯度<min,那么直接删去

第二步:遍历弱边缘,若与强边缘有连接,那么确定为边缘,没连接删去

语法与案例

语法

edges = cv2.Canny(待处理8位输入图像image ,阈值1 threshold1,阈值2 threshold2,图像梯度幅度L2gradient 默认为False计算速度快,他的图像梯度是二者绝对值之和,而设置为True就是G = (Gx^2 +Gy ^2)**(1/2),这样计算的更为准确)

我使用的是jupyter notebook,我项目的文件结构是这样的,我将对pig.JPG图片进行处理,如果你使用的是pycharm,将图片和代码放在同一个文件夹下就好了:

我把我的pig.JPG图片放在文章中,大家可以下载然后重命名:

案例是为了论证一个知识点,请先看代码和运行结果,我再讲这个知识点:

python 复制代码
import numpy as np
import cv2
pig = cv2.imread("pig.JPG")
img1 = cv2.Canny(pig,128,200)
img2 = cv2.Canny(pig,32,128)
cv2.imshow("original",pig)
cv2.imshow("128-200",img1)
cv2.imshow("32-128",img2)
cv2.waitKey()
cv2.destroyAllWindows()

在上面这个运行结果可以看出,阈值低的部分可以选择出更多边缘细节。

原因如下:当低阈值较小时,更多的像素梯度幅值能够大于低阈值,这就使得更多的像素有机会被标记为弱边缘像素或者强边缘像素。

例如,在一个包含一些微弱边缘的图像中,较低的低阈值可以让这些微弱边缘对应的像素梯度幅值超过低阈值,从而被考虑进入边缘检测的后续流程。

对于后续的边缘连接等操作,这些被标记为弱边缘的像素有机会与强边缘像素连接起来,最终形成完整的边缘。因为在边缘连接阶段,一些弱边缘像素如果与强边缘像素相邻或者在一定的连接规则下,它们会被判定为边缘的一部分,从而增加了边缘的完整性,捕获到更多的边缘信息。

致谢

本文参考了一些博主的文章,博取了他们的长处,也结合了我的一些经验,对他们表达诚挚的感谢,使我对 Canny边缘检测 有更深入的了解,也推荐大家去阅读一下他们的文章。纸上学来终觉浅,明知此事要躬行:
opencv基础44- Canny边缘检测详解-cv.Canny()
图像处理算法 | 高斯滤波

相关推荐
_Never_stop_20 小时前
ppt的png转eps,在overleaf编译
图像处理
paid槮1 天前
OpenCV图像形态学详解
人工智能·opencv·计算机视觉
AI算法董同学1 天前
轻松测试二维码生成与识别:使用Python的qrcode、opencv和pyzbar库
开发语言·python·opencv
星期天要睡觉1 天前
计算机视觉(opencv)——实时颜色检测
人工智能·python·opencv·计算机视觉
weixin_418007602 天前
用opencv来识别信用卡的号码 Vs 使用yolo+paddleocr
人工智能·opencv·yolo
爱凤的小光2 天前
OpenCV的数据类型二
人工智能·opencv
AndrewHZ2 天前
【图像处理基石】遥感图像高度信息提取:Python实战全流程+常用库汇总
图像处理·人工智能·python·计算机视觉·cv·遥感图像·高程信息
努力努力再nuli2 天前
学习华为昇腾AI教材图像处理原理与应用部分Day1
图像处理·人工智能·学习
学术小白人2 天前
【IEEE出版 | 早鸟优惠本周截止】人工智能驱动图像处理与计算机视觉技术国际学术研讨会 (AIPCVT 2025)
图像处理·人工智能·计算机视觉
jndingxin2 天前
瑞芯微算法环境搭建(2)------编译opencv
人工智能·opencv·计算机视觉