векторы на изображении в матлабе

как дела? Мне нужна помощь. Я читаю изображение, затем отображаю его, затем нажимаю две точки на изображении, скажем: p1 и p2. Теперь я хочу нарисовать линии (если возможно, стрелки), показывающие, что это векторы, ортогональные плоскости земли. Затем нарисуйте линии, параллельные оси Y, и каждую из этих точек скажите l1 и l2 и, наконец, рассчитайте кратчайшее расстояние между этими линиями. Я получил точки, нарисовал линии, но не знаю, как получить расстояние. Также я заметил, что для одной строки это работает нормально, но для двух строк они рисуются в разных местах, я не знаю, почему. Я пытался сделать это около трех дней, но результаты, которые я получаю, сильно отличаются от того, что я хочу. Что касается некоторых частей, я не уверен, как это сделать. Ниже приведен код, который у меня есть в настоящее время. Я также приложил изображение, демонстрирующее, чего я пытаюсь достичь. Я надеюсь, что это понятно. Я удалил часть, где я пытаюсь получить расстояние, потому что, даже если я знаю, что мне нужно четыре точки от этих линий, чтобы оценить кратчайшее расстояние между ними, я не знаю, как получить эти точки :( - открыт для предложений. [![введите здесь описание изображения][1]][1]

Спасибо за помощь. PS. дайте мне знать, если то, что я пытаюсь сделать, невозможно. Хотя мне это казалось логичным, когда я собирался это сделать.

Ниже мой текущий код

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

person gordon    schedule 05.01.2018    source источник


Ответы (1)


Пожалуйста, взгляните на документацию getpts, она возвращает [X,Y], с Point_i=[X(i), Y(i)].

Поскольку в вашем случае две линии параллельны, они не пересекаются, и поэтому d - это разница x двух выбранных точек. Или это был просто частный случай?

Первый черновик будет выглядеть так:

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

Для остальной части кода, пожалуйста, будьте более конкретными. Поскольку вы хотите показать вектор нормали изображения, хотите ли вы построить все это в трехмерном графике?

РЕДАКТИРОВАТЬ: что касается комментариев, окончательный код был изменен для отображения 2D-изображения на 3D-графике. Дальнейшее улучшение можно сделать, но это должно быть довольно просто (например, взгляните на это или это для стрелок)

% 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);
person HTh    schedule 05.01.2018
comment
Я предпочитаю, чтобы это было как можно проще. если это возможно в 2D, то я предпочитаю 2D. В противном случае, если 3D не будет так хлопотно. Тогда это еще интереснее. Что касается расстояния, я был сбит с толку тем, как определить две ближайшие точки двух отрезков. Потому что я предполагаю, что это будет кратчайшее расстояние между линиями. - person gordon; 06.01.2018
comment
хм, это объясняет, почему это сработало для одной строки, а не для двух отдельных строк, спасибо. - person gordon; 06.01.2018
comment
На самом деле, если это не будет слишком много работы, 3D имеет больше смысла, и в этом случае линии должны быть параллельны оси Y плоскости земли. Потрясающая идея. - person gordon; 06.01.2018
comment
какую версию Matlab вы используете, f2 = image(g,myImg); выдает ошибку неправильного количества аргументов. - person gordon; 06.01.2018
comment
спасибо, кажется, я исправил это. Но быстрый вопрос, как просто просмотреть его в 2D-графике. - person gordon; 06.01.2018
comment
очистить весь код ниже, включая график% 3D ... и заменить его простым imshow (myImg) - person HTh; 06.01.2018
comment
спасибо, но я только что заметил кое-что. вы забыли о горизонтальной составляющей векторов. мы получили только ортогональные/вертикальные :(. - person gordon; 06.01.2018
comment
вы имеете в виду кратчайшее соединение между двумя линиями? вы можете добавить его как imshow(myImg); hold on; line([X(1),X(2)],[(Y(1)+Y(2))/2,(Y(1)+Y(2))/2]); в 2D-изображение - person HTh; 06.01.2018
comment
нет-нет, для каждой точки есть ортогональная нормаль (вертикальная составляющая вектора), теперь другая - это x-компонента. Те, что со стрелками на них. - person gordon; 06.01.2018
comment
как это? imshow(myImg); hold on; line([X(1),X(1)+xLim/10],[Y(1),Y(1)]); line([X(2),X(2)+xLim/10],[Y(2),Y(2)]); - person HTh; 06.01.2018
comment
это выдает ошибки. вы имели в виду что-то вроде xLim(1) ... xLim(2)? xLim(2) в порядке, а xLim(1) отключено. это не в отмеченной точке. и да что-то в этом роде :) - person gordon; 06.01.2018
comment
ой извините, не проверял код. это должно работать imshow(myImg); hold on; line([X(1),X(1)+(xLim(2)-xLim(1))/10],[Y(1),Y(1)]); line([X(2),X(2)+(xLim(2)-xLim(1))/10],[Y(2),Y(2)]); - person HTh; 06.01.2018
comment
Давайте продолжим это обсуждение в чате. - person gordon; 06.01.2018