2013-10-12 49 views
1

我想实现Canny边缘检测算法,并且我遇到了一些问题。我认为我理解Canny边缘检测的每一步,但与OpenCv实现的结果相比,它们差异很大。Canny边缘检测算法 - 实现问题

看来,我不能像算法应该产生的1px宽边缘。以下是这个非常简单的二进制图象的步骤和结果:正被处理

二值图像:

Binary Image that is being processed

梯度幅值来计算使用Sobel算子:

Gradient magnitudes

边缘方向:

1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 <br> 
1/- - - - - - - - - - - \ 1 <br> 
1 |/- - - - - - - - - \ | 1 <br> 
1 | |/- - - - - - - \ | | 1 <br> 
1 | | |/- - - - - \ | | | 1 <br> 
1 | | | | | | | | | | | | | 1 <br> 
1 | | | | | | | | | | | | | 1 <br> 
1 | | | | | | | | | | | | | 1 <br> 
1 | | | | | | | | | | | | | 1 <br> 
1 | | | | | | | | | | | | | 1 <br> 
1 | | | \ - - - - -/| | | 1 <br> 
1 | | \ - - - - - - -/| | 1 <br> 
1 | \ - - - - - - - - -/| 1 <br> 
1 \ - - - - - - - - - - -/1 <br> 
1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 

非最大值抑制后的图像:

0 0 0 0 0 0 0 0 0 0 0 0 0 0 0<br> 
0 0 0 0 0 0 0 0 0 0 0 0 0 0 0<br> 
0 0 255 0 0 0 0 0 0 0 0 0 255 0 0<br> 
0 0 0 0 0 0 0 0 0 0 0 0 0 0 0<br> 
0 0 0 0 255 0 0 0 0 0 255 0 0 0 0<br> 
0 0 0 0 0 0 0 0 0 0 0 0 0 0 0<br> 
0 0 0 0 0 0 0 0 0 0 0 0 0 0 0<br> 
0 0 0 0 0 0 0 0 0 0 0 0 0 0 0<br> 
0 0 0 0 0 0 0 0 0 0 0 0 0 0 0<br> 
0 0 0 0 0 0 0 0 0 0 0 0 0 0 0<br> 
0 0 0 0 255 0 0 0 0 0 255 0 0 0 0<br> 
0 0 0 0 0 0 0 0 0 0 0 0 0 0 0<br> 
0 0 255 0 0 0 0 0 0 0 0 0 255 0 0<br> 
0 0 0 0 0 0 0 0 0 0 0 0 0 0 0<br> 
0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 

如果我在这个步骤执行滞后阈值,我得到很厚边的结果。显而易见的问题是梯度幅度值,但我不知道如何解决它。如果有人更有经验和知识渊博,善意地指点我正确的方向,我会非常感激。

回答

2

我不认为索贝尔操作员是适合您的情况。实际上梯度大小应该粗略地勾画边缘。后面的步骤是提炼边缘提取。我不知道你是如何实现细化过程的,我所做的是使用插值来找到梯度的标准是局部最大值的像素。当我申请Sobel算子,我没有得到很厚的边缘,但边缘不是很连续在某些点:

0  0  0  0  0  0  0  0  0  0  0  0  0  0  0  0 
0  0  0  0  0  0  0  0  0  0  0  0  0  0  0  0 
0  0  0  0 270 270 270 270 270 270 270 270  0  0  0  0 
0  0  0 270  0  0  0  0  0  0 270 270  0  0  0  0 
0  0 270  0  0  0  0  0  0  0  0  0  0  0 270  0 
0  0 270  0  0 270 270 270 270  0  0 270  0  0 270  0 
0  0 270  0  0 270  0  0  0  0  0 270  0  0 270  0 
0  0 270  0  0 270  0  0  0  0  0 270  0  0 270  0 
0  0 270  0  0 270  0  0  0  0  0 270  0  0 270  0 
0  0 270  0  0  0  0  0  0  0  0 270  0  0 270  0 
0  0 270 270  0  0  0  0  0  0  0 270  0  0 270  0 
0  0 270 270  0 270 270 270 270 270 270 270  0  0 270  0 
0  0  0  0  0  0  0  0  0  0  0  0  0 270 270  0 
0  0  0  0  0  0  0  0  0  0  0  0 270 270  0  0 
0  0  0  0 270 270 270 270 270 270 270 270 270  0  0  0 
0  0  0  0  0  0  0  0  0  0  0  0  0  0  0  0 

当我使用高斯函数的标准偏差卷积原始图像,以得到渐变,我终于可以弄清楚清晰的边缘:

0  0  0  0  0  0  0  0  0  0  0  0  0  0 
0  1 494 494 494 494 494 494 494 494 494 494  1  1 
0 494  1  1  1  1  1  1  1  1  1  1 494  1 
0 494  1  1 494 494 494 494 494 494  1  1 494  1 
0 494  1 494 494  1  1  1  1 494 494  1 494  1 
0 494  1 494  1  1  1  1  1  1 494  1 494  1 
0 494  1 494  1  1  1  1  1  1 494  1 494  1 
0 494  1 494  1  1  1  1  1  1 494  1 494  1 
0 494  1 494  1  1  1  1  1  1 494  1 494  1 
0 494  1 494 494  1  1  1  1 494 494  1 494  1 
0 494  1  1 494 494 494 494 494 494  1  1 494  1 
0 494  1  1  1  1  1  1  1  1  1  1 494  1 
0  1 494 494 494 494 494 494 494 494 494 494  1  1 
0  1  1  1  1  1  1  1  1  1  1  1  1  1