OpenCV边缘检测算法数学原理
边缘是指图像中灰度发生急剧变化的区域。两个具有不同灰度值的相邻区域之间总存在着边缘,这是灰度值不连续的结果。这种不连续通常可以利用求导的方法检测到,一般常用一阶、二阶和一二阶混合导数来检测边缘。边缘检测的数学原理需要一些基础数学知识。
OpenCV内置边缘检测算法
Sobel算子
Sobel算子的原理可参照此篇文章:关于Sobel核的一般数学推导
Scharr算子
Scharr算子卷积核为:
Sobel接口(将ksize=1)和Scharr接口两种调用方式,为语义清晰,推荐后一种方式。Laplacian算子
Laplacian边缘检测算法是二阶算法,表达式为
Canny算子
Canny边缘检测算法包含以下五个主要步骤,具有检测率高、定位准确、一次响应三个特点。
噪声抑制
Canny算法第一步是使用高斯滤波来去除图像中的噪声。设原图像为,矩阵为
。高斯滤波的核矩阵为
,则第一步得出图像与高斯滤波的卷积
。需要注意的是,此步并未包含在OpenCV中的
Canny接口中,需要自行调用接口。当然,这也意味着此步可以根据具体条件使用除了高斯滤波之外的其他滤波方法。本文中仅考虑线性滤波的情况,非线性滤波不适用于该表达(读者可自行推导)。
计算梯度
使用Sobel算子,得到
方向和
方向的
,则梯度为
非极大值抑制
非极大值抑制(Non-Maximum Suppression, NMS)是使边缘细化为单像素宽度的关键步骤,目的是消除在梯度方向上不是真正边缘的像素,从而得到更加精确的边界定位。NMS步骤:
- 对每个像素点,沿梯度方向
,找出前后相邻的两个像素的幅值
和当前像素点幅值
- 如果当前点的幅值不是该方向上的最大值(
),则将其抑制(设为0)
方向角取值为
的整数倍,通常近似取
。如计算出的梯度方向角
,由于离
更近,则近似取
。需要注意的是,关于幅度的计算,若
双阈值检测
定义两个阈值,将幅值与两个阈值对比,根据对比情况依次分为强边缘、弱边缘和非边缘。我们保留强边缘,滞后处理弱边缘,抑制非边缘。具体为
- 强边缘:
- 弱边缘:
- 非边缘:
边缘连接
对于上一步的弱边缘,判断其是否与强边缘连接。如果是,则保留;否则抑制。此步从所有强边缘像素点出发,使用广度优先搜索(BFS)算法,将所有相连的弱边缘像素点转换为强边缘像素点。其余未被搜索到的弱边缘点被抑制。
Canny算法对真实边缘进行细化,较好的排除了非边缘的影响(如色彩渐变)。
其他边缘检测算法
差分边缘检测
差分边缘检测是最基础的边缘检测算法。差分边缘检测算法原理是:将图像的相邻像素点进行差分,得到像素点的梯度,然后根据梯度的大小来判断像素点是否为边缘点。差分边缘检测在方向上的一阶差分定义为
,算子定义为
Roberts算子
Roberts边缘检测算法又称为交叉微分算法,是基于交叉微分的梯度算法。Roberts算子的核模板为
Prewitt算子
上述两种算子由于每次只关注了两个像素,因此容易受到噪声干扰。Prewitt每次基于边缘的6个像素的平均值来计算梯度,因此可以减少噪声,但同时对边缘的定位不如上两个算法。核模板为
LoG算子
LoG(Laplacian-of-Gaussian)边缘检测算法首先对图像进行高斯滤波,然后求其拉普拉斯二阶导数,即图像与Laplacian of Gaussian方法进行滤波运算。最后通过检测滤波结果的零交叉以获得图像或物体的边缘。
滤波
LoG算法第一步是使用高斯滤波来去除图像中的噪声。设原图像为,矩阵为
。高斯滤波的核矩阵为
,则第一步得出图像与高斯滤波的卷积
。这里跟Canny算法第一步是相似的,不同之处在于Canny滤波可以使用其他滤波方法,这里由于算法本身的定义,只采用高斯滤波。
增强
对上一步处理后的平滑图像进行Laplacian运算,即。对平滑图像进行Laplacian运算可等效为先对高斯滤波卷积核进行Laplacian运算,再与
卷积,即
。其中
称为LoG滤波器,表达式为
关于的证明:首先考虑一维可导函数
,我们有函数的卷积的导数等于一个函数与另一个函数的导数的卷积,即
。证明如下:
- 先对图像进行高斯平滑,在使用拉普拉斯对图像进行卷积运算;
- 先得到LoG(高斯的拉普拉斯变换)的卷积核,再对图像进行卷积运算。
这两种方式在数学上是等价的。
检测
我们通过检测的点来作为边缘点。
LoG算法和Canny算法的比较
LoG算法由于直接求Laplacian算子,也就是二阶导,因此相较于Canny算法少了双阈值检测和边缘连接两步,因此在实际应用中,LoG算法可能不如Canny算法。
