边缘检测及Canny算法

news/2025/3/28 6:50:43/文章来源:https://www.cnblogs.com/wangle1006/p/18784842

对边缘的直观理解

边缘有助于我们对图像进行语义理解。直观上,边缘发生在图像强度值变化剧烈的地方
如何描述变化?自然是用导数/梯度

如上图,我们对图中的信号在水平方向上求导,可以得到右侧的导数图像,可以看到,它在边缘处由于信号发生剧烈变化,导数产生了极值。因此,导数的极值点能帮助我们定位边缘所在。

用卷积描述导数

对于一个二元的连续函数f(x,y)其偏导数可由如下极限得到:

\[\frac{\partial f(x, y)}{\partial x} = \lim_{\varepsilon \to 0} \frac{f(x + \varepsilon, y) - f(x, y)}{\varepsilon} \]

而对于离散的图像数据,我们通常使用如下表达式近似偏导数,也就是有限差分的方式:

\[\frac{\partial f(x, y)}{\partial x} \approx \frac{f(x + 1, y) - f(x, y)}{1} \]

而这种计算方式,可以用卷积核的形式进行处理:
x方向上的导数可理解为右边的像素减去我自己,转化成卷积核长这样:

y方向上的导数可理解为上面的像素减去我自己,转化成卷积核长这样:

用这种卷积核对图像做卷积,得到每个像素点在x和y方向上的导数:

其他几种表示导数的卷积核

除了上面这种”极简“导数卷积核外,我们常用的还有以下几种卷积核:

Prewitt
该算子考虑了上下两层的信息,增强了对弱边缘的捕获能力,更具有鲁棒性。

Sobel
该算子在其中心列/行上权重为2,也就是说更关注自身所在列/行,能够抵御一定的噪声干扰。
这个卷积核可以分解为

\[\begin{bmatrix} 1 \\ 2 \\ 1 \end{bmatrix} \cdot \begin{bmatrix} -1 & 0 & 1 \end{bmatrix} \]

可以把卷积分解成两次小的卷积操作,降低计算复杂度。

Roberts
可以检测45°/135°边缘。

从工程实践来说,Sobel算子具有良好的抗噪性和运算效率,其综合性能最优,是最常用的求导卷积核。OpenCV等库的默认实现。为了解决其在方向上的局限性(x,y两个方向),也常组合使用多方向核(如8方向Sobel扩展)。

图像2D上的导数---梯度

1D上叫导数,2D上叫梯度。把函数对x和y的偏导数放到一个向量中,该向量就表示了梯度信息。

\[\nabla f = \left[ \frac{\partial f}{\partial x}, \frac{\partial f}{\partial y} \right] \]

这个梯度向量的方向,就表达了当前像素点主要是在这个方向上变化

\[\theta = \tan^{-1} \left( \frac{\partial f}{\partial y} / \frac{\partial f}{\partial x} \right) \]

向量的长度,就是在这个方向上变化的快慢

\[||\nabla f|| = \sqrt{\left( \frac{\partial f}{\partial x} \right)^2 + \left( \frac{\partial f}{\partial y} \right)^2} \]

该点的梯度长度,决定了该点是不是边缘,边缘点的梯度变化大,非边缘的梯度小。
梯度的方向,垂直于边。

把梯度的模算出来,画在图像上,就得到了梯度强度图,取一个阈值,就能取到边缘上的点。
(也可以理解为取极值点,但极值点可能比较离散,连不成一条线)

真实场景的应用---高斯偏导核

对于实际图像来说,由于噪声存在,如果直接使用上面的导数卷积核,就会造成如下情况:

导数的极值到处都是。如何处理噪声?我们可以做高斯平滑。

如下图所示,我们先做平滑,再进行求导

这两步又可以合成一步(卷积的交换律,结合律),也就是

\[\frac{d}{dx}(f*g) = f * \frac{d}{dx}g \]

高斯平滑加导数,等效于直接对高斯核做导数,然后与之卷积
也就是高斯偏导核

二维的高斯偏导核图像如图:

注意:这里的x方向的高斯偏导核是不可以再分解成两个高斯核的,可以从高斯函数公式的导数公式看出。
原高斯核可以分成两个方向的高斯核相乘。也就可以先对x方向求卷积,再对y方向求卷积。

