所以我已经自己实现了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值现在都是正值。
答案 0 :(得分:5)
如果你回忆起霍夫空间的参数化,rho
,theta
到x,y
之间的直接关系是:
rho = x*cos(theta) + y*sin(theta)
请注意,x,y
分别代表列和行位置。此外,原点定义在图像的左上角角落。现在您想要绘制线的等式,即可得到rho
和theta
。只需重新排列等式,以便您可以求解y = mx + b
形式的线的等式:
因此,只需循环遍历您拥有的每个rho
和theta
,然后绘制一条从x = 0
的原点开始直到图像限制的行x = width-1
。但是,由于MATLAB是1索引的,我们需要从x = 1
转到x = width
。假设您的rho
和theta
存储在相同长度的单独数组中,并且您的边缘图像存储在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
。因此,上面的代码现在应该正确处理任何行,以及当斜率无限时的退化情况。因此,代码的第二个版本就是你所追求的。