MATLAB: Dibujando una línea sobre una imagen en blanco y negro

¿Cuál es la mejor manera de trazar una línea sobre una imagen en blanco y negro (binaria) en MATLAB, siempre que se conozcan las coordenadas de inicio y fin?

Tenga en cuenta que no estoy tratando de agregar una línea de anotación. Me gustaría que la línea se convierta en parte de la imagen.

Es posible que desee ver mi respuesta a una pregunta sobre SO sobre agregar una línea a una matriz de imágenes . Aquí hay un ejemplo similar al que tengo en esa respuesta, que hará que una línea blanca se ejecute desde el índice de fila y columna (10, 10) hasta (240, 120) :

 img = imread('cametwign.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 

Y aquí está la imagen resultante:

enter image description here

Si le molestan casos excepcionales de otros métodos, aquí hay un método a prueba de balas que da como resultado una línea:

  • cuyos píxeles siempre se tocan entre sí durante toda la longitud de la línea (los píxeles son 8 vecinos entre sí),
  • la densidad de la línea no depende del parámetro adicional , sino que se determina de forma flexible para acomodar la garantía desde el primer punto.

Entradas (conveniente para hacer funcionar este código):

  • img – matriz que contiene imagen,
  • x1 , y1 , x2 , y2 – coordenadas de los puntos finales de la línea a dibujar.

Código:

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

Aquí está la imagen de ejemplo con tres líneas dibujadas en ella: enter image description here

Este algoritmo ofrece un enfoque.

En realidad, es solo una modificación en la respuesta de Plesiv. Estoy dibujando miles de líneas sobre una imagen y necesito boost el rendimiento. La mayor mejora realizada al omitir llamadas interp1 y el uso de variables enteras lo hizo un poco más rápido. Se realiza aproximadamente un 18% más rápido en mi PC en comparación con el código de 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 

Si tiene Computer Vision System Toolbox, puede usar insertShape .