您的位置:首页 > 编程语言 > C语言/C++

Canny边缘检测基本原理与C++实现

2010-05-19 15:51 381 查看
最优的阶梯型边缘检测算法(canny边缘检测)
 
1.Canny边缘检测基本原理
(1)图象边缘检测必须满足两个条件:一能有效地抑制噪声;二必须尽量精确确定边缘的位置。
(2)根据对信噪比与定位乘积进行测度,得到最优化逼近算子。这就是Canny边缘检测算子。
(3)类似与Marr(LoG)边缘检测方法,也属于先平滑后求导数的方法。
 
2.Canny边缘检测算法:
step1:用高斯滤波器平滑图象;



step2:用一阶偏导的有限差分来计算梯度的幅值和方向;
 


 
 
step3:对梯度幅值进行非极大值抑制(这个就不是很明白!!!)
 



将梯度角离散为圆周的四个扇区之一,以便3 * 3的窗口作抑制运算。
四个扇区的标号为0到3,对应3*3邻域的四种可能组合。
在每一点上,邻域的中心象素M[x, y]与沿着梯度线的两个象素相比。如果M[x, y]的梯度值不比沿梯度线的两个相邻象素梯度值大,则令M[x, y] = 0。
即: 


 
step4:用双阈值算法检测和连接边缘。
解析1:
对非极大值抑制图像作用两个阈值th1和th2,两者关系th1=0.4th2。我们把梯度值小于th1的像素的灰度值设为0,得到图像1。然后把梯度值小于th2的像素的灰度值设为0,得到图像2。由于图像2的阈值较高,去除大部分噪音,但同时也损失了有用的边缘信息。而图像1的阈值较低,保留了较多的信息,我们可以以图像2为基础,以图像1为补充来连结图像的边缘。
链接边缘的具体步骤如下:
对图像2进行扫描,当遇到一个非零灰度的像素p(x,y)时,跟踪以p(x,y)为开始点的轮廓线,直到轮廓线的终点q(x,y)。
考察图像1中与图像2中q(x,y)点位置对应的点s(x,y)的8邻近区域。如果在s(x,y)点的8邻近区域中有非零像素s(x,y)存在,则将其包括到图像2中,作为r(x,y)点。从r(x,y)开始,重复第一步,直到我们在图像1和图像2中都无法继续为止。
当完成对包含p(x,y)的轮廓线的连结之后,将这条轮廓线标记为已经访问。回到第一步,寻找下一条轮廓线。重复第一步、第二步、第三步,直到图像2中找不到新轮廓线为止。
至此,完成canny算子的边缘检测。
 
解析2
减少假边缘段数量的典型方法是对N[i,j]使用一个阈值。将低于阈值的所有值赋零值。但问题是如何选取阈值?
解决方法:双阈值算法。双阈值算法对非极大值抑制图象作用两个阈值τ1和τ2,且2τ1≈τ2,从而可以得到两个阈值边缘图象N1[i,j]和 N2[i,j]。由于N2[i,j]使用高阈值得到,因而含有很少的假边缘,但有间断(不闭合)。双阈值法要在N2[i,j]中把边缘连接成轮廓,当到达轮廓的端点时,该算法就在N1[i,j]的8邻点位置寻找可以连接到轮廓上的边缘,这样,算法不断地在N1[i,j]中收集边缘,直到将N2[i,j]连接起来为止。
 
http://hi.baidu.com/liujianz/blog/item/1d8cf65191188b2142a75bd2.html
http://hi.baidu.com/lipiji1986/blog/item/adf6df1ae35302fdaf513303.html
http://zh.wikipedia.org/zh-cn/Canny%E7%AE%97%E5%AD%90
 
代码:
网上有这样的一个工程, 找一下把。
 
 
 
 
 
 
 
 
 
 
 
 
 
内容来自用户分享和网络整理,不保证内容的准确性,如有侵权内容,可联系管理员处理 点击这里给我发消息
标签:  c++ 算法 n2 优化