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

Customize get pixel coordinate function in MATLAB

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

1 - Select 使用鼠标的几个点;

2 - 当用户完成后,点击 "RETURN"*;

3 - 点击 "RETURN" 后,如果用户想要编辑其中一个点,he/she 必须点击所需的点并将其拖动到 he/she 想要的位置。

我创建了这个函数:

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(如果用户想要编辑其中一个点,he/she 必须单击所需的点并将其拖动到 he/she 想要的位置)?

提前谢谢大家,

与其获取图形的 CurrentPoint,不如获取 axes 对象的 CurrentPoint

cp = get(gca, 'CurrentPoint');

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

对于你关于拖动点的问题的第二部分。您可能想要执行以下操作。

  1. 为plot对象设置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