目录
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像素,所以图像中梯度公式就变为:
最简单来说,图像的梯度,就是两个临近像素点的差值。当然也可以用左右临近的6个像素点差值和表示,这里对 f(x) 不同的看待方法,就产生了Opencv中常用的sobel、Prewitt等不同的梯度计算算子,后面会介绍它们。
边缘是图像强度函数中变化迅速的地方,边缘可以用梯度值表示,如下:
通常情况下,图像的梯度我们表示如下:
梯度向量指向图像强度增长最快的方向:
梯度的方向计算公式为(角度值相对于x轴方向):
梯度的模长(幅值)——数学意义是此处梯度变化的大小,物理意义是为图像边缘的强度或可能性:
我们要获得X方向梯度图,本质上就是让梯度图中每个位置的像素点值代表原图中相应位置的左右两个像素值之差。这刚好直接把原图跟[-1, 0, 1]行向量进行卷积就能得到!!!如下是对一个高斯核图像进行X方向求导的示意图:
几点注意:
提示:求Y方向梯度图像同理,而求梯度的模长图像,只要求X和Y的平方和再开根号就能得到。
对高斯核(可以视为一个图像)的X和Y方向求导的3D和2D可视化结果如下:
对一般的图像求导结果的可视化如下:(同样注意:下图灰度值大小并不代表具体的求导值结果,梯度值中也有负数)
如果像下面这样的‘简单干净’图像,可以直接用图像梯度找到边缘:
但是大多情况下,图像是有各种噪声的,比如:
当图像的像素存在大量噪点时,相邻的像素差异大,所求梯度也会偏大,无法提取边缘信息:(注意:之前我们讲的图像梯度是仅计算相邻两个像素点灰度值变化幅度,所以只要图像模糊或有噪声等,图像中任何位置都可能梯度变化成随机值)
解决方案:
过程和理论效果如下:
上述方案降低计算量的方法:
根据卷积的计算性质有:
我们可以先对平滑核求导,再进行卷积相乘,从而减少计算量,如下:
不同σ值高斯核对图像平滑去噪后,再对图像求导的结果如下:
先提示几点:
卷积核长这样:
其利用像素点上下、左右邻点的灰度差。这种判定是欠合理的,会造成边缘点的误判,因为许多噪声点的灰度值也很大,而且对于幅值较小的边缘点,其边缘反而丢失了。
效果:
卷积核长这样:
Sobel 算子在 Prewitt 算子的基础上增加了权重的概念,认为相邻点的距离远近对当前像素点的影响是不同的,距离越近的像素点对应当前像素的影响越大,从而实现图像锐化并突出边缘轮廓。
效果:
四邻域模板核长这样:
八邻域模板核长这样:
效果:
卷积核长这样:
这网上普遍说是最简单的算子,而且最先介绍。元素值是少并简单,但理解感觉是最难的,而且用的很少,所以我放在最后介绍。
这是Roberts于1963年提出的交叉算子边缘检测方法。该方法最大优点是计算量小,速度快。但该方法由于是采用偶数模板,如下图所示,所求的(x,y)点处梯度幅度值,其实是图中交叉点处的值,从而导致在图像(x,y)点所求的梯度幅度值偏移了半个像素(见下图)。
1)Robert算子对陡峭的低噪声图像效果较好,尤其是边缘正负45度较多的图像,但定位准确率较差;
2)Prewitt算子对灰度渐变的图像边缘提取效果较好,而没有考虑相邻点的距离远近对当前像素点的影响;
3)Sobel算子考虑了综合因素,对噪声较多的图像处理效果更好。
4)Laplacian算子对噪声比较敏感,由于其算法可能会出现双像素边界,常用来判断边缘像素位于图像的明区或暗区,很少用于边缘检测;
该算法诞生于1986年,这可能是计算机视觉中应用最广泛的边缘检测器,着重讲一讲。
问题1:边缘很粗
在如sobel这样的边缘检测算子,对图像求梯度图后,会设置一个阈值,绝对值超过阈值的像素为视为边缘,这就导致得到的边缘图中‘边缘’会很粗。
问题2:渐变边低于阈值
由于sobel中梯度阈值是全局性的,不能太高也不能太低,这就导致很多不明显的渐变边被擦除。
该算法整个过程如下:
第1,2,3步
2,3个步理解简单,但工程上具体实现时其实是这样的:先对高斯核求导,然后求导后的高斯核对原灰度图进行卷积操作。这样做的目的简化计算量,之前专题内容里有提到过原理。
假设对某图完成1,2,3步后结果如下:
第4步:NMS
为了解决梯度图中‘边缘’很粗问题,我们要利用非极大值抑制算法来找到沿着梯度方向的局部最大像素点,非局部最大像素点全部变为0,就像下面这种情况:
具体怎么实现上述非极大值抑制想法呢?思想和方法很简单,编程也不复杂,如下:
使用NMS算法的效果如下:(边缘几乎都变成单像素宽度了,亮度强度代表梯度幅值大小即是边缘的强度)
上图放大观察后会发现,经过NMS后的梯度图,边缘宽度基本为1个像素宽度了,筛除了大量冗余的边缘像素点。
第5步:双阈值 + 连通区域分析
对梯度图每个像素都做上述这种筛选,就得到极大值抑制之后的新梯度图。走到这一步,如果直接设个梯度幅值阈值,也能直接得到没有‘粗’边缘的梯度图了,但是全图一刀切的梯度阈值肯定不好,一个好办法是设置两个阈值,一个高一个低,超过高标准阈值的梯度点视为‘确定边缘’,在高标准和低标准之间的视为‘待确认边缘’,低于低标准阈值的视为‘非边缘’。
其中‘待确认边缘’的进一步确认方法就是:看这个点是否在任何一个‘确定边缘’点所形成的连通区域线上,如果在则保留,不在则排除。
如上图,B位置的边缘线,它们没有跟任何一个超过maxVal阈值的点有连通,它们将全部排除。而C区域的一些梯度像素点因为和超过高阈值的梯度像素点有连通,所以这些梯度幅值虽然不大的边缘点,同样会被保留。
使用双阈值 + 连通区域分析 与 单阈值的对比效果如下:
上图右下角就是canny算法处理的最终效果,比较好的解决了上面提到的两个问题。
采用不同σ的高斯核,canny算法最终得到的效果会有较大变化,本质原因是高斯核的σ越大,则对图像平滑效果越明显,越是会把边缘给平滑掉。
所以,高斯核的σ越小,最终得到的边缘会越密集详细,反之,边缘会稀疏(仅保留非常明显的边缘)。根据这一特性,你可以根据需要,通过控制σ来让自己获取详略不同的边缘图。
我们现在知道了计算机视觉中边缘提取的全过程,它能有什么用呢?下一专题开始介绍其用途以及实现不同用途所需要的不同算法。
2021年11月10日完成。