4

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

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

谢谢,本

4

3 回答 3

7

高斯分布

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

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

因此可以分解为一维分布的乘法。因此可以先在 x 方向(独立于每一行)然后在 y 方向(独立于每一列)进行过滤

圆角

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

同样取决于平台,最好完全避免使用 arctan:您可以画一个圆,将其划分为 4 个区域,并为仅使用算术运算的梯度分量生成一组条件,并为您提供区域方向的答案。

于 2009-09-08T04:49:33.820 回答
1

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

如果你是为了教育目的,我建议考虑购买一本关于计算机视觉的好书。几乎所有的介绍性文本都会讨论高斯滤波(以及有据可查的一维技巧)以及精明的边缘检测和非极大值抑制。

于 2009-09-08T16:43:36.983 回答
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;
}
于 2012-10-03T03:52:17.707 回答