Canny边缘检测
本文主要参考:
冈萨雷斯 《数字图像处理》第二版
边缘检测是数字图像处理中应用十分广泛的一类算法,它能够将图像信息简化为线条特征供后续的图像算法使用,在电子元件自动检测、虹膜识别等方向都发挥了较大作用。Canny边缘检测算子是John F. Canny于1986年开发出来的一个多级边缘检测算法。目前,Canny算子是传统边缘检测算法中使用最广泛、效果最好的一种算法。本文将分享本人在学习Canny算子过程中的笔记和思路。Canny边缘检测算法基本步骤如下:
1. 高斯平滑
要想对图像进行边缘检测,首先要知道边缘在图像中的表现形式。下图引用自《数字图像处理》,显示的是放大后的边缘区域。(a)图显示的是理想的边缘数字模型,在理想情况下,边缘两端图像灰度级会产生跳变,能够清晰地看到边界的存在,从灰度剖面图可以看到,边缘两边的灰度级相差较大,并存在跃变。但是,在现实情况下,由于光学系统、取样和其他图像采集的不完善性得到的图像边缘是模糊的,模糊程度与图像获取过程以及图像质量有关。在这种模糊图像中,边缘处的灰度级将不会存在大的跳变,而是一种斜坡式的变化,斜坡部分与边缘的模糊程度成正比,如图(b)所示。
考虑到灰度级在边缘处存在较大的变化,检测边缘的基本思路就是在边缘处对灰度级进行求导,得到灰度的变化情况。如下图展示的是灰度在边缘处的一阶导数和二阶导数情况。可以看到,在边缘两侧由于灰度级变化不大,因此灰度的一阶导数趋近于零,而在斜坡部分的导数大于零,因此我们可以通过一阶导数确定边缘的存在情况。而由于灰度剖面图存在斜坡部分,无法准确定位边缘位置,我们通过求灰度的二阶导数可以看到,在斜坡的开始和结束位置二阶导数存在跳变,我们可以通过连接二阶导数的极大和极小值点,取该直线与零轴相交的点坐标作为边缘处坐标。
上述讨论确定了使用灰度的导数信息进行边缘检测。然而,在实际的图像数据中,往往存在噪声干扰,而求导操作又是一种对噪声十分敏感的操作。如下图展示了在边缘处加入不同程度的噪声后,在对图像灰度进行求导操作得到的一阶和二阶导数曲线图。可以看到,加入噪声后,由于求导操作对噪声的敏感性,导致导数信息无法使用的问题。因此,在进行边缘检测前,需要对图像进行高斯平滑,减少噪声对求导操作的影响。
高斯平滑是数字图像处理中比较基础的算法,这里暂时不作介绍。
2. 计算梯度信息
数字图像的一阶导数是灰度值分别在x,y方向上的梯度近似值。图像像素f(x,y)在位置(x,y)处的梯度定义向量:
梯度向量指向在坐标(x,y)处 f 的最大变化率方向。
其大小为:
方向为:
在计算图像梯度时,我们使用常用的Sobel梯度算子,其通过增加中心点的重要性实现了某种程度的平滑效果。Sobel算子模版如下图所示(引用自《数字图像处理》):
上图(f)为求图像x方向的导数,图(g)求导y方向。分别使用上述的Sobel两个方向算子对图像进行处理,可以得到如下图效果。图(a)为原图,图(b)和图©分别是使用x、y方向对图进行卷积处理,得到的结果。可以看到,图(b)主要保留了图像中横向的边缘,而图©则更多地保留了竖直方向的边缘。图(d)展示的是同时使用两个算子对原图进行处理,可以看到保留了图像中大量的边缘信息。从图(d)可以看出,如果直接使用梯度算子对图像进行处理,得到的结果将保留许多我们不需要的边缘点。由于我们对图像进行边缘检测时,更希望提取图像中比较突出的边缘,因此,我们对图像进行模糊处理去除噪声影响的同时,能够去除不明显边界点的影响。
3. 非极大值抑制
由于边缘附近的梯度值都会较大,因此仅用梯度算子对图像进行处理后,边缘会有一定的宽度。如下图,白色像素为边缘,但是由于在边缘处都有较大的梯度值,所以利用梯度算子计算后,这些像素都被保留了下来。在实际应用中,我们更希望得到更精准的边缘位置(即让计算得到的边缘更细)。这里就需要用到非极大值抑制的方法。
由上图可以观察到,其实边缘的宽度方向是和边缘的梯度方向一致的(与边缘前进方向垂直)。因此,可以利用在梯度方向上寻找极大值处像素进行保留作为边缘的精确位置。
在上述计算梯度信息的过程中,我们获得了图像梯度大小和方向信息,而在梯度的方向上我们能得到梯度的局部极大值。如下图点c,蓝色线方向为该点梯度方向,如果点c处的梯度值比dTmp1和dTmp2点处梯度值小的话,那么它就会被排除,不作为边缘点。此处计算dTmp1和dTmp2点处梯度值需要利用g1,g2,g3,g4点进行线性插值得到。
对梯度图像进行非极大值抑制以后,我们将得到更细的边缘图(理论上我们会得到只有一个像素宽度的边缘)。这样就可以进行下一个步骤–双阈值算法。
4. 双阈值算法
对梯度图像进行非极大值抑制以后,我们保留了图像局部梯度极大值处的像素,接下来我们能想到应该用一个阈值去筛选真实的边缘点,即保留较大的梯度值处的像素。但是这种做法会导致某些边缘存在断裂的情况。如下图,一条边缘可能存在梯度大小不同的线段(在图中用较粗的部分表示梯度较大的边缘),如果阈值选择不准确会导致边缘断裂。
双阈值算法的思想就是:通过高阈值开始搜索边缘,利用低阈值延长边缘点。具体的做法是,设置一个高阈值h和一个低阈值l,然后分情况讨论:
如果像素梯度大于h,保留。如果像素梯度小于l,删除。如果像素梯度介于l和h之间,则判断该处像素8领域内像素梯度是否存在高于阈值h的点,如果存在,保留。
至此,Canny边缘检测算法就算完成了。值得一提的是,虽然当前计算机视觉和图像处理领域深度学习的方法(特别是卷积神经网络)得到了很好的发展,也得到了较为显著的成果。但是上个世纪八十年代出现的Canny边缘检测算法在今天仍然被广泛使用,且发挥着重要作用。而且,各种经典的数字图像处理传统算法,其中都存在了大量基础的、值得斟酌的技巧和方法。因此希望我们在学习深度学习这种热门方法的同时,不要忽视了对计算机视觉和数字图像处理传统方法的学习和应用。
本文仅作为学习笔记交流分享用。由于本人水平有限,文章可能出现纰漏,欢迎大家进行交流指正。谢谢阅读!
如果觉得《【图像处理算法】Canny边缘检测》对你有帮助,请点赞、收藏,并留下你的观点哦!