distance(g1,g2) 表示两点之间的距离。实际上w是一个比例系数,这个比例系数可以通过梯度方向(幅角的正切和余切)得到。
右边图中的4个直线就是4个不同的情况,情况不同,g1、g2、g3、g4代表c的八领域中的4个坐标会有所差异,但是线性插值的原理都是一致的。
代码如下:
5双阈值的选取。
双阈值的选取是按照直方图来选择的,首先把梯度幅值的直方图(扯点题外话:梯度的幅值直方图和角度直方图也是SIFT算子中的一个环节)求出来,选取占直方图总数%多少(自己定,代码中定义70%)所对应的梯度幅值为高阈值,高阈值的一半为低阈值,这只是一种简单策略。也可以采用其他的。
代码如下:
6 边缘检测,也即是根据步骤5得到的双阈值进行连接。
首先判断该点是否超过高阈值,然后判断该点的8邻域点中寻找满足超过低阈值的点,再根据此点收集新的边缘,直到整个图像边缘闭合。整个图像找完后,将非边缘点剔除,即灰度值置0.
代码如下:
其中,邻域跟踪算法给出了两个,一种是递归,一种是非递归。
递归算法。解决了堆栈溢出问题。之前找了很多canny代码参考,其中有一个版本流传很广,但是对于大图像堆栈溢出。
非递归算法。如下:
到此,整个算法写完了。打击下信心,整个算法跑起来没问题,但是没有opencv 的cvCanny 一个函数效果好。分析了下原因,一个是梯度算子选的太简单,opencv一般选用的是3*3 sobel。二是边缘连接性还是不够好,出现了很多断的,也就是邻域跟踪算法不够好。希望有高手能改进。
附上代码:
整篇博客参考过网上很多canny算法的总结,在此谢过!
本文来自电脑杂谈,转载请注明本文网址:
http://www.pc-fly.com/a/jisuanjixue/article-34002-3.html
猎潜小艇时到还打过几场家门口的海战
也要拿回来