MATLAB: рисование линии на черно-белом изображении - PullRequest
14 голосов
/ 17 марта 2010

Как лучше всего нарисовать линию над черно-белым (двоичным) изображением в MATLAB, если известны начальная и конечная координаты?

Обратите внимание, я не пытаюсь добавить строку аннотации. Я бы хотел, чтобы линия стала частью изображения.

Ответы [ 5 ]

9 голосов
/ 17 марта 2010

Возможно, вы захотите посмотреть мой ответ на вопрос 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

А вот и полученное изображение:

enter image description here

5 голосов
/ 14 января 2013

Если вас беспокоят исключительные случаи других методов, вот пуленепробиваемый метод, который приводит к строке:

  • , чьи пиксели всегда соприкасаются друг с другом по всей длине линии (пиксели являются 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;
<Ч />

Вот пример изображения с тремя линиями, нарисованными на нем: enter image description here

3 голосов
/ 17 марта 2010

Этот алгоритм предлагает один подход.

0 голосов
/ 02 мая 2017

Если у вас есть набор инструментов системы Computer Vision, вы можете использовать insertShape .

0 голосов
/ 02 мая 2017

На самом деле это просто модификация ответа плесива. Я рисую тысячи линий над изображением, и мне нужно увеличить производительность. Наибольшее улучшение было достигнуто за счет исключения вызовов interp1 и использования целочисленных переменных, что сделало его немного быстрее. На моем ПК он работает примерно на 18% быстрее, чем код plesiv.

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
...