数字图像处理---通俗Canny边缘检测

0.何谓边缘

说起边缘,那肯定是图像中明暗变化比较剧烈的像素所组成的线条。从视觉的角度来讲,我们首先注意到的其实就是一些简单的线条,然后再由这些简单的线条组合成更加抽象的概念来使得我们能够认识出我眼前的是个啥。就好比下面的图,你光看那个边缘图,是不是大概就能看出来原图里是个女人?
数字图像处理---通俗Canny边缘检测_第1张图片
右边的边缘图其实就是把原图中的边缘提取出来之后的图,从直觉上也能够看得出来,所谓的边缘检测无非就是对整个图的像素做像素级的二分类。要么是边缘点(用白色表示),要么不是边缘点(用黑色表示)。把这些点展示出来就成了边缘图。

当然边缘检测的算法有很多种,这篇博客就先简单哔哔一下最为经典的边缘检测算法—Canny!!

1.Canny边缘检测算法流程

其实Canny算法的步骤就那么几步:
1.高斯滤波
2.计算图像的梯度和梯度方向
3.非极大值抑制
4.双阈值筛选边缘

很明显第一步无非就是减少图像中的噪声,增强边缘检测的鲁棒性。第二步是想把边缘给强调出来,但是由于强调出来有二义性,所以用第三步来过滤一些边缘点。但是第三步可能过滤不干净,所以就有了第四步的套路来过滤干净。so。。。下面就一个一个的来哔哔。

2.高斯滤波

高斯滤波和其他的滤波器套路基本上一致,无非就是一个滤波核在原图上摩擦摩擦,一步一步似爪牙,似魔鬼的步伐。。。所以高斯滤波的效果如何,取决于滤波核的大小和里面的值。
数字图像处理---通俗Canny边缘检测_第2张图片
那现在的主要矛盾就是滤波核里的值怎么来确定。其实非常简单,就是通过这么一个公式:
数字图像处理---通俗Canny边缘检测_第3张图片
这个公式的意图是啥呢?其实就是个滤波核里的值尽量的填成一个二维的高斯分布。我们可以举个栗子:
1.假设我的滤波核是3*3的
2.假设我的高斯分布的标准差为1也就是σ=1
3.x和y代表滤波核中各个点相对于中心点的坐标,就像酱紫:
数字图像处理---通俗Canny边缘检测_第4张图片
有了这些假设之后,我们就能很简单的把滤波核对应的值给算出来,就像酱紫:
数字图像处理---通俗Canny边缘检测_第5张图片
但是这个时候算出来的值有个问题,如果把所有的9个值全加起来不等于1!!!(概率合应该为1)所以我们要对其进行归一化,让所有的9个值加起来等于1。其实归一化很简单,就是个9个值全加起来也就是(0.0585+0.0965+0.0585+…+0.0585=0.7792),然后把每个值都除以这个0.7792,就能得到归一化后的滤波核。(这个时候你会发现所有值全加起来等于1)
数字图像处理---通俗Canny边缘检测_第6张图片
而且可以脑补一下,如果波滤核的size比较大,然后每个格子里面的值看成是概率的话。其实就可以脑补成酱紫的图(很明显的一个二维高斯分布):
数字图像处理---通俗Canny边缘检测_第7张图片
确定了滤波核的值之后,就可以快乐的滤波了。

3. 计算图像的梯度和梯度的方向

要算图像的梯度,肯定会想到图像的梯度算子。在Canny中用到的梯度算子是Sobel算子,说是算子,其实就是滤波核。Sobel算子主要分为两个,一个是用来计算水平方向的梯度,另一个用来计算竖直方向的梯度。
数字图像处理---通俗Canny边缘检测_第8张图片
在这里插入图片描述
所以,对原图用第一个滤波核就能算出图像的水平方向的梯度,用第二个滤波核就能算出图像的竖直方向的梯度。

有了两个方向的梯度之后,其实就能算出图像的梯度和梯度的方向了。因为已经有了水平和竖直了,要算总的梯度,无非就是勾股定理嘛~~~~

数字图像处理---通俗Canny边缘检测_第9张图片
也就是说
图像的梯度值 = 开根号(竖直方向的梯度幅值的平方+水平方向的梯度幅值的平方)

图像的方向 = arctan(竖直方向的梯度幅值/水平方向的梯度幅值)

4. 非极大值抑制

假设现在拿到了梯度方向的图是酱紫:
数字图像处理---通俗Canny边缘检测_第10张图片
梯度幅值的图是酱紫:
数字图像处理---通俗Canny边缘检测_第11张图片
那如果要做非极大值抑制,就还需要个东西,就是这个:
数字图像处理---通俗Canny边缘检测_第12张图片
这个表达的意思非常简单,中间的方块可以看成是一个3*3的区域,然后线代表的是角度。比如(-1,1)这个点的角度是45度,(0, 1)这个点的角度是0度。那这个东西有啥用呢,举个栗子:
如果我要对梯度幅值图里第2行第2列的那个点(值是144)做非极大值抑制,那我就看我对应的方向的值是多少,很明显是26。那26很明显和45度更加接近,所以我要做非极大值抑制的时候所要对比的梯度幅值的点就是45度那根线所对应的点,也就是5和3。此时可以看出,144>5并且144>3,所以144是个极大值点,所以这个点就不会被抑制。

那如果我要对梯度幅值图里第5行第2列的点(值是178)做非极大值抑制,那很明显它的方向也就是角度是7度,7度离0度更近,所以我要做非极大值抑制的时候所要对比的梯度幅值的点就是0度那根线所对应的点,也就是180和14。此时可以看出,178<180并且178>14,所以178不是个极大值点,所以这个点就要被舍弃,把他赋成0。

很明显,对整个图做完非极大值抑制之后,是极大值的点得到了保留,不是极大值的点就都赋成了0。

5.双阈值筛选边缘

我们要做边缘检测目的是把边缘点设置成255,非边缘点设置成0。但做完非极大值抑制之后,图中的点虽然有一部分已经被抑制成了0。但我们还不知道应该把剩下的哪些点设置成边缘点。那有的童鞋可能会觉得,我设个阈值不就好了?我梯度值大于某个阈值我就认为是边缘点。这样当然可以,但是效果不会太好。所以前辈们撸了个双阈值筛选边缘的套路。套路如图:
数字图像处理---通俗Canny边缘检测_第13张图片
套路呢从图就能很容易的看出来,就是会有两个阈值A和B(A 数字图像处理---通俗Canny边缘检测_第14张图片

OK,这样一套流程下来,Canny边缘检测就做完了,希望这篇博客对想了解Canny算法大致流程的童鞋有一定的帮助。也欢迎各位大佬吐槽。

你可能感兴趣的:(算法铺子,ML历险记,图像处理,人工智能,边缘检测,Canny,计算机视觉)