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

时间:2015-02-05 18:52:48

标签: matlab image-processing hough-transform

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

我可以设置我喜欢的数据数组。

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因为th=0在r不为0时会出现NAN错误。

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

如果您注意到两个y值均为+ 11。我必须这样做才能让线条成为他们需要的地方。我有一种感觉出现了其他问题。

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

1 个答案:

答案 0 :(得分:5)

如果你回忆起霍夫空间的参数化,rhothetax,y之间的直接关系是:

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

请注意,x,y分别代表位置。此外,原点定义在图像的左上角角落。现在您想要绘制线的等式,即可得到rhotheta。只需重新排列等式,以便您可以求解y = mx + b形式的线的等式:

因此,只需循环遍历您拥有的每个rhotheta,然后绘制一条从x = 0的原点开始直到图像限制的行x = width-1 。但是,由于MATLAB是1索引的,我们需要从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坐标的情况下,坐标是1}}。接下来,对于我们拥有的每个x对,确定相应的rho,theta坐标,然后使用line从蓝色的起始和结束y坐标绘制一条线。我们重复这个,直到我们用尽了。

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

何时line

上面的代码可以假设您在Hough变换中没有检测到垂直线,或者theta = 0时。如果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)锚定在y = height。因此,上面的代码现在应该正确处理任何行,以及当斜率无限时的退化情况。因此,代码的第二个版本就是你所追求的。


祝你好运!