Draw a straight line in image, given an angle
Afficher commentaires plus anciens
Is there a way to draw a straight line in an image from a starting (x,y) coordinate, such that the line is equivalent to a specified angle?
For example, if I start at pixel (50,50), how can I draw a line to be 30 degrees of this pixel? I would like to draw 10 pixels in this direction (obviously, the resulting line will be zig-zagged)...
8 commentaires
Walter Roberson
le 29 Sep 2011
This is just another way of phrasing your previous question, http://www.mathworks.com/matlabcentral/answers/16986-normal-vector-of-line-based-on-pixel-coordinates
Philip
le 29 Sep 2011
Image Analyst
le 29 Sep 2011
I fail to see why the answers you got there won't apply to lines at any angle. The fact is, they will apply.
Walter Roberson
le 29 Sep 2011
Irrelevant, Philip. In both cases you identify a specific starting point and need to draw a line at an angle from that point. It matters not to the general algorithm whether the angle has a 90 degree relationship to another known angle, or if it has (say) a 42 degree relationship to the other known angle.
Philip
le 29 Sep 2011
Image Analyst
le 29 Sep 2011
You know your line endpoints. You said you knew the (x,y) starting point. And the other endpoint's x position, if you don't know it, can't be less than 1 or more than the number of columns in your image. Therefore you know both endpoints.
Walter Roberson
le 29 Sep 2011
Calculate the total angle relative to the forward Y axis (i.e., angle 0 on a polar plot.) Choose a large radius, R, such as 1000, for an imaginary line segment; don't worry if it is out of the image. Now, R*sin(theta) and R*cos(theta) give you the total delta x and total delta y if you were drawing the whole line segment. Round to integers, and add those rounded deltas to the starting point to get the imaginary end point. Now apply Bresenham's line algorithm to the imaginary line between the starting point and the identified imaginary end point, except stop when you have generated as many total pixels as you desire. The result will be a line segment drawn from the starting point at your desired angle, for the desired number of pixels.
Philip
le 30 Sep 2011
Réponses (2)
Image Analyst
le 29 Sep 2011
How about this:
lineLength = 10;
angle = 30;
x(1) = 50;
y(1) = 50;
x(2) = x(1) + lineLength * cosd(angle);
y(2) = y(1) + lineLength * sind(angle);
hold on; % Don't blow away the image.
plot(x, y);
xlim([0 70]);
ylim([0 70]);
grid on;
If you want the line to be "burned into" your image, then you'll have to use imline() - search answers for my demo on that - or use the Bresenham line algorithm like Walter suggested if you want to do it yourself.
9 commentaires
Philip
le 30 Sep 2011
Image Analyst
le 30 Sep 2011
Philip: Yes you can. See my demo in an answer below.
K M Ibrahim Khalilullah
le 20 Juin 2016
@Image Analyst I have the same problem. Thanks for your suggestion. >> Is it possible to control end point according to the Image size? because i need end point also.
Image Analyst
le 26 Juin 2016
Yes, just make up your formula's for (x1,y1) and (x2,y2) using the number of rows and columns in your image and whatever else you need to do to set the endpoints wherever you want them.
Michelle De Luna
le 19 Juil 2021
@Image Analyst: Hi there! Quick question (and this may be an easy one, so I apologize in advance, but I would greatly appreciate your guidance): Is there a way to create two lines of identical length when the angles dictating the incline of each of the lines is different? I am in the middle of drawing two equidistant lines on a plot using your suggested code above, but each line starts at a different point and has a different angle. Here's what I have so far. Any suggestions?
lineLength = 10
angle_one = 22.0443
t(1) = 410
e(1) = 200
t(2) = t(1) + lineLength * cosd(angle_one)
e(2) = e(1) + lineLength* sind(angle_one)
plot(t,e)
grid on
hold on
angle_two = 51.2134
c(1) = 436
d(1) = 217
c(2) = c(1) + lineLength * cosd(angle_two)
d(2) = d(1) + lineLength * sind(angle_two)
plot(c,d)
grid on
Image Analyst
le 19 Juil 2021
Yes, of course, because you specified different starting points and angles. What do you want? The same starting point and the same angles? Then they would overlap.
Michelle De Luna
le 20 Juil 2021
Right. The starting points can differ (as should the angles). In my scenario, it would be perfectly fine to have the two lines overlap. I would merely need the lines to have similar length, or to have a length of 21 pixels each.
Image Analyst
le 21 Juil 2021
I don't see the problem. The code is doing exactly what you told it to. Nor do I know what you want. Perhaps a diagram would help. Have it show what you are getting, and what you want instead.
Walter Roberson
le 21 Juil 2021
Michelle De Luna:
No. It is possible to generate two lines of identical length only if they happen to have a particular Pythagorean triple relationship such as listed at http://oeis.org/A084646 or related sequences. For example if the distance is 25 then there are two different angles that can generate that identical distance.
Any case in which the angle and distance does not happen to correspond to one of the triples, you can never get out identical distances.
Image Analyst
le 30 Sep 2011
% Demo to write an ellipse and a line into the overlay of an image,
% and then to burn those overlays into the image.
%----- Initializing steps -----
% Clean up
clc;
clear all;
close all;
workspace; % Display the workspace panel.
% Change the current folder to the folder of this m-file.
if(~isdeployed)
cd(fileparts(which(mfilename)));
end
hasIPT = license('test', 'image_toolbox');
if ~hasIPT
% User does not have the toolbox installed.
message = sprintf('Sorry, but you do not seem to have the Image Processing Toolbox.\nDo you want to try to continue anyway?');
reply = questdlg(message, 'Toolbox missing', 'Yes', 'No', 'Yes');
if strcmpi(reply, 'No')
% User said No, so exit.
return;
end
end
% Display images to prepare for the demo.
monochromeImage = imread('pout.tif');
subplot(2, 4, 1);
imshow(monochromeImage);
title('Original Image');
subplot(2, 4, 2);
imshow(monochromeImage);
title('Original Image with ellipse in overlay');
subplot(2, 4, 5);
imshow(monochromeImage);
title('Original Image');
subplot(2, 4, 6);
imshow(monochromeImage);
title('Original Image with line in overlay');
set(gcf, 'units','normalized','outerposition',[0 0 1 1]); % Maximize figure.
set(gcf,'name','Demo by ImageAnalyst','numbertitle','off')
%----- Burn ellipse into image -----
% Create elliptical mask, h, as an ROI object over the second image.
subplot(2, 4, 2);
hEllipse = imellipse(gca,[10 10 50 150]); % Second argument defines ellipse shape and position.
% Create a binary image ("mask") from the ROI object.
binaryImage = hEllipse.createMask();
% Display the ellipse mask.
subplot(2, 4, 3);
imshow(binaryImage);
title('Binary mask of the ellipse');
% Let's try to add some text. (Doesn't work)
% hText = text(50, 100, 'Line of Text');
% textMask = hText.createMask();
% binaryImage = binaryImage & textMask;
% imshow(binaryImage);
% Burn ellipse into image by setting it to 255 wherever the mask is true.
monochromeImage(binaryImage) = 255;
% Display the image with the "burned in" ellipse.
subplot(2, 4, 4);
imshow(monochromeImage);
title('New image with ellipse burned into image');
%----- Burn line into image -----
burnedImage = imread('pout.tif');
% Create line mask, h, as an ROI object over the second image in the bottom row.
subplot(2, 4, 6);
hLine = imline(gca,[10 100],[10 100]); % Second argument defines line endpoints.
% Create a binary image ("mask") from the ROI object.
binaryImage2 = hLine.createMask();
% Display the line mask.
subplot(2, 4, 7);
imshow(binaryImage2);
title('Binary mask of the line');
% Burn line into image by setting it to 255 wherever the mask is true.
burnedImage(binaryImage2) = 255;
% Display the image with the "burned in" line.
subplot(2, 4, 8);
imshow(burnedImage);
title('New image with line burned into image');
Catégories
En savoir plus sur Display 2-D Images dans Centre d'aide et File Exchange
Community Treasure Hunt
Find the treasures in MATLAB Central and discover how the community can help you!
Start Hunting!