霍夫变换:将极坐标转换回笛卡尔坐标,但仍然无法绘制它们

Hough Transform: Converted polar coordinates back to Cartesian, but still can't plot them

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

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

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 值现在都是正的。

如果你回忆一下 Hough 的参数化 space,rhothetax,y 之间的直接关系是:

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

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

的直线方程式

因此,只需遍历每个 rhotheta 并画一条线,从 x = 0 的原点开始,直到图像的极限 x = width-1.但是,因为 MATLAB 是 1 索引的,我们需要从 x = 1x = 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

上面的代码很简单。首先,使用 imshow in MATLAB. Next, use hold on so we can draw our lines in the image that will go on top of the image. Next, we calculate how many rho,theta pairs there are, and then we define the two x coordinates to be 1 and width as we will use these to determine where the starting and ending y coordinates are, given these x coordinates. Next, for each rho,theta pair we have, determine the corresponding y coordinates, then use line 从起点和终点 (x,y) 坐标以蓝色绘制一条线来显示图像。我们重复此操作,直到 运行 超出行数。

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

theta = 0

假设您在 Hough 变换中没有检测到垂直线,或者当 theta = 0 时,上面的代码是有效的。如果 theta = 0(就像你的情况),这意味着我们有一条 垂直 线,因此会产生无限斜率,我们的 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) 的底部。因此,上面的代码现在应该可以正确处理任何直线,以及斜率无限大的退化情况。因此,第二个版本的代码就是您所需要的。


祝你好运!