Completing a line in a pixel image array

3 views (last 30 days)
Hello All
I want to create a pixel array image and then want to make a line with a specified angle from the centre. I want to make all the pixel falling on this line (or the next immediate pixel) as ones and the others zeros.
I found out there is a method to draw lines, using plot function, but that is not my goal. I am trying to make a filter for an image.
Here is what I have achieved so fat, but the line only comes half way and then there is another half which I cant understand.
close all, clear all;
clc;
rows=500;
cols=500;
img=zeros(rows,cols);
theta=50;
deltatheta=0.5;
if theta>90
theta=-(90-(theta-90));
end
for i=1:rows
for j=1:cols
x = j-cols/2 ;
y = rows/2-i;
if atan(y/x)*180/pi<theta && atan((rows/2-(i+1))/((j+1)-cols/2))*180/pi>theta
img(i,j) = 1 ;
end
end
end
figure, imagesc(img), colormap gray
Any help would be much appreciated.
  1 Comment
newbie
newbie on 10 Jan 2014
I am quite new to MatLab and is finding the experience all interesting. However, I am frustrated at this point. It might be very simple for most of you but need some serious help here.

Sign in to comment.

Accepted Answer

Matt J
Matt J on 10 Jan 2014
Edited: Matt J on 10 Jan 2014
I would approach it like below. Basically, it looks at all the rays from the image center to each pixel coordinate and tests which rays make an acute angle to your line (dot product>=0) and also which pixels have a projected distance to your line of one or less (using cross product computation).
theta=50;
rows=500; cx=rows/2+.5;
cols=500; cy=cols/2+.5;
e=ones(1,rows*cols);
[X,Y,Z]=ndgrid((1:rows)-cx, (1:cols)-cy, 0);
Coords=[X(:),Y(:),Z(:)].';
linedir=[cosd(theta), sind(theta),0].';
AcuteAngle=(linedir.'*Coords >= 0);
DistLessThan1=sum(cross(Coords,linedir*e).^2)<=1 ;
img=reshape(AcuteAngle & DistLessThan1,rows,cols);
  3 Comments
Matt J
Matt J on 10 Jan 2014
Edited: Matt J on 10 Jan 2014
Yes, it only draws half a line because in your post you said something about wanting it to run "from the centre". However, if you want the whole line, you would just omit the AcuteAngle test from the version I gave you,
img=reshape(DistLessThan1,rows,cols);
newbie
newbie on 10 Jan 2014
Okay, now I get it. Thank you very much for help. It was a relief :)

Sign in to comment.

More Answers (1)

Image Analyst
Image Analyst on 10 Jan 2014
Do you want just a binary image (line or no line)? If so, use Matt's code or the first two lines of my code below. Do you have an existing image where you want to burn the line into? If so, use hline, and burn in the mask:
hLine = imline(gca,[10 100],[10 100]); % Define line.
binaryImage = hLine.createMask(); % Create binary mask.
burnedImage(binaryImage) = 255; % Burn into image.
You can find the endpoints (args 2 and 3) for a certain angle using normal trigonometry. If you want a full blown demo with both line and ellipse being burned into the existing gray level image, see the attached demo.
  3 Comments
Image Analyst
Image Analyst on 10 Jan 2014
Edited: Image Analyst on 10 Jan 2014
Good point. I didn't think of that case. I just thought of the lines lying totally inside the image. If they struck the image edge it would get somewhat complicated.
newbie
newbie on 10 Jan 2014
Thank you very much Analyst for the response. This also does the work the trick for me, but I think Matt's code is more generic and addresses the issue. As i said, I want to classify each pixel falls into a line or a band of lines. I dont want to burn it into another image, but I want to do an inverse fourier of an image with a customizable filter like this.

Sign in to comment.

Community Treasure Hunt

Find the treasures in MATLAB Central and discover how the community can help you!

Start Hunting!