数字图像处理笔记——边缘检测(Edge detection)

边缘检测

我们之前讲边缘检测的时候讲到了一阶导和二阶导,理想边缘的像素值是跳变的,而斜坡边缘的像素值是渐变的。我们在求一阶导的时候导数值大的地方可以看做边缘;若是对于斜坡边缘,我们不想得到一长条边缘,而只想得到这个渐变的中央点时,我们可以看二阶导,二阶导只在边缘开始与结束的地方会出现,因此我们只需要找到二阶导的过零点就可以找到渐变的中央点了

在现实生活中出现的边缘更多时候带有噪声,这种情况下使得我们很难找到边缘

这种情况下我们的解决方法就是先加一个低通滤波器再进行边缘检测,这也就是我们在SOBEL滤波器中做的事情,我们可以将其看做在一个方向上做边缘检测,在另一个方向上做一个平滑滤波

边缘检测基本上与图像的梯度有关

图像的边缘与梯度垂直,因此我们可以用图像在两个方向上导数的平方和来表示图像是否存在边缘,边缘的角度由两个导数的反正切值表示

利于对于如下图像我们可以看到M与α的值,在求M的时候我们用两个方向的SOBEL滤波器对图像进行滤波来得到gx、gy(当然也可以采用[-1 1]这样简单的差分形式),再求平方和。由于这种方法采用的是一阶导,因此M大的地方表示导数值比较大,阿尔法来表示边缘的角度。通过这两幅图我们可以通过筛选某个特定的角度来实现检测特定方向的边缘,例如我们筛选M(x,y)>τ&|α(x,y)<θ|的值可以得到方向为大致为θ的边缘

高斯拉普拉斯函数

除了SOBEL算子,我们还有其他的方法可以检测一个图像的边缘,一种方法就是利用高斯拉普拉斯函数

这种方法的本质就是先利用高斯滤波器对图像进行滤波,来过滤掉乱七八糟的东西,再求拉普拉斯算子来检测图像的边缘,得到的结果像一个墨西哥帽,因此也叫墨西哥帽函数

由于这种方法采用的是二阶导,因此图像中过零点的位置是图像的边缘,我们在MATLAB中可以用fspecial加'log'参数来构造一个高斯拉普拉斯函数,再用这个函数对图像进行滤波就能得到检测结果

这种方法的好处是我们可以调整需要检测边缘的尺度,如果要检测的边缘很小,我们可以把σ调小,得到的就是左图的结果;如果需要检测大边缘,我们将高斯函数的σ调大,得到的是右图的结果,最明显的地方就是图里面鼻子的边缘消失了

为了减少计算量,我们也可以用两个高斯函数来得到高斯拉普拉斯函数作为近似

CANNY边缘检测

相对以上两种算法,CANNY边缘检测算法更加复杂,但是效果更好,它的基本思路是先对图像进行低通滤波,之后计算M与α,然后对M采用非极大值抑制算法来得到一个新的梯度图

非极大值抑制算法的思路如下,将α分成四个块(根据需求可以调整为更多的块)。由于我们在之前讲过对于斜坡边缘,它的一阶导大的值有很多,因此我们先看一个像素的阿尔法属于哪个块,再在这个特定方向上寻找比周围值都大的导数值(最能代表这个边缘)作为新的边缘,而将其他值置零就可以了

最后一部就是设定两个阈值,梯度值大于大阈值,则这个新像素的值置1;梯度值小于小阈值的像素,新像素值置0;处在两个阈值之间的值,看它是否与已经置1的像素接壤,如果是,则这个像素也置1。最后一步是为了补全两段边缘之间的间隙,从而使边缘更加完整

左图是用CANNY算法得出的结果,右图是SOBEL算子算出的结果,我们可以看到CANNY边缘检测算法确实取得了更好的效果

猜你喜欢

转载自blog.csdn.net/shanwenkang/article/details/84586165