在MATLAB中自定义获取像素坐标函数

在MATLAB中自定义获取像素坐标函数,matlab,matlab-figure,matlab-guide,Matlab,Matlab Figure,Matlab Guide,我需要创建一个显示图像的GUI,用户必须能够执行以下操作: 1-使用鼠标选择多个点 2-用户完成后,点击“返回”* 3-点击“返回”后,如果用户想要编辑其中一个点,他/她必须单击所需点并将其拖动到他/她想要的位置 我创建了这个函数: function [x, y] = test(img) [lin, col] = size(img); fig = figure('WindowButtonDownFcn', {@func, lin, col}, 'KeyPressFcn', @keyfunc);

我需要创建一个显示图像的GUI,用户必须能够执行以下操作:

1-使用鼠标选择多个点

2-用户完成后,点击“返回”*

3-点击“返回”后,如果用户想要编辑其中一个点,他/她必须单击所需点并将其拖动到他/她想要的位置

我创建了这个函数:

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-它可以绘制图像,但坐标系的零位于图形的左上角。如何将其移动到图像的左上角

问题2-如何实现项目编号3(如果用户想要编辑其中一个点,他/她必须单击所需点并将其拖动到他/她想要的位置)


提前感谢大家,

您不需要获取图形的
CurrentPoint
,而是需要获取axes对象的
CurrentPoint

有关拖动点的问题的第二部分。您可能需要执行以下操作

  • 为plot对象设置
    按钮downfcn
    ,以触发回调函数

  • 在该函数中,查找绘图上最靠近单击点的点

  • 跟踪此索引并设置
    WindowButtonMotionFcn
    ,以便无论何时移动鼠标,该点都会移动到该位置

  • 设置
    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
    

    您不需要获取图形的
    CurrentPoint
    ,而需要获取axes对象的
    CurrentPoint

    有关拖动点的问题的第二部分。您可能需要执行以下操作

  • 为plot对象设置
    按钮downfcn
    ,以触发回调函数

  • 在该函数中,查找绘图上最靠近单击点的点

  • 跟踪此索引并设置
    WindowButtonMotionFcn
    ,以便无论何时移动鼠标,该点都会移动到该位置

  • 设置
    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
    

    谢谢你的回答。还有一个问题:我可以添加“删除”功能吗?我添加了它,但它只影响结果(x,y向量),但不更新行。@Gabs Yes您可以使用
    clickedLine中的
    ind
    删除特定元素。然后你会想更新绘图
    xdata
    ydata
    。对不起,我到底是怎么做到的?@Gabs如果你不知道怎么做,我猜你没有写这段代码。。。我已经对代码进行了更新,所以右键单击绘图可以删除一个点。我确实编写了代码,但编写GUI绝对不是我的领域。。。我真的不明白回调是如何工作的。。。对不起…:-(谢谢你的回答。再问一个问题:我可以添加“删除”功能吗?我添加了它,但它只影响结果(x,y向量)但是它不会更新线条。@Gabs是的,你可以使用
    点击线条
    中的
    ind
    删除特定元素。然后你会想更新绘图
    xdata
    ydata
    。对不起,但我到底是怎么做的?@Gabs如果你不知道怎么做,我猜你没有写这段代码……我做了一个简单的解释n更新代码,以便右键单击绘图可以删除一个点我确实编写了代码,但编写GUI绝对不是我的领域…我真的不明白回调是如何工作的…抱歉…:-(