《A Sub-Pixel Edge Detector: an Implementation of the Canny/Devernay Algorithm》

来源:互联网 发布:淘宝茶具套装 编辑:程序博客网 时间:2024/05/22 02:30

论文《A Sub-Pixel Edge Detector: an Implementation of theCanny/Devernay Algorithm》提出了一种基于canny算法进行亚像素级边缘提取的算法,并给出了网页测试demo,可以在上面载入图像进行边缘提取测试,效果不错。这里简要翻译一下论文的方法:

Canny算法

针对边缘检测算法的研究有很多,其中Canny算法在这方面具有开创性的贡献,我在之前的博客里总结过canny的原理,这里简要说明一下:

Canny算子求边缘点具体算法步骤如下:
1. 用高斯滤波器平滑图像.
2. 计算梯度幅值和方向

3. 对梯度幅值进行非极大值抑制

非极大值抑制(Non-Maxima Suppression method)主要是为了更精确的定位某种特征,比如用梯度变化表征边缘时,梯度变化较大的区域通常比较宽,所以利用x和y方向的梯度确定一个法向arctan(y/x),然后在法向上判断当前梯度测量是否是一个峰值(或局部极大值),如果是就保留,不是极大值就抑制(如设置为0)。这样的话就能将边缘定位在1-2像素宽(相邻像素有时候求极大值的方向恰好互不干扰)。

4. 用双阈值算法检测和连接边缘.

5.通过滞后跟踪边缘,抑制所有弱而不强的边缘。

Devernay亚像素校正算法

Canny检测出的边缘是像素级别的,而有时需要精度低于一个像素,即亚像素边缘提取,Devernay【3】在Canny算法的基础上进行了拓展:将新的边缘点定义为相邻几个梯度模值差值的最大值,可以通过计算梯度方向上相邻的三点处的梯度模值的二次函数插补。如下图所示:


上图中,||g(A,B,C)||为三个垂直于边缘方向上的梯度模值,canny算法会选择模值最大的B点作为边缘点。但是,也可能在A和C之间存在点η ,在η 点处的梯度模值大于B点及AC之间的其他点,此时,η 点能更好地表示边缘。论文[3]给出了估计η 点以及计算η 点偏移量的方法,并给出η 的亚像素位置。

为了减少计算量,论文中只用了三点来进行二次方程拟合,并求出相对于BC向量的补偿 η :


Devernay亚像素算法准确性

影响Devernay算法准确性的四个误差来源:

1.假设梯度满足二次曲线规律带来的误差;

2.使用有限项计算梯度值带来的误差;

3.插补计算时有些点的梯度并没有通过canny运算计算出来所带来的误差;(个人理解这里应该是说在非水平和垂直方向上)

4.数据误差;

以高斯边缘为例,公式:,其中是高斯核函数,Y是阶梯函数,即:

   (1)

α 是阶梯函数的系数,下图中左是带亚像素偏移 γ 的高斯边缘特性,右图是使用抛物线估计的边缘点位置,例如途中三点abc,:(−1, a), (0, b) 和(1, c) ,边缘估计点的位置为:

          (2)

把带偏移 γ 的高斯边缘函数带入,可以得到:

   (3)

带入(2)式得到:

            (4)



右图中,高斯梯度与二次方程梯度极大值点偏差为:

 ,

文中给出了该误差的分布图5:


当γ=0时,误差为0,因为此时边缘在网格中间位置;当γ=0.5时,误差也为0,因为此时a=b或b=c,二次曲线插补值可以给出正确的偏移;σ越小,边缘越锐利,而σ越大,边缘越模糊,误差反而越小。

公式(4)也说明了第二种误差来源,即有限差分计算带来的误差。

亚像素边缘算法改进

在上面说的四种误差来源中,其中简单地使用水平和垂直方向插补可以有效去除第三种误差。Deverary使用三个点中间的插补值作为边缘, 这里进行修正:当点(x,y)处梯度满足以下条件,此时该点为水平方向的边缘点:


,


类似的,垂直方向的边缘点也是可以定义出来的。当x和y方向的梯度相等时,默认为还是水平边缘点,这个影响不大。修正方法的误差分布见下图6:


对比图5,修正方法的误差有了明显的减弱。另外,论文还对比了边缘是倾斜角度时的提取结果,见下图7:


边缘点链(Edge Point Chaining)

此前检测边缘点是一个独立过程,每个边缘点并不相关。后续需要将属于同一个边缘轮廓的点集归到一起--链,形成轮廓。每个边缘点对应的应是一个像素点,而不是一个5*5的区域。

首先,被归为同一链路的像素点应该具有近似的梯度方向,以像素点A和B为例,它们的夹角应小于90度,数学表示为:g(A).g(B)>0。 另外,图像轮廓可以将亮区域和暗区域分开,所以连续的链路需要将暗区域划分到曲线的同一侧,一个简单的方法是验证从边缘点A到点B的向量与点A两个可能的梯度方向中的一个是否近似正交。有两个概念需要介绍一下:前向链路(forward chaining)和后向链路(back chaining)。当 ,其中表示向量v旋转90度,此时成为A-B的前向链路,记为:,反方向称为反向链路。

一个边缘点至多有一个前向链路,也至多有一个后向链路,而不用有类似 Y 形状的链路。所以在确定AB是否成链前,需要检查A是否已经有前向链路和B是否已经有后向链路。此时可以通过距离来判断,如果新的链路比之前的距离短,那么之前链路就会被斩断,而增加这新的链路,经过这个步骤,边缘点的链接关系就能确定下来了。以下图8为例:


A,B,C,D四点的距离关系满足:||A-B||>||B-C||>||C-D||,假定链路搜索顺序为:A-B-C,你会发现当我们想时,存在,而且根据CB距离小于AB,所以会被切断;同样地,由于D的存在,也会被切断,所以最后的结果只剩下:。 再假定链路搜索顺序为C-B-A,经过判断过程,剩下这条链路。 所以,最后的链路结果为:

算法实现

Canny/Devernay算法主要分为四部分:图像求梯度,计算边缘点,边缘点链路编码,应用canny双阈值等方法,如下图9所示:


计算图像梯度的方法为算法2,如下图10所示,主要在水平和垂直两个方向上求取梯度:


求取边缘点及亚像素校正过程,算法3的伪代码如下图11所示:


可以发现,当某一点的水平方向和垂直方向梯度值相等时,该点可以被归为任意方向上的边缘,不影响结果。最后,边缘点链路编码过程算法4,如下图12所示:


算法4中的是指边缘点的邻域集合,取5*5,括号里的数字2应该是说邻域集中上下左右不超过2个像素,最后的边缘点取其邻域水平或垂直方向上的局部最大值。当然,过程中包含前向链路和后向链路,算是的子集。

最后,算法5描述了canny算法的应用,如下图13所示:


测试结果

算法中的输入参数除了被检测图像外,还有高斯函数的标准差S,canny算法的双阈值H和L,在线测试网址请点击


可见,当S取不同值是,边缘的粗细间隔是不一样的。S越大,边缘越粗些。



后记:第一次把英文文献翻译在CSDN上面,感慨大略看懂到能够翻译出来还是有一段距离的。

整个项目,我重新用opencv包装了,项目地址:https://github.com/fcqing/sub-pixel-edge-detect

参考

https://en.wikipedia.org/wiki/Canny_edge_detector

http://blog.csdn.net/qq_14845119/article/details/52064928

《A non-maxima suppression method for edge detection with sub-pixel accuracy》

http://ipolcore.ipol.im/demo/clientApp/demo.html?id=216

阅读全文
0 0