【问题标题】:Canny Edge Detector in CC 语言中的 Canny 边缘检测器
【发布时间】:2010-11-26 09:15:40
【问题描述】:
我正在寻找有关 Canny 边缘检测 - Wikipedia entry - 中实现的算法如何工作的一些说明。使用 2D 高斯滤波器执行降噪似乎很简单,但我听说使用两个 1D 滤波器 - 这是如何实现的?计算梯度和边缘方向也很简单。但是,在执行非最大抑制时,是否有一个巧妙的技巧来获得圆角?我目前正在做的是将边缘方向(theta)值除以 pi/4,将其转换为整数并使用 switch 语句。但是,如何处理负 theta 值 - 即 -pi/4 应该以与 3*pi/4 或 pi/4 相同的方式处理吗?
非常感谢任何建议/链接!
谢谢,
本
【问题讨论】:
标签:
c++
c
algorithm
image-processing
edge-detection
【解决方案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;
}
【解决方案3】:
高斯分布:
[为简单起见省略了常量]
g2d(x,y)=exp(-xxyy)=exp(-x^2) * exp(-y^2)=g1d(x) * g1d(y)
因此可以分成一维分布的乘法。因此可以先在 x 方向(独立于每一行)进行过滤,然后在 y 方向(独立于每一列)进行过滤
圆角:
如果角度在 [0..pi) 之外,在这种情况下,可以根据需要多次加/减 pi(或使用函数 fmod),并且对于 [0..pi),一切都清楚了。
还取决于平台,最好完全避免使用 arctan:您可以画一个圆,将其划分为 4 个区域,并为仅使用算术运算的梯度分量生成一组条件,并在哪个区域给出答案方向是。