目录

1 前言

2 图像梯度

2.1 梯度公式的离散形式

2.2 图像的梯度表示

2.3 图像梯度的最简单计算方法

2.4 直接应用梯度找图像边缘的问题以及解决方案

3 边缘检测

3.1 好的边缘检测器应具备的要素

3.2 简单的边缘检测算子

3.2.1——Prewitt(普鲁伊特)算子

3.2.2——soble(索贝尔)算子

3.2.3——Laplacian(拉普拉斯)算子

3.2.4——Roberts罗伯特交叉算子

3.2.5——上述4种算子的总结:

3.3 Canny边缘检测

3.3.1——常规边缘检测算法的2个问题

3.3.2——canny算法的原理

3.3.3——高斯核对canny算法的影响


1 前言

为什么要研究边缘检测?

答:直观地说,图像中的大多数语义和形状信息都可以用‘边缘’来体现。(更深层的生理原因是哺乳动物的大脑神经元对边缘信息非常敏感)

形成图像边缘常见的一些原因:

  • 表面形状的突变
  • 背景深度的不连续
  • 颜色的突变
  • 光线阴影的不连续

2 图像梯度

2.1 梯度公式的离散形式

数学中梯度定义如下:

因为图像是离散的二维函数,最小单位就是1像素,所以图像中梯度公式就变为:

最简单来说,图像的梯度,就是两个临近像素点的差值。当然也可以用左右临近的6个像素点差值和表示,这里对 f(x) 不同的看待方法,就产生了Opencv中常用的sobel、Prewitt等不同的梯度计算算子,后面会介绍它们。

2.2 图像的梯度表示

边缘是图像强度函数中变化迅速的地方,边缘可以用梯度值表示,如下:

通常情况下,图像的梯度我们表示如下:

梯度向量指向图像强度增长最快的方向:

梯度的方向计算公式为(角度值相对于x轴方向):

梯度的模长(幅值)——数学意义是此处梯度变化的大小,物理意义是为图像边缘的强度或可能性:

2.3 图像梯度的最简单计算方法

我们要获得X方向梯度图,本质上就是让梯度图中每个位置的像素点值代表原图中相应位置的左右两个像素值之差。这刚好直接把原图跟[-1, 0, 1]行向量进行卷积就能得到!!!如下是对一个高斯核图像进行X方向求导的示意图:

几点注意:

  1. 上图中3D高斯核的‘水平面’代表2D高斯核图中像素0值,高于水平面的是正数(图像的灰度值本身就是全为正),但是得到的求导图像,开始出现负值。
  2. 是跟[-1, 0, 1]卷积还是[1, 0, -1]卷积,没有本质区别,虽然结果区域的正负号会变化,但只要事先统一确认方向,最终判定边缘或搞其他操作,正负号并不产生影响。

提示:求Y方向梯度图像同理,而求梯度的模长图像,只要求X和Y的平方和再开根号就能得到。

对高斯核(可以视为一个图像)的X和Y方向求导的3D和2D可视化结果如下:

对一般的图像求导结果的可视化如下:(同样注意:下图灰度值大小并不代表具体的求导值结果,梯度值中也有负数)

2.4 直接应用梯度找图像边缘的问题以及解决方案

如果像下面这样的‘简单干净’图像,可以直接用图像梯度找到边缘:

但是大多情况下,图像是有各种噪声的,比如:

当图像的像素存在大量噪点时,相邻的像素差异大,所求梯度也会偏大,无法提取边缘信息:(注意:之前我们讲的图像梯度是仅计算相邻两个像素点灰度值变化幅度,所以只要图像模糊或有噪声等,图像中任何位置都可能梯度变化成随机值)

解决方案:

  1. 先平滑处理:使用平滑滤波器去噪,使图像信号变得平滑。
  2. 然后再对平滑后的信号求导,取极值。

过程和理论效果如下:

上述方案降低计算量的方法:

根据卷积的计算性质有:

我们可以先对平滑核求导,再进行卷积相乘,从而减少计算量,如下:

不同σ值高斯核对图像平滑去噪后,再对图像求导的结果如下:

3 边缘检测

