C中的Canny边缘检测器

时间:2009-09-08 03:47:44

标签: c++ c algorithm image-processing edge-detection

我正在寻找关于如何在Canny边缘检测中实现算法的一些澄清 - Wikipedia entry - 工作。使用2D高斯滤波器进行降噪似乎非常简单,但我听说使用两个1D滤波器 - 这是如何实现的?计算梯度和边缘方向也很简单。然而,当执行非最大抑制时,有一个巧妙的技巧来获得圆角?我目前正在做的是将边缘方向(theta)值除以pi / 4,将其转换为整数并使用switch语句。但是,如何处理负θ值 - 即-pi / 4应该以与3 * pi / 4相同的方式处理,还是与pi / 4相同?

非常感谢任何建议/链接!

谢谢, 本

3 个答案:

答案 0 :(得分:7)

高斯分布

[为简单起见,省略了常量]

g2d(x,y)= exp(-x xy y)= exp(-x ^ 2)* exp(-y ^ 2)= g1d(x)* g1d(y)

因此可以分为1d分布的乘法。因此,可以首先在x方向上进行过滤(在每一行上独立),然后在y方向上进行过滤(在每一列上独立)

圆角

如果角度在[0..pi]之外,则在这种情况下根据需要添加/减去pi多次(或使用函数fmod)是正确的,而对于[0..pi),一切都是明确的。

同样取决于平台,最好避免使用arctan:你可以绘制一个圆,将其划分为4个区域,并为渐变组件生成一组条件,这些条件仅使用算术运算并给出答案在哪个区域方向是。

答案 1 :(得分:1)

您是否必须自己实施或者是否可以使用库? OpenCv是一个庞大的计算机视觉算法库,包括边缘检测:http://opencv.willowgarage.com/documentation/image_processing.html?highlight=canny#cvCanny

如果你是出于教育目的,我建议考虑购买一份关于计算机视觉的好文章。几乎任何介绍性文本都将讨论使用高斯(以及记录良好的1d技巧)以及精确边缘检测和非最大抑制进行过滤。

答案 2 :(得分:1)

我认为-pi / 4应该以与3 * pi / 4相同的方式处理,因为它们都定义了相同的对角线。

如果你可以标准化渐变的角度,使其位于[0,pi),那么你可以使用如下的简单函数来量化角度:

enum Angle
{
    HORIZONTAL,
    DIAG_UP,
    VERTICAL,
    DIAG_DOWN
};

Angle quantizeAngle(double theta)
{
    if (0 <= theta && theta < PI/8.0) || (7.0*PI/8.0 <= theta && theta < PI))
        return HORIZONTAL;
    else if (PI/8.0 <= theta && theta < 3.0*PI/8.0)
        return DIAG_UP;
    else if (3.0*PI/8.0 <= theta && theta < 5.0*PI/8.0)
        return VERTICAL;
    else 
        return DIAG_DOWN;
}