2010-03-17 62 views
13

什么是绘制了在MATLAB黑白(二进制)图像的行的最佳方式,所提供的起点和终点坐标已知?MATLAB:画线在黑白图像

请注意,我不想添加注释行。我希望该行成为图像的一部分。

回答

7

你可能想在my answer寻找到一个SO质疑约adding a line to an image matrix。这里有一个类似的例子,一个我在这个问题的答案,这将使运行的行和列索引(10, 10)(240, 120)白线:

img = imread('cameraman.tif'); % Load a sample black and white image 
x = [10 240];     % x coordinates 
y = [10 120];     % y coordinates 
nPoints = max(abs(diff(x)), abs(diff(y)))+1; % Number of points in line 
rIndex = round(linspace(y(1), y(2), nPoints)); % Row indices 
cIndex = round(linspace(x(1), x(2), nPoints)); % Column indices 
index = sub2ind(size(img), rIndex, cIndex);  % Linear indices 
img(index) = 255; % Set the line points to white 
imshow(img);  % Display the image 

而这里的结果图像:

enter image description here

+5

这对于一条对角线来说非常合适,但可能会为不平的线条添加不需要的像素。如果你不关心额外的像素,我建议选择gnovices解决方案,因为它快速简单。 – Jonas 2010-03-17 19:44:14

+0

@Jonas:我已经更新了算法来更好地计算线条,从而消除了一些不必要的像素。 – gnovice 2017-05-02 04:10:56

+0

谢谢你改进我的答案! – Jonas 2017-05-02 07:22:45

5

如果您对其他方法的例外情况感到困扰,这里采用一种防弹方法可以产生一条线:

  • 其像素总是线的整个长度期间彼此接触(像素是8邻居彼此),该行的
  • 密度不依赖于附加参数但灵活地确定,以适应保从第一点。

输入(方便用于制造功能超出此代码):

  • img - 基质含有图像,
  • x1y1x2y2 - 结束点的坐标要绘制的线条。

代码:

% distances according to both axes 
xn = abs(x2-x1); 
yn = abs(y2-y1); 

% interpolate against axis with greater distance between points; 
% this guarantees statement in the under the first point! 
if (xn > yn) 
    xc = x1 : sign(x2-x1) : x2; 
    yc = round(interp1([x1 x2], [y1 y2], xc, 'linear')); 
else 
    yc = y1 : sign(y2-y1) : y2; 
    xc = round(interp1([y1 y2], [x1 x2], yc, 'linear')); 
end 

% 2-D indexes of line are saved in (xc, yc), and 
% 1-D indexes are calculated here: 
ind = sub2ind(size(img), yc, xc); 

% draw line on the image (change value of '255' to one that you need) 
img(ind) = 255; 

这里的三行上绘制的示例图像: enter image description here

+0

这个方法很适合处理超出界限的点。我使用了一些光线交叉码来找到给定点的斜坡形式的界限。它在调用这个函数之前完成,但它可以很容易地被合并。 – taranaki 2014-12-17 06:08:06

+0

对...对不起。我很久以前写过这篇文章。现在需要花费很多精力来进行改进,因为我目前没有Matlab。 – plesiv 2014-12-17 14:37:51

+0

如果你删除'interp1'调用它可以更快,考虑到你的评论上面我发布了一个新的答案。 – saastn 2017-05-02 09:31:50

0

实际上它只是在plesiv的回答修改。我在图像上绘制了数千行,我需要提高性能。通过省略interp1调用和使用整数变量所做的最大改进使其稍快。与我们的plesiv代码相比,它在我的电脑上执行速度提高了大约18%。

function img = drawLine(img, x1, y1, x2, y2) 
x1=int16(x1); x2=int16(x2); y1=int16(y1); y2=int16(y2); 
% distances according to both axes 
xn = double(x2-x1); 
yn = double(y2-y1); 

% interpolate against axis with greater distance between points; 
% this guarantees statement in the under the first point! 
if (abs(xn) > abs(yn)) 
    xc = x1 : sign(xn) : x2; 
    if yn==0 
     yc = y1+zeros(1, abs(xn)+1, 'int16'); 
    else 
    yc = int16(double(y1):abs(yn/xn)*sign(yn):double(y2)); 
    end 
else 
    yc = y1 : sign(yn) : y2; 
    if xn==0 
     xc = x1+zeros(1, abs(yn)+1, 'int16'); 
    else 
    xc = int16(double(x1):abs(xn/yn)*sign(xn):double(x2)); 
    end 
end 

% 2-D indexes of line are saved in (xc, yc), and 
% 1-D indexes are calculated here: 
ind = sub2ind(size(img), yc, xc); 

% draw line on the image (change value of '255' to one that you need) 
img(ind) = 255; 
end 
0

如果您有计算机视觉系统工具箱,你可以使用insertShape

+0

'insertShape'非常慢,它只返回RGB格式的图像。 – saastn 2017-05-02 09:27:04