如何实现基于梯度的霍夫变换


9

我正在尝试使用霍夫变换进行边缘检测,并希望使用渐变图像作为基础。

我迄今所做,给出的图像I尺寸的[M,N]和它的部分衍生物gxgy是计算中的每个像素作为梯度角thetas = atan(gy(x,y) ./ gx。同样,我将梯度幅度计算为magnitudes = sqrt(gx.^2+gy.^2)

要构建霍夫变换,我使用以下MATLAB代码:

max_rho = ceil(sqrt(M^2 + N^2));
hough = zeros(2*max_rho, 101);
for x=1:M
    for y=1:N
        theta = thetas(x,y);
        rho = x*cos(theta) + y*sin(theta);

        rho_idx = round(rho)+max_rho;
        theta_idx = floor((theta + pi/2) / pi * 100) + 1;
        hough(rho_idx, theta_idx) = hough(rho_idx, theta_idx) + magnitudes(x,y);
    end
end

产生的霍夫变换看起来似乎是合理的(请参阅http://i.stack.imgur.com/hC9mP.png),但是当我尝试将其最大值用作原始图像中的边缘参数时,结果看起来或多或少是随机的。在构造霍夫变换时我做错了什么吗?

更新:我的代码中有一个愚蠢的错误:rho计算为x*cos(theta)+y*cos(theta)而不是x*cos(theta)+y*sin(theta)。也就是说,我使用两个余弦而不是一个余弦和一个正弦。我已经在上面编辑了代码,下面是新生成的图像。但是,这并没有提供更好的优势。

@endolith:要绘制的边缘,考虑到极大值hough在-矩阵rho_idx, theta_idx,我的指标转化为rho,theta数值:

theta = (theta_idx -1) / 100 * pi - pi / 2;
rho = rho_idx - max_rho;

最后,我将边缘绘制为y= (rho - x*cos(theta)) / sin(theta)

新结果


“当我尝试将其最大值用作原始图像中的边缘参数时”您如何做?
endlith 2011年

@Jonas Due Vesterheden只是想知道这是时间VS多普勒频率图像吗?...
Spacey

@穆罕默德:我不知道。原始图像是某些电路板。“ VS”是什么意思?
乔纳斯·杜伊·维斯特海登2011年

@JonasDueVesterheden'VS'的意思是'versus'。(时间与多普勒频率”):-)
太空

您应先对hough贴图进行平滑处理,然后再应用Non max抑制。

Answers:


2

你的问题让我有些困惑。霍夫变换用于检测线,而不是边缘。

如果只需要一张边缘贴图,则应简单地设定梯度幅度的阈值,或使用像Canny边缘检测器这样的更精美的东西。

如果要检测直线,最好从边缘贴图开始hough,如果可以访问图像处理工具箱,则最好使用该功能。对梯度进行霍夫变换的问题在于,形成直线的边缘像素可能具有相反的梯度方向。例如,考虑一个棋盘图案。两行正方形之间的边缘会翻转方向,具体取决于您上方是黑色正方形,下方是白色正方形,还是相反。

关于您的实现,我认为问题在于霍夫矩阵中的垃圾箱太小。本质上,rho维度上的bin大小为1,theta维度上的bin大小小于2度。这意味着梯度方向必须非常精确地下降才能形成一条线,这在实践中很少发生。如果将rho_idx和theta_idx计算为更大的bin,则将使行检测器更能容忍错误,并且可以获得更好的行。


1

我不知道这是否是一个问题,但由于象限的不确定性,atan()仅给您从-90到+90度的角度。要获得完整的倾斜角度(从-180到180),您需要使用atan2()。


谢谢你的建议!据我了解,使用-90至+90度的角度就足够了,因为边缘的“方向”无关紧要。我尝试使用atan2,但似乎无法解决问题。
乔纳斯·杜伊·维斯特海登2011年
By using our site, you acknowledge that you have read and understand our Cookie Policy and Privacy Policy.
Licensed under cc by-sa 3.0 with attribution required.