【问题标题】:Customize get pixel coordinate function in MATLAB在 MATLAB 中自定义获取像素坐标函数
【发布时间】:2016-06-11 03:30:30
【问题描述】:

我需要创建一个显示图像的 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 - 它可以绘制图像,但坐标系在图形的左上角为零。 如何将它移到图片的左上角?

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

提前谢谢大家,

【问题讨论】:

    标签: matlab matlab-figure matlab-guide


    【解决方案1】:

    您需要获取 axes 对象的 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
    

    【讨论】:

    • 感谢您的回答。还有一个问题:我可以添加“删除”功能吗?我添加了它,但它只影响结果(x,y 向量),但它不会更新行。
    • @Gabs 是的,您可以使用在clickedLine 中找到的ind 删除特定元素。然后你会想要更新情节xdataydata
    • 抱歉,我到底是怎么做到的?
    • @Gabs 我猜如果您不知道该怎么做,您就没有编写此代码...我已对代码进行了更新,以便右键单击绘图删除一个点
    • 我确实编写了代码,但编写 GUI 绝对不是我的领域...我不太了解回调是如何工作的...抱歉...: -(
    猜你喜欢
    • 2011-09-26
    • 2018-04-25
    • 2011-12-04
    • 2012-11-26
    • 2018-06-22
    • 1970-01-01
    • 2013-10-15
    • 2014-06-18
    • 2015-06-14
    相关资源
    最近更新 更多