A
http://www.cnblogs.com/cfantaisie/archive/2011/06/05/2073168.html
1.Canny边缘检测基本原理
对非极大值抑制图像作用两个阈值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算子的边缘检测。
B http://hi.baidu.com/gabe2008/item/082c25d411db2493260ae788
传统Canny 算法采用双阈值法从候选边缘点中检测和连接出最终的边缘, 双阈值法首先选取高阈值 Th 和低阈值 Tl ,然后开始扫描图像, 对候选边缘图像 N 中标记为候选边缘点的任一像素点( i , j )进行检测,若点( i , j ) 梯度幅值 G ( i ,j)高于高阈值 Th ,则认为该点一定是边缘点,若点( i , j)梯度幅值 G( i , j)低于低阈值 Tl ,则认为该点一定不是边缘点, 而对于梯度幅值处于两个阈值之间的像素点,则将其看作疑似边缘点 ,再进一步依据边缘的连通性对其进行判断,若该像素点的邻接像素中有边缘点,则认为该点也为边缘点,否则,认为该点为非边缘点。
我的感悟:
1.先用高阈值求边缘。canny求得的边缘希望是连在一起的(通常是封闭的),但高阈值求的边缘一般断断续续。断开的地方如果低阈值求的边缘存在,就用低阈值的边缘接上去,目的让边缘尽量都连在一起。其它情况下低阈值的边缘是不用的。
2.两个阈值是有区别的,高的那个阈值是将要提取轮廓的物体与背景区分开来,就像阈值分割的那个参数一样,是决定目标与背景对比度的,低的那个阈值是用来平滑边缘的轮廓,有时高的阈值设置太大了,可能边缘轮廓不连续或者不够平滑,通过低阈值来平滑轮廓线,或者使不连续的部分连接起来
3.如果是都是强边界,低阈值几乎不发挥作用。
4.高阈值已经出现了图像中1/3的轮廓,低阈值对它的影响最大,从最小的0到高阈值之间,边缘差异非常大。
C 关于cvCanny()
void cvCanny( const CvArr* image, CvArr* edges, double threshold1, double threshold2, int aperture_size=3 ); image单通道输入图像.edges单通道存储边缘的输出图像threshold1第一个阈值threshold2第二个阈值aperture_sizeSobel 算子内核大小 (见 cvSobel).
函数 cvCanny 采用 CANNY 算法发现输入图像的边缘而且在输出图像中标识这些边缘。threshold1和threshold2 当中的小阈值用来控制边缘连接,大的阈值用来控制强边缘的初始分割。
- 注意事项:cvCanny只接受单通道图像作为输入。
- 外部链接:经典的canny自调整阈值算法的一个opencv的实现见在OpenCV中自适应确定canny算法的分割门限