3.1 好的边缘检测器应具备的要素

  1. 精度要好:把假阳性(误检)、假阴性(漏检)检测概率搞得尽量低。
  2. 位置要准:检测到的边缘位置要和原图一致。
  3. 连续+尽量窄:如下图最左边是好的边缘返回结果,右边3个时差的返回结果。

3.2 简单的边缘检测算子

先提示几点:

  1. 很多算子的核宽可以指定和变化。
  2. 彩色图相当于3种灰度图的叠加,彩色图求梯度需要先转成一个灰度图。转灰度图主要有两种方法:
    1. 方法1:Gray=(R+G+B)/3;
    2. 方法2:Gray=0.299R+0.587G+0.114B;(这种参数考虑到了人眼的生理特点)
  3. 图像梯度对噪音非常敏感,需要先对图像进行平滑,然后求梯度。通常滤波和边缘检测是矛盾的概念,抑制了噪声会使得图像边缘模糊,这会增加边缘定位的不确定性;实际工程经验表明,使用高斯核函数可以在抗噪声干扰和边缘检测精确定位之间提供较好的折衷方案。
  4. 使用opencv的梯度算子,实际上要取个阈值,梯度图元素的绝对值超过阈值的部分视为边缘。低于阈值的像素点用0值表示,表示此处没边缘,不为0的像素点,灰度值越高表面此处边缘强度越大。

3.2.1——Prewitt(普鲁伊特)算子

卷积核长这样:

其利用像素点上下、左右邻点的灰度差。这种判定是欠合理的,会造成边缘点的误判,因为许多噪声点的灰度值也很大,而且对于幅值较小的边缘点,其边缘反而丢失了。

效果:

3.2.2——soble(索贝尔)算子

卷积核长这样:

Sobel 算子在 Prewitt 算子的基础上增加了权重的概念,认为相邻点的距离远近对当前像素点的影响是不同的,距离越近的像素点对应当前像素的影响越大,从而实现图像锐化并突出边缘轮廓。

效果:

3.2.3——Laplacian(拉普拉斯)算子

四邻域模板核长这样:

八邻域模板核长这样:

效果:

3.2.4——Roberts罗伯特交叉算子

卷积核长这样:

这网上普遍说是最简单的算子,而且最先介绍。元素值是少并简单,但理解感觉是最难的,而且用的很少,所以我放在最后介绍。

这是Roberts于1963年提出的交叉算子边缘检测方法。该方法最大优点是计算量小,速度快。但该方法由于是采用偶数模板,如下图所示,所求的(x,y)点处梯度幅度值,其实是图中交叉点处的值,从而导致在图像(x,y)点所求的梯度幅度值偏移了半个像素(见下图)。

3.2.5——上述4种算子的总结:

1)Robert算子对陡峭的低噪声图像效果较好,尤其是边缘正负45度较多的图像,但定位准确率较差;

2)Prewitt算子对灰度渐变的图像边缘提取效果较好,而没有考虑相邻点的距离远近对当前像素点的影响;

3)Sobel算子考虑了综合因素,对噪声较多的图像处理效果更好。

4)Laplacian算子对噪声比较敏感,由于其算法可能会出现双像素边界,常用来判断边缘像素位于图像的明区或暗区,很少用于边缘检测;

3.3 Canny边缘检测

该算法诞生于1986年,这可能是计算机视觉中应用最广泛的边缘检测器,着重讲一讲。

3.3.1——常规边缘检测算法的2个问题

问题1:边缘很粗

在如sobel这样的边缘检测算子,对图像求梯度图后,会设置一个阈值,绝对值超过阈值的像素为视为边缘,这就导致得到的边缘图中‘边缘’会很粗。

问题2:渐变边低于阈值

由于sobel中梯度阈值是全局性的,不能太高也不能太低,这就导致很多不明显的渐变边被擦除。

3.3.2——canny算法的原理

该算法整个过程如下:

  1. 对原始图像进行灰度化
  2. 对图像进行平滑(高斯滤波)
  3. 求图像平滑后的梯度图、以及梯度方向图
  4. NMS非极大值抑制筛选
  5. 双阈值+连通与否筛选

1,2,3

2,3个步理解简单,但工程上具体实现时其实是这样的:先对高斯核求导,然后求导后的高斯核对原灰度图进行卷积操作。这样做的目的简化计算量,之前专题内容里有提到过原理。

