对边缘的直观理解

边缘有助于我们对图像进行语义理解。直观上,边缘发生在图像强度值变化剧烈的地方

如何描述变化?自然是用导数/梯度

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

用卷积描述导数

对于一个二元的连续函数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. 双阈值检测​

    定义高低两个阈值:

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

边缘检测及Canny算法的更多相关文章

  1. OpenCV探索之路(六):边缘检测(canny、sobel、laplacian)

    边缘检测的一般步骤: 滤波--消除噪声 增强--使边界轮廓更加明显 检测--选出边缘点 Canny算法 Canny边缘检测算法被很多人推崇为当今最优秀的边缘检测算法,所以我们第一个就介绍他. open ...

  2. 边缘检测之Canny

    1. 写在前面 最近在做边缘检测方面的一些工作,在网络上也找了很多有用的资料,感谢那些积极分享知识的先辈们,自己在理解Canny边缘检测算法的过程中也走了一些弯路,在编程实现的过程中,也遇到了一个让我 ...

  3. [OpenCV入门教程之十二】OpenCV边缘检测:Canny算子,Sobel算子,Laplace算子,Scharr滤波器合辑

    http://blog.csdn.net/poem_qianmo/article/details/25560901 本系列文章由@浅墨_毛星云 出品,转载请注明出处. 文章链接:http://blog ...

  4. 学习 opencv---(11)OpenC 边缘检测:Canny算子,Sobel算子,Laplace算子,Scharr滤波器

    本篇文章中,我们将一起学习OpenCV中边缘检测的各种算子和滤波器——Canny算子,Sobel算子,Laplace算子以及Scharr滤波器.文章中包含了五个浅墨为大家准备的详细注释的博文配套源代码 ...

  5. Canny算法检测边缘

    Canny算法是边缘检测的一个经典算法,比单纯用一些微分算子来检测的效果要好很多,其优势有以下几点: 边缘误检与漏检率低. 边缘定位准确,且边界较细. 自带一定的滤噪功能,或者说,对噪声的敏感度要比单 ...

  6. 边缘检测:Canny算子,Sobel算子,Laplace算子

    1.canny算子 Canny边缘检测算子是John F.Canny于 1986 年开发出来的一个多级边缘检测算法.更为重要的是 Canny 创立了边缘检测计算理论(Computational the ...

  7. opencv目标检测之canny算法

    canny canny的目标有3个 低错误率 检测出的边缘都是真正的边缘 定位良好 边缘上的像素点与真正的边缘上的像素点距离应该最小 最小响应 边缘只能标识一次,噪声不应该标注为边缘 canny分几步 ...

  8. Canny算法源码,欢迎交流

    http://blog.csdn.net/jianxiong8814/article/details/1563109 http://blog.csdn.net/assuper/article/deta ...

  9. (22)Canny算法

    基础知识,主要是看这个博客:https://blog.csdn.net/qq_41167777/article/details/84863351

  10. opencv笔记4:模板运算和常见滤波操作

    time:2015年10月04日 星期日 00时00分27秒 # opencv笔记4:模板运算和常见滤波操作 这一篇主要是学习模板运算,了解各种模板运算的运算过程和分类,理论方面主要参考<图像工 ...

随机推荐

  1. FormData接口调用

    JAVA调用方式 JAVA原生实现 package com.hisense.demo.utils; import java.io.*; import java.net.HttpURLConnectio ...

  2. Solution -「CTSC 2017」「洛谷 P3772」游戏

    \(\mathscr{Description}\)   有 \(n\) 个随机真值 \(x_{1..n}\), 已知 \(P(x_1=1)=p_1\), 对于 \(2\le i\le n\), \(P ...

  3. 使用iText对PDF文件签章和验章

    PDF是国际板式文件标准,使用的范围很广.OFD为国产板式文件标准,设计起点很高,天然支持国产签名算法(SM2.SM3):具有后发优势,目前市场占有率仍然很低,前途光明而又漫长.PDF标准并不支持国产 ...

  4. G1原理—5.G1垃圾回收过程之Mixed GC

    大纲 1.Mixed GC混合回收是什么 2.YGC可作为Mixed GC的初始标记阶段 3.Mixed GC并发标记算法详解(一) 4.Mixed GC并发标记算法详解(二) 5.Mixed GC并 ...

  5. python基础学习6和7

    模块类与对象 模块 内置模块 time, random, os, json 第三方模块 requests, pandas, numpy,.... 自定义模块 xxx.py 常见的内置模块 hashli ...

  6. FastReport实现遍历Dataset数据集计算

    delphi在使用fastreport进行打印时,需要对数据进行计算求和. 在打印文本框的OnBeforePrint事件中进行以下代码即可实现效果 procedure Memo7OnBeforePri ...

  7. npm run的时候报错: this[kHandle] = new _Hash(algorithm, xofLen);

    在前面加入以下配置信息 set NODE_OPTIONS=--openssl-legacy-provider && 后面跟原来的启动配置信息 另外一种方式,可以避免修改package. ...

  8. 一文详解 Sa-Token 中的 SaSession 对象

    Sa-Token 是一个轻量级 java 权限认证框架,主要解决登录认证.权限认证.单点登录.OAuth2.微服务网关鉴权 等一系列权限相关问题. Gitee 开源地址:https://gitee.c ...

  9. 更换Linux系统镜像源

    更换Linux系统镜像源 切换镜像源通常是为了提高软件包下载的速度和稳定性.以下是CentOS 7切换镜像源的一般步骤: 一.安装wget(如果尚未安装) 首先,需要确保系统中安装了wget工具,因为 ...

  10. 深入剖析实体-关系模型(ER 图):理论与实践全解析

    title: 深入剖析实体-关系模型(ER 图):理论与实践全解析 date: 2025/2/8 updated: 2025/2/8 author: cmdragon excerpt: 实体-关系模型 ...