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

目录

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 前言

为什么要研究边缘检测?

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

CS131专题-3:图像梯度、边缘检测(sobel、canny等)_第1张图片

CS131专题-3:图像梯度、边缘检测(sobel、canny等)_第2张图片

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

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

2 图像梯度

2.1 梯度公式的离散形式

数学中梯度定义如下:

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

CS131专题-3:图像梯度、边缘检测(sobel、canny等)_第3张图片

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

2.2 图像的梯度表示

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

CS131专题-3:图像梯度、边缘检测(sobel、canny等)_第4张图片

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

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

CS131专题-3:图像梯度、边缘检测(sobel、canny等)_第5张图片

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

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

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

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

CS131专题-3:图像梯度、边缘检测(sobel、canny等)_第6张图片

CS131专题-3:图像梯度、边缘检测(sobel、canny等)_第7张图片

几点注意:

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

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

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

CS131专题-3:图像梯度、边缘检测(sobel、canny等)_第8张图片

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

CS131专题-3:图像梯度、边缘检测(sobel、canny等)_第9张图片

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

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

CS131专题-3:图像梯度、边缘检测(sobel、canny等)_第10张图片

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

CS131专题-3:图像梯度、边缘检测(sobel、canny等)_第11张图片

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

CS131专题-3:图像梯度、边缘检测(sobel、canny等)_第12张图片

解决方案:

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

过程和理论效果如下:

CS131专题-3:图像梯度、边缘检测(sobel、canny等)_第13张图片

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

根据卷积的计算性质有:

CS131专题-3:图像梯度、边缘检测(sobel、canny等)_第14张图片

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

CS131专题-3:图像梯度、边缘检测(sobel、canny等)_第15张图片

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

CS131专题-3:图像梯度、边缘检测(sobel、canny等)_第16张图片

3 边缘检测  

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

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

CS131专题-3:图像梯度、边缘检测(sobel、canny等)_第17张图片

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(普鲁伊特)算子

卷积核长这样:

CS131专题-3:图像梯度、边缘检测(sobel、canny等)_第18张图片

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

效果:

CS131专题-3:图像梯度、边缘检测(sobel、canny等)_第19张图片

3.2.2——soble(索贝尔)算子

卷积核长这样:

CS131专题-3:图像梯度、边缘检测(sobel、canny等)_第20张图片

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

效果:

CS131专题-3:图像梯度、边缘检测(sobel、canny等)_第21张图片

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

四邻域模板核长这样:

CS131专题-3:图像梯度、边缘检测(sobel、canny等)_第22张图片

八邻域模板核长这样:

CS131专题-3:图像梯度、边缘检测(sobel、canny等)_第23张图片

效果:

CS131专题-3:图像梯度、边缘检测(sobel、canny等)_第24张图片

3.2.4——Roberts罗伯特交叉算子

卷积核长这样:

CS131专题-3:图像梯度、边缘检测(sobel、canny等)_第25张图片

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

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

CS131专题-3:图像梯度、边缘检测(sobel、canny等)_第26张图片

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

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

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

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

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

3.3 Canny边缘检测

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

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

问题1:边缘很粗

CS131专题-3:图像梯度、边缘检测(sobel、canny等)_第27张图片

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

问题2:渐变边低于阈值

CS131专题-3:图像梯度、边缘检测(sobel、canny等)_第28张图片

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

3.3.2——canny算法的原理

该算法整个过程如下:

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

1,2,3

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

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

CS131专题-3:图像梯度、边缘检测(sobel、canny等)_第29张图片

4步:NMS

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

CS131专题-3:图像梯度、边缘检测(sobel、canny等)_第30张图片

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

CS131专题-3:图像梯度、边缘检测(sobel、canny等)_第31张图片

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

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

CS131专题-3:图像梯度、边缘检测(sobel、canny等)_第32张图片

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

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

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

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

CS131专题-3:图像梯度、边缘检测(sobel、canny等)_第33张图片

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

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

CS131专题-3:图像梯度、边缘检测(sobel、canny等)_第34张图片

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

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

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

CS131专题-3:图像梯度、边缘检测(sobel、canny等)_第35张图片

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

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

2021年11月10日完成。

你可能感兴趣的:(斯坦福CS131,计算机视觉,图像处理,sobel,canny算法)