假设对某图完成1,2,3步后结果如下:

4步:NMS

为了解决梯度图中‘边缘’很粗问题,我们要利用非极大值抑制算法来找到沿着梯度方向的局部最大像素点,非局部最大像素点全部变为0,就像下面这种情况:

具体怎么实现上述非极大值抑制想法呢?思想和方法很简单,编程也不复杂,如下:

  • 找沿着梯度方向线上的局部最大像素点:首先要明白,我们要找到并保留的是沿着梯度方向线上的局部最大像素点,而不是各方向局部最大像素点。因为,边缘线一般是连通的,不能只找上下左右梯度幅值最大的那个,这么找得到的边缘线就必定断裂了。
  • 判定方法——看C点像素值是否比dTmp1dTmp2都大:上图C点是梯度图中某个像素点,它周围有8个临近像素点,还有一根C点位置梯度方向的可视化直线,这根直线在g1,g2像素点之间有个交点dTmp1,在g3,g4像素点之间有个交点dTmp2。虽然这两个交点的像素值本就不存在,但可以通过附近的两个像素点通过线性插值估算出来(这里也要用到梯度方向)。如果C像素点梯度幅值比那两个交点大,那么这个C点就保留,否则的话,这个像素点置为0。

使用NMS算法的效果如下:(边缘几乎都变成单像素宽度了,亮度强度代表梯度幅值大小即是边缘的强度)

上图放大观察后会发现,经过NMS后的梯度图,边缘宽度基本为1个像素宽度了,筛除了大量冗余的边缘像素点。

5步:双阈值 + 连通区域分析

对梯度图每个像素都做上述这种筛选,就得到极大值抑制之后的新梯度图。走到这一步,如果直接设个梯度幅值阈值,也能直接得到没有‘粗’边缘的梯度图了,但是全图一刀切的梯度阈值肯定不好,一个好办法是设置两个阈值,一个高一个低,超过高标准阈值的梯度点视为‘确定边缘’,在高标准和低标准之间的视为‘待确认边缘’,低于低标准阈值的视为‘非边缘’。

其中‘待确认边缘’的进一步确认方法就是:看这个点是否在任何一个‘确定边缘’点所形成的连通区域线上,如果在则保留,不在则排除。

如上图,B位置的边缘线,它们没有跟任何一个超过maxVal阈值的点有连通,它们将全部排除。而C区域的一些梯度像素点因为和超过高阈值的梯度像素点有连通,所以这些梯度幅值虽然不大的边缘点,同样会被保留。

使用双阈值 + 连通区域分析单阈值的对比效果如下:

上图右下角就是canny算法处理的最终效果,比较好的解决了上面提到的两个问题。

3.3.3——高斯核对canny算法的影响

采用不同σ的高斯核,canny算法最终得到的效果会有较大变化,本质原因是高斯核的σ越大,则对图像平滑效果越明显,越是会把边缘给平滑掉。

所以,高斯核的σ越小,最终得到的边缘会越密集详细,反之,边缘会稀疏(仅保留非常明显的边缘)。根据这一特性,你可以根据需要,通过控制σ来让自己获取详略不同的边缘图。

我们现在知道了计算机视觉中边缘提取的全过程,它能有什么用呢?下一专题开始介绍其用途以及实现不同用途所需要的不同算法。

2021年11月10日完成。