高斯偏导核的σ影响:下图σ为1,3,7

可以看到σ越小,检测到的边缘越精细,越大,检测到的边缘的尺度越大。

高斯核 vs 高斯偏导核

高斯核:

  • 高频率波,低通滤波
  • 权值为正
  • 加权和为正

高斯偏导核

  • 高斯核的导数
  • 可为负
  • 加权和为0
  • 高对比度(边缘)处有高绝对值的加权值

Canny算法

通过上文中的方法,我们首先计算高斯偏导核的卷积结果,得到梯度模的图像

设置阈值对边缘点进行筛选:

这里存在一个问题:由于做了高斯模糊,阈值以上部分边缘看起来很粗

如上图,我们设置阈值之后,阈值以上的部分是一段相对较粗的区域,边缘的具体位置不精确。而实际上我们更期望得到的边缘是更精准的一条线。这里我们需要引入非最大化抑制的方法。

非最大化抑制 non-maximun suppression

我们在每个像素的梯度方向上判断前后两个点和自身模的大小,如果自己是最大的则保留,否则不保留。
如上图所示,q点的梯度方向上,前后两个点分别是r和p,梯度大小可以通过像素点上的梯度插值得到。判断p、q、r的梯度大小,如果q是最大的,则q点保留下来;如果q不是最大的,则q点舍弃。
由于梯度方向和边缘是垂直关系,这样从整体来看,我们最终留下了那个边缘垂线方向上的极值点

然而这里又产生了新问题:求得结果不连通

如图中人脸下巴位置处,理应有一条边缘连接起来,而由于光照等因素影响,使得该处梯度变化不明显,检测出的边缘无法连通;而如果我们降低阈值,有可能引入更多的噪声因素。
此时,我们可以引入双阈值检测方法。

双阈值检测 Hysteresis Thresholding

该方法的核心思路在于设置高低两种阈值,筛选出可信的边缘,再利用边缘的连通性补全弱边缘信息。

  1. 用高阈值检测出图中粗的部分,这部分梯度变化剧烈且稳定,受噪声干扰小,比较鲁棒。
  2. 用低阈值检测弱边缘,这部分可能包含较多的候选点,也包含更多的噪声。
  3. 这里引入一个先验条件,有效的弱边缘一定与高阈值检测出的强边缘连通。因此,我们可以检查弱边缘像素候选点的8邻域像素:
    • 若邻域内存在强边缘像素,则该弱边缘点标记为有效
    • 若邻域内不存在强边缘像素,则该弱边缘点视为噪声,舍弃掉。
      下图为通过双阈值检测得到的结果:

总结Canny算法步骤

  1. 使用高斯导数过滤图像
    首先,对图像进行高斯滤波,以减少噪声并平滑图像,为后续的边缘检测做好准备。

  2. 找到梯度的大小和方向
    计算图像的梯度,确定每个像素点的梯度幅度和方向。梯度幅度表示边缘的强度,梯度方向表示边缘的方向。

  3. 非最大抑制(Non-maximum suppression)​
    将宽的“脊”缩小到单个像素宽度。通过比较每个像素点的梯度幅度与其相邻像素点,保留局部最大值,从而细化边缘。

  4. 双阈值检测​
    定义高低两个阈值:

    • 使用高阈值初步检测边缘曲线,确保鲁棒性强的边缘被保留。
    • 使用低阈值来链接边缘曲线,把和强边缘相接的弱边缘连接起来。

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处:http://www.hqwc.cn/news/902392.html

如若内容造成侵权/违法违规/事实不符,请联系编程知识网进行投诉反馈email:809451989@qq.com,一经查实,立即删除!

相关文章

​工贸一体企业全链路管理应用实例:业务流程优化+任务智能分配+项目进度追踪

河源集品科技主营小型家电出口,自主研发实力强。发展中项目管理遇难题,试用多款工具无果。经对比,选用日事清。其功能全面,匹配公司流程、绩效等管理需求,能一键发起流程、自动流转待办,性价比高。针对订单、生产流程、多部门协作挑战,日事清给出对应方案,试用效果出色…

如何使用FPGA开发

