2016-06-10 6 views
0

I определяется для создания GUI которым показывает изображение, и пользователь должен иметь возможность выполнять следующие действия:Настройки получить пиксели функции координат в MATLAB

1 - Выберите несколько точек с помощью мыши;

2 - Когда пользователь закончил, нажмите «RETURN» *;

3 - После наложения «RETURN», если пользователь хочет отредактировать одну из точек, он должен щелкнуть нужную точку и перетащить ее туда, где он хочет.

Я создал эту функцию:

function [x, y] = test(img) 

[lin, col] = size(img); 
fig = figure('WindowButtonDownFcn', {@func, lin, col}, 'KeyPressFcn', @keyfunc); 
imshow(img, []); 
% axs = axes('position', [1 col 1 lin]); 
set(gca, 'Ydir', 'reverse'); 
x = []; 
y = []; 
uiwait(fig); 

     function func(src, callback, lin, col) 
      seltype = get(fig, 'SelectionType'); 
      set(gca, 'Ydir', 'reverse'); 
      if strcmp(seltype, 'normal') 
       set(fig, 'Pointer', 'circle'); 
       cp = get(fig, 'CurrentPoint'); 
       xinit = cp(1, 1); 
       yinit = cp(1, 2); 
       x = [x, xinit]; 
       y = [y, yinit]; 
       hl = line('XData', xinit, 'YData', yinit, 'color', 'b', 'Marker', '.'); 
       set(fig, 'WindowButtonMotionFcn', {@moveMouse, lin, col}); 
       set(fig, 'WindowButtonUpFcn', @mouseRelease); 
      end 

      function moveMouse(src, callback, lin, col) 
       cp = get(fig, 'CurrentPoint'); 
       xdata = [xinit, cp(1, 1)]; 
       ydata = [yinit, cp(1, 2)]; 
       set(hl, 'XData', xdata); 
       set(hl, 'YData', ydata); 
       drawnow; 
      end 

      function mouseRelease(src, callback) 
       last_selection = get(fig, 'SelectionType'); 
       if strcmp(last_selection, 'alt') 
        set(fig, 'Pointer', 'arrow'); 
        set(fig, 'WindowButtonMotionFcn',''); 
        set(fig, 'WindowButtonUpFcn',''); 
       else 
        return; 
       end 
      end   
     end 

     function keyfunc(src, callback) 
      keypressed = get(fig, 'CurrentCharacter'); 
      if keypressed == 13 
       uiresume(fig); 
      end 
     end 

end 

Q1 - Он может построить изображение, но система координат имеет свой нуль в верхнем левом краю рисунка. Как переместить его влево-вверху изображения?

Q2 - Как я могу реализовать номер позиции 3 (ЕСЛИ пользователь хочет отредактировать одну из точек, он/она должен щелкнуть нужную точку и перетащить ее туда, где он/она хочет)?

Спасибо всем заранее,

ответ

2

Вместо того, чтобы получать CurrentPoint фигуры, вы хотите получить CurrentPoint из осей объекта.

cp = get(gca, 'CurrentPoint'); 

% Then get just the x/y position 
cp = cp(1,1:2); 

Для второй части вашего вопроса о перетаскивании точки. Вероятно, вы захотите сделать что-то вроде следующего.

  1. Установите ButtonDownFcn для объекта участка, чтобы вызвать функцию обратного вызова

  2. В этой функции найти точку на участке, который находится ближе всего к точке щелкнули.

  3. Отслеживайте этот индекс и устанавливайте WindowButtonMotionFcn так, чтобы всякий раз, когда вы перемещаете мышь, эта точка перемещается в это место.

  4. Установите WindowButtonUpFcn, чтобы при отпускании кнопки мыши сброс WindowButtonMotionFcn.

Нечто подобное должно дать вам представление.

set(hl, 'ButtonDownFcn', @(src,evnt)clickedLine(src)) 


function clickedLine(src, evnt)  
    cp = get(ancestor(src, 'axes'), 'CurrentPoint'); 

    xdata = get(src, 'XData'); 
    ydata = get(src, 'YData'); 

    % Find the index of the closest point 
    [~, ind] = min((xdata - cp(1,1)).^2 + (ydata - cp(1,2)).^2); 


    hfig = ancestor(src, 'figure'); 

    switch get(hfig, 'SelectionType') 
     case 'alt' 
      % Right click deletes a point 
      xdata(ind) = []; 
      ydata(ind) = []; 

      set(src, 'XData', xdata, 'YData', ydata); 
     otherwise 
      % Set the WindowMotionFcn callback to track this point 
      set(hfig, 'WindowButtonMotionFcn', @(s,e)dragPoint(src,ind), ... 
         'WindowButtonUpFcn', @(s,e)stopDrag(s)); 
    end 
end 

function dragPoint(plt, index) 
    xdata = get(plt, 'xdata'); 
    ydata = get(plt, 'ydata'); 

    % Get the current point 
    cp = get(ancestor(plt, 'axes'), 'CurrentPoint'); 

    xdata(index) = cp(1,1); 
    ydata(index) = cp(1,2); 

    % Update the data and refresh 
    set(plt, 'XData', xdata, 'YData', ydata); 

    drawnow 
end 

function stopDrag(hfig) 
    set(hfig, 'WindowButtonMotionFcn', '', ... 
       'WindowButtonUpFcn', ''); 
end 
+0

Благодарим за ответ. Еще один вопрос: могу ли я добавить функциональность «удалить»? Я добавил его, но он влияет только на результат (x, y векторы), но он не обновляет строку. – Gabs

+0

@Gabs Да, вы можете использовать 'ind', найденный в' clickedLine', чтобы удалить определенный элемент. Затем вы захотите обновить сюжет 'xdata' и' ydata'. – Suever

+0

Извините, но как именно я это делаю? – Gabs

Смежные вопросы