【问题标题】:Hough Transform: Converted polar coordinates back to Cartesian, but still can't plot them霍夫变换:将极坐标转换回笛卡尔坐标,但仍无法绘制它们
【发布时间】:2015-02-05 18:52:48
【问题描述】:

所以我已经自己实现了霍夫变换的每个部分,除了实际将线条重新绘制到原始图像上。

我可以像这样设置我的数据数组。

points | theta | rho
-------|-------|----
[246,0]   -90    -246
[128,0]   -90    -128
[9,0]     -90     -9
[0,9]      0      9     
[0,128]    0     128
[0,246]    0     246 

这些点是从极坐标中的峰转换而来的点。所以现在我需要画出所有这六条线,但我没有运气。

编辑


所以我尝试根据建议更改我的代码。这就是我想出的。

function help(img, outfile, peaks, rho, theta)
    imshow(img);
    x0 = 1;
    xend = size(img,2); 
    peaks_len=length(peaks);
    for i=1:peaks_len
        peak=peaks(i,:);
        r_ind=peak(1);
        t_ind=peak(2);
        r=rho(r_ind);
        th=theta(t_ind);
        %display([r,th,peak]);

        %// if a vertical line, then draw a vertical line centered at x = r
%         display([r, th]);

        if (th == 0)
            display('th=0');
            display([1, size(img,1)]);
            line([r r], [1 size(img,1)], 'Color', 'green');
        else
            %// Compute starting y coordinate
            y0 = abs((-cosd(th)/sind(th))*x0 + (r / sind(th)))+11;%-25; 

            %// Compute ending y coordinate
            yend = abs((-cosd(th)/sind(th))*xend + (r / sind(th)))+11;%-25;
            display('y');
            display([y0, yend]);
            display('x');
            display([x0 xend]);
             %// Draw the line
            line([x0 xend], [y0 yend], 'Color', 'green');
        end
    end
end

我不得不从r==0 更改为th==0,因为当r 不为0 时th=0 会给出NAN 错误。

根据峰值,然后我用它来获取我需要的数据,然后计算一些值......但由于某种原因,这不能很好地绘制。

如果您注意到两个 y 值的 + 11。我必须这样做才能让线路到达他们需要的地方。我感觉还有什么地方出了问题。

我确实改变了它,所以我的 Rho 值现在都是正数。

【问题讨论】:

  • 您没有正确使用abs。我的意思是在积累阶段,而不是绘图阶段。画线时不要使用abs。在转换阶段计算rho 时,取那里的绝对值。你好像误会了我的意思。
  • 我实际上完全改变了我的 rho,所以没有负面影响。
  • 没关系。画线时不要使用abs。它们不会出现在图像上,因为从技术上讲它们会超出范围。
  • 这里的 matlab 似乎将 y 值向下计数。所以没有腹肌,什么都没有。
  • 当你显示图像时是的。另外,我假设这是您在计算转换时使用的约定。 TBH 我真的不知道你是怎么做到的。不管怎样,祝你好运!

标签: matlab image-processing hough-transform


【解决方案1】:

如果你回忆一下霍夫空间的参数化,rho,thetax,y 之间的直接关系是:

rho = x*cos(theta) + y*sin(theta)

请记住,x,y 分别代表 位置。此外,原点定义在图像的左上角。现在您要绘制直线方程,您有rhotheta。只需重新排列方程,即可求解y = mx + b 形式的直线方程:

因此,只需遍历您拥有的每个rhotheta 并画一条线,从x = 0 的原点开始直到图像的限制x = width-1。但是,由于 MATLAB 是 1-indexed,我们需要从 x = 1 转到 x = width。假设您的 rhotheta 存储在相同长度的单独数组中,并且您的边缘图像存储在 im 中,您可以执行以下操作:

imshow(im); %// Show the image
hold on; %// Hold so we can draw lines
numLines = numel(rho); %// or numel(theta);

%// These are constant and never change
x0 = 1;
xend = size(im,2); %// Get the width of the image

%// For each rho,theta pair...
for idx = 1 : numLines
    r = rho(idx); th = theta(idx); %// Get rho and theta
    %// Compute starting y coordinate
    y0 = (-cosd(th)/sind(th))*x0 + (r / sind(th)); %// Note theta in degrees to respect your convention

    %// Compute ending y coordinate
    yend = (-cosd(th)/sind(th))*xend + (r / sind(th));

    %// Draw the line
    line([x0 xend], [y0 yend], 'Color', 'blue');
end

上面的代码很简单。首先,在 MATLAB 中使用imshow 显示图像。接下来,使用hold on,这样我们就可以在图像中绘制我们的线条,这些线条将在图像的顶部。接下来,我们计算有多少 rho,theta 对,然后我们将两个 x 坐标定义为 1 和 width,因为我们将使用它们来确定开始和结束 y 坐标的位置,给定这些x 坐标。接下来,对于我们拥有的每个rho,theta 对,确定对应的y 坐标,然后使用line 在蓝色的(x,y) 坐标的起点和终点画一条线。我们重复这个直到我们用完线。

如果生成的y 坐标超出图像范围,请不要惊慌。 line 将足够聪明,可以简单地限制结果。

theta = 0

上面的代码工作假设你在霍夫变换中没有检测到垂直线,或者当theta = 0。如果theta = 0(如您的情况),这意味着我们有一条 vertical 线,因此会产生无限斜率,并且我们的y = mx + b 公式无效。应theta = 0,直线方程变为x = rho。因此,您需要在循环中添加一个额外的 if 语句来检测这一点:

imshow(im); %// Show the image
hold on; %// Hold so we can draw lines
numLines = numel(rho); %// or numel(theta);

%// These are constant and never change
x0 = 1;
xend = size(im,2); %// Get the width of the image

%// For each rho,theta pair...
for idx = 1 : numLines
    r = rho(idx); th = theta(idx); %// Get rho and theta

    %// if a vertical line, then draw a vertical line centered at x = r
    if (th == 0)
        line([r r], [1 size(im,1)], 'Color', 'blue');
    else
        %// Compute starting y coordinate
        y0 = (-cosd(th)/sind(th))*x0 + (r / sind(th)); %// Note theta in degrees to respect your convention

        %// Compute ending y coordinate
        yend = (-cosd(th)/sind(th))*xend + (r / sind(th));

        %// Draw the line
        line([x0 xend], [y0 yend], 'Color', 'blue');
   end
end

为了画垂直线,我需要知道图像有多,以便我们可以从图像顶部(y = 1)向下画一条垂直线到底部锚定在x = rho 的图像(y = height)。因此,上面的代码现在应该正确处理任何线,以及斜率无限时的退化情况。因此,第二个版本的代码就是您所追求的。


祝你好运!

【讨论】:

  • 那么第二种情况应该适用于所有行,垂直、水平和其他?
  • @ChrisJones - 是的!请记住,这不能处理负面的rho,因为我假设您的霍夫空间的原点位于图像的左上角......所以您将无法想象这些。
  • 正如你所看到的,图像有负 rhos。我也放了一些错误的角度。虽然这确实适用于非垂直线。
  • @ChrisJones - 你是如何得到否定的rho 的?仅当您的原点不在左上角时才会发生这种情况。如果您的来源定义明确,则不可能使用负 rho
  • @ChrisJones - 考虑通过在累加器空间中计算 rho 的绝对值来使 rho 严格为正。查看 Wiki 文章了解其含义:en.wikipedia.org/wiki/Hough_transform#Theory
猜你喜欢
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 2016-04-14
  • 1970-01-01
  • 2013-08-05
相关资源
最近更新 更多