MATLAB: Drawing a line over a black and white image

前端 未结 5 1865
生来不讨喜
生来不讨喜 2020-11-30 10:01

What is the best way to draw a line over a black and white (binary) image in MATLAB, provided the start and end coordinates are known?

Please note, I am not trying t

相关标签:
5条回答
  • 2020-11-30 10:46

    If you are bothered by exceptional cases of other methods here's a bullet-proof method that results in a line:

    • whose pixels always touch each other during the whole length of the line (pixels are 8-neighbors to each other),
    • density of the line is not dependent on the additional parameter, but is determined flexibly to accommodate guarantee from the first point.

    Inputs (convenient for making function out of this code):

    • img - matrix that contains image,
    • x1, y1, x2, y2 - coordinates of the end points of the line to be drawn.

    Code:

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

    Here's the example image with three lines drawn on it: enter image description here

    0 讨论(0)
  • 2020-11-30 10:50

    This algorithm offers one approach.

    0 讨论(0)
  • 2020-11-30 10:51

    If you have the Computer Vision System Toolbox, you can use insertShape.

    0 讨论(0)
  • 2020-11-30 10:52

    It actually is just a modification on plesiv's answer. I'm drawing thousands of lines over an image and I need to increase the performance. The most improvement made by omitting interp1 calls and using integer variables made it slightly faster. It performs about 18% faster on my PC comparing to plesiv's code.

    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 讨论(0)
  • 2020-11-30 10:55

    You may want to look at my answer to an SO question about adding a line to an image matrix. Here's a similar example to the one I have in that answer, which will make a white line running from row and column index (10, 10) to (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
    

    And here's the resulting image:

    0 讨论(0)
提交回复
热议问题