【问题标题】:MATLAB: Drawing a line over a black and white imageMATLAB:在黑白图像上画一条线
【发布时间】:2011-01-28 17:00:57
【问题描述】:

如果已知起点和终点坐标,在 MATLAB 中在黑白(二进制)图像上画线的最佳方法是什么?

请注意,我不是要添加注释行。我希望这条线成为图像的一部分。

【问题讨论】:

    标签: image matlab image-processing line matlab-cvst


    【解决方案1】:

    您可能想查看my answer 以了解有关adding a line to an image matrix 的SO 问题。这是一个与我在该答案中的示例类似的示例,它将生成一条从行和列索引(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
    

    这是生成的图像:

    【讨论】:

    • 这非常适用于对角线,但可能会为较平的线添加不需要的像素。如果您不关心额外的像素,我建议您选择 gnovices 解决方案,因为它既快速又简单。
    • @Jonas:我更新了算法以更好地计算线条,从而消除了一些不必要的像素。
    • 感谢您改进我的回答!
    【解决方案2】:

    如果您对其他方法的异常情况感到困扰,这里有一个防弹方法,它会导致一行:

    • 其像素在整条线中始终相互接触(像素彼此相邻 8 个),
    • 线的密度不依赖于附加参数,而是灵活地确定以适应从第一点开始的保证。

    输入(方便使用此代码实现功能):

    • img - 包含图像的矩阵,
    • x1, y1, x2, y2 - 要绘制的线的端点坐标。

    代码:

    % 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;
    

    这是一个示例图像,上面画了三条线:

    【讨论】:

    • 这种方法可以优雅地处理越界点会很好。我使用了一些射线交点代码来查找给定直线的点斜率形式的边界。它是在调用此函数之前完成的,但它可以很容易地被合并。
    • 是的...对不起。我很久以前写过这个。由于我目前没有Matlab,所以现在需要花费太多精力来改进。
    • 如果您删除 interp1 电话,它会更快,考虑到您在上面的评论,我发布了一个新答案。
    【解决方案3】:

    This algorithm 提供了一种方法。

    【讨论】:

      【解决方案4】:

      这实际上只是对 plesiv 答案的修改。我在图像上画了数千条线,我需要提高性能。通过省略interp1 调用和使用整数变量所做的最大改进使它稍微快了一点。与 plesiv 的代码相比,它在我的 PC 上的执行速度快了大约 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
      

      【讨论】:

        【解决方案5】:

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

        【讨论】:

        • insertShape 真的很慢,它只返回 RGB 格式的图像。
        猜你喜欢
        • 1970-01-01
        • 2011-09-30
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        • 2018-10-18
        • 1970-01-01
        • 2020-12-20
        • 1970-01-01
        相关资源
        最近更新 更多