介绍 与传统的微控制器相比,FPGA(现场可编程门阵列)是独一无二的,因为它们不执行顺序指令。相反,它们由一组可配置的逻辑块组成,这些逻辑块可以被重新编程以执行自定义的数字逻辑功能。这使得FPGA可以并行执行多个操作,使其在信号处理、数据处理和实时控制等特定任务中非常…

3月10号-3月16号笔记三合一+两篇面经

2025.3.10 学习 八股 blocked和waiting有啥区别 触发条件:线程进入BLOCKED状态通常是因为试图获取一个对象的锁(monitor lock),但该锁已经被另一个线程持有。这通常发生在尝试进入synchronized块或方法时,如果锁已被占用,则线程将被阻塞直到锁可用。线程进入WAITING状态是…

Dicom纯js的三维重建影像浏览器

主要功能介绍 实现通过浏览器浏览Dicom影像阅片。主要功能:支持标准DIcom影像的2D浏览,预设窗位,伪彩,序列间,序列内多种布局方式。 影像处理,提供影像翻图、缩放、移动、透镜、反相、旋转、截图等操作 影像测量,提供箭头、直线、十字架、角度、Cobb、心胸比、椭圆、矩形…

电子签借贷真实吗?315报道引发的行业地震!电子签到底冤不冤?

看了315的相关报道后,曝光套路贷本来是正向的,却将电子签和高利贷混为一谈。这种无意识的混淆不仅会误导大众,也不利于新兴技术的健康发展。电子签作为一种替代纸质合同签署的新兴技术,有着独特的优势和重要的意义。在过去,不同主体之间签订合同往往需要面对面进行签署,这…

C#反编译

偶遇C#逆向题,IDA拼尽全力无法战胜,只给我一团乱码。 这时可以使用dnSpy来反编译: https://github.com/dnSpy/dnSpy/releases/tag/v6.1.8 1.dnSpy使用方法: 将你要反编译的程序的整个文件夹拖到那里,似乎只有.dll那里才能看到源码, 例题:https://www.nssctf.cn/problem/3…

Windows11跳过Microsoft账户登录方法

新版Win11默认必须联网并且使用Microsoft账户登录,不然不能进去系统,以下是不联网进入方法1、在开机出现登录界面时,按下Ctrl+Shift+F3快捷键,然后系统会自动重启,重启 后会出现一个不需要登录Microsoft账户的启动界面,直接进入Windows11系统,系统中会弹窗,点确定。 2、…

android studio 真机wifi调试经验汇总

--------------- 2025/03/11 真机连接连不上wifi调试可能的原因: 1.手机没有开启开发者模式 2.手机没有开启usb调试以及wifi调试 3.手机应该改为传输文件模式 4.手机和电脑应该连接同一个wifi 5.在电脑cmd窗口输入adb connect ip:port(前提电脑需要配好adb环境)adb连接手机教…

广度优先搜索(BFS)走迷宫:

广度优先搜索(BFS)走迷宫: 广度优先搜索(BFS)是一种经典的图遍历算法,在解决路径查找、迷宫问题、拓扑排序等问题 前置知识:队列: 队列与栈类似,但是先进先出,而不是栈的先进后出。 原理: 相当于爆破,将所有的位置都走一遍 通用迷宫代码实现: #include <iostre…

TEA与XTEA算法:

TEA算法使用64位的明文分组和128位的密钥,它使用Feistel分组加密框架,需要进行 64 轮迭代,尽管作者认为 32 轮已经足够了。该算法使用了一个神秘常数δ作为倍数,它来源于黄金比率,以保证每一轮加密都不相同。但δ的精确值似乎并不重要,这里 TEA 把它定义为 δ=「(√5 - 1…

ui中的控件stackwidget如何拖拽添加widget

QStackedWidget界面的操作步骤-百度经验

UPX加壳原理,加壳及去壳:

加壳: 先写一个简单的代码:生成text.exe文件,然后把这个文件放到与upx同一个文件夹里: 输入指令./upx text.exe 即可加壳 使用IDA打开,可以明显发现被upx加壳了,其大小也由原来的55kb压缩到42KB: 去壳: 工具去壳: 使用指令./upx -d text.exe即可脱壳大小也变回去了,用…