how are you? I need help. I read an image and then display it, then click two points on the image say: p1 and p2. Now I want to draw lines (arrows if possible) showing that these are vectors orthogonal to the ground plane. Then draw lines parallel to the y-axis and each of these points say l1 and l2 and finally calculate the shortest distance between these lines. I have gotten the points, drawn the lines but am not sure how to get the distance. Also I have observed that for one line it works fine but for two lines, they are drawn in different locations, I dont know why. I have been trying to do this for about three days but the results I get are far different from what I want. As for some parts am not sure how to do it. Below is the code I have currently. I have also attached an image demonstrating what am trying to achieve. I hope its understandable. I removed the part where I try to get the distance because even if I know that I need four points from these lines to estimate the shortest distance between them, I don't know how to get these points :( - am open to suggestions. [![enter image description here][1]][1]
Thanks for the help. PS. let me know if what am trying to do is impossible. It seemed logical to me though when i set out to do it.
Below is my current code
% Read and display image
i = imread('sample.jpg');
im = i;
f = figure;
imshow(im);
% Get user clicked points
[p1 p2] = getpts(f);
% Draw parallel vertical lines at given pts. parallel to the y-axis/post
hold on;
line([p1(1) p1(1)], get(gca, 'ylim'));
line([p2(1) p2(1)], get(gca, 'ylim'));
% Calculate shortest distance between these two lines
% - not sure how to proceed with this because as far as i know I need at
% least 4 points to determine where they meet :(
% Draw vector symbols at points
% 1. draw x component arrow/line - parallel to the x-axis of image
% (or perpendicular to y-axis??) but must be perpendicular to ground plane
% Slope of current line
m = (diff(p1)/diff(get(gca, 'ylim')));
% Slope of new line
Li = 10 ;
minv = -1/m;
line([mean(p1) mean(p1)+Li],[mean(get(gca, 'ylim')) mean(get(gca, 'ylim'))+Li*minv],'Color','r')
% 2. draw y component arrow/line - parallel to the y-axis of image
% Slope of current line
m = (diff(p2)/diff(get(gca, 'ylim')));
% Slope of new line
Li = 10 ;
minv = -1/m;
line([mean(p2) mean(p2)+Li],[mean(get(gca, 'ylim')) mean(get(gca, 'ylim'))+Li*minv],'Color','k')
axis equal;
Please have a look at the documentation of getpts, it returns [X,Y], with Point_i=[X(i), Y(i)].
Since the two lines are parallel in your case, they do not intersect and d is therefore the x difference of the two selected points. Or was this just a special case?
A first draft would look like this:
% Read and display image
i = imread('Sample.jpg');
im = i;
f = figure;
imshow(im);
% Get user clicked points
[X, Y] = getpts(f);
% Draw parallel vertical lines at given pts. parallel to the y-axis/post
hold on;
line([X(1) X(1)], get(gca, 'ylim'));
line([X(2) X(2)], get(gca, 'ylim'));
d=X(2)-X(1);
For the rest of the code, please be more specific. Since you want to show the normal vector of the picture, do you want to plot the whole thing in a 3D plot?
EDIT: Regarding the comments, the final code has been modified to show a 2D image in a 3D plot. Further imporvement can be done, but should be rather easy (e.g. have a look at this or this for arrows)
% Read and display image
myImg = imread('Sample.jpg');
f1 = figure;
imshow(myImg);
imSize=size(myImg);
% Get user clicked points
[X, Y] = getpts(f1);
xLim=get(gca, 'xlim');
yLim=get(gca, 'ylim');
close(f1);
% Draw parallel vertical lines at given pts. parallel to the y-axis/post in the image
lWidth = 5; %width of line in Pixel, should be odd
lColor = [255,0,0]; %Linecolor in RGB
pColor = [0,255,0]; %Pointcolor in RGB
vColor = [0,0,255]; %Vectorcolor in RGB
% image positions of points in pixel
xP1=int16((X(1)-xLim(1))/(xLim(2)-xLim(1))*imSize(2));
xP2=int16((X(2)-xLim(1))/(xLim(2)-xLim(1))*imSize(2));
yP1=int16((Y(1)-yLim(1))/(yLim(2)-yLim(1))*imSize(1));
yP2=int16((Y(2)-yLim(1))/(yLim(2)-yLim(1))*imSize(1));
% Draw lines in image
for xLine = [xP1,xP2]
for i = max([1,xLine-(lWidth-1)/2]):min([imSize(2),xLine+(lWidth-1)/2])
for j=1:imSize(1)
myImg(j,i,1:3)=lColor;
end
end
end
%mark Points
Points=[[xP1,yP1];[xP2,yP2]];
for k = 1:2
Pos=Points(k,:);
for i = max([1,Pos(1)-(lWidth-1)/2]):min([imSize(2),Pos(1)+(lWidth-1)/2])
for j = max([1,Pos(2)-(lWidth-1)/2]):min([imSize(1),Pos(2)+(lWidth-1)/2])
myImg(j,i,1:3)=pColor;
end
end
end
%3D plot - Some rotations required to get a nice axisvalue alignment
g = hgtransform('Matrix',makehgtform('translate',[0,imSize(1),0])*makehgtform('axisrotate',[0,1,0],pi)*makehgtform('zrotate',pi));
f2 = image(g,myImg);
axis([0,imSize(2),0,imSize(1),-0.1,1.1]) %axis range
view(40,30) %view point
%add normal vectors
hold on
r=(lWidth-1)/2;
[X,Y,Z] = cylinder(r);
xC1=X+double(xP1);
xC2=X+double(xP2);
yC1=imSize(1)-Y-double(yP1);
yC2=imSize(1)-Y-double(yP2);
mesh(xC1,yC1,Z,'facecolor',vColor/255,'edgecolor',vColor/255);
mesh(xC2,yC2,Z,'facecolor',vColor/255,'edgecolor',vColor/255);