CS131专题-3:图像梯度、边缘检测(sobel、canny等)相关推荐

  1. opencv for python的图像梯度算子以及canny边缘检测

    opencv for python的图像梯度算子以及canny边缘检测 一.图像梯度算子: 二.Canny边缘检测(一个多级边缘检测算法): 一.图像梯度算子: 1.概念简介(部分引自百度百科): 图 ...

  2. OpenCV图像梯度(Sobel和Scharr)

    OpenCV图像梯度(Sobel和Scharr) 1 图像梯度是什么? 2 图像梯度的用途 3 图像梯度的使用 参考 这篇博客将介绍图像渐变以及如何使用OpenCV的cv2.Sobel计算Sobel渐 ...

  3. opencv-python图像处理 ----图像梯度、Sobel算子

    一.图像的梯度处理 1.Sobel算子 梯度可以按照x方向或者y方向求梯度,其实就是在看像素点的差异变化情况,比如黑白物体的交界,其像素值变化差异是非常大的. 求梯度计算使用的函数就叫做Sobel算子 ...

  4. 图像梯度算子——Sobel/scharr/Laplacian

    1.sobel算子 sobel算子可以计算图像梯度,计算图像梯度的作用是提取边界. (1)X方向的梯度 以3x3的卷积核计算sobel算子为例: 图中左边就是计算水平梯度时的卷积核,简单来说就是右边减 ...

  5. python怎么计算图像梯度_Opencv-Python学习笔记十——图像梯度、边缘检测 Gradient, Edge Detection...

    图像梯度 边缘检测 图像梯度,图像边界 使用到的函数有: cv2.Sobel(), cv2.Schar(), cv2.Laplacian() 梯度简单来说就是求导,OpenCV 提供了三种不同的梯度滤 ...

  6. OpenCV——图像梯度与边缘检测(python实现)

    OpenCV--图像梯度与边缘检测 6.1 简介 严格的说,梯度计算需要求导数.但是图像梯度的计算,是通过计算像素值的差得到梯度的近似值.图像梯度表示的是图像变化的速度,反映了图像的边缘信息. 边缘是 ...

  7. OpenCV(十七)边缘检测3 -- Canny算子(最优边缘检测)

    目录 一.基础理论 1.作用及介绍 1.原理 2.过程 3.Canny函数 二.回调函数及总代码 效果 参考资料 ​​​​​​​ 一.基础理论 1.作用及介绍 Canny边缘检测是非常流行的边缘检测算 ...

  8. Halcon之图像梯度、图像边缘、USM锐化

    图像梯度.图像边缘.USM锐化图像梯度.图像边缘.USM锐化图像梯度.图像边缘.USM锐化 图像卷积: 1.模糊 2.梯度 3.边缘 4.锐化 1.视频教程: B站.网易云课堂.腾讯课堂 2.代码地址 ...

  9. OpenCV中的图像处理 —— 图像梯度+Canny边缘检测+图像金字塔

    OpenCV中的图像处理 -- 图像梯度+Canny边缘检测+图像金字塔 目录 OpenCV中的图像处理 -- 图像梯度+Canny边缘检测+图像金字塔 1. 图像梯度 1.1 Sobel和Schar ...

最新文章

  1. 如何在 Vue 项目中使用 echarts
  2. 计算机视觉迎新突破?谷歌AI模型打破现有CNNs精度
  3. 用户人品预测大赛--getmax队--竞赛分享
  4. spring事务--使用aop事务代理对象调用方法示例
  5. Redis数据库(一)——Redis简介、部署及常用命令
  6. 2015蓝桥杯省赛---java---C---6(奇妙的数字)
  7. python 死循环插曲变量_FishC03 讲:python小插曲之变量和字符串
  8. java回忆录—输入输出流详细讲解(入门经典)
  9. 抽象类的继承/纯虚函数的实现
  10. 多线程例题练手(c入门)
  11. Asp.Net学习之-母板
  12. PPT修改母版页码(亲测可用)
  13. HTML+CSS美食静态网页设计——简单我的家乡吉林
  14. c++中“箭头(-)”和“点号(.)”操作符的区别
  15. 手机如何借用笔记本网络上网
  16. 美食杰小项目(首页)
  17. 2017usnews计算机科学,2017年USNews美国计算机CS专业研究生排名
  18. 监控物联网项目:web、flv视频流 、websocket、ESP32
  19. brew官网安装方法过慢的解决办法
  20. Python学习笔记:练习-和电脑对战的小游戏

热门文章

  1. 你哪来这么多事(三):学生信息删除
  2. java正则表达式 匹配%号_java正则表达式匹配带有括号的电话号为什么匹配不上...
  3. datatable java实现分页_jQuery Datatable - 使用Php的服务器端处理数据分页
  4. Git 头指针分离与 FETCH_HEAD
  5. CoordinatorLayout 和 AppBarLayout 实现的局部点击按钮实现滑动某一个固定的距离
  6. java运行环境jdk的安装和环境变量的配置教程
  7. cygwin执行.py提示找不到模块,但已经安装模块的解决办法
  8. Ubuntu 划词翻译
  9. JavaScript 变量
  10. Ubuntu换回Gnome界面