在 MATLAB 中使用 ginput 函数时缩放 in/out

Zooming in/out while using ginput function in MATLAB

我正在使用 MATLAB 中的 ginput 函数来使用光标收集图像上的许多 x,y 坐标。我沿着图像的某条路径行进,需要放大以获得精确的坐标,但在使用 ginput 时放大选项被禁用。关于如何解决这个问题的任何想法?

这是我使用的非常简单的代码。

A = imread('image1.tif');
B = imshow(A);
[x,y] = ginput; 
% at this point i scan the image and click many times, and
% ideally i would like to be able to zoom in and out of the image to better 
% aim the cursor and obtain precise xy coordinates

我认为这样做的方法是利用 ginput 函数的 "button" 输出,即

[x,y,b]=ginput;

b returns 按下的鼠标按钮 或键盘键 。选择您最喜欢的两个键(例如 [ 和 ],字符 91 和 93)并编写一些放大 in/zoom 代码来处理按下这些键时发生的情况:

A = imread('image1.png');
B = imshow(A);
X = []; Y = [];
while 0<1
    [x,y,b] = ginput(1); 
    if isempty(b); 
        break;
    elseif b==91;
        ax = axis; width=ax(2)-ax(1); height=ax(4)-ax(3);
        axis([x-width/2 x+width/2 y-height/2 y+height/2]);
        zoom(1/2);
    elseif b==93;
        ax = axis; width=ax(2)-ax(1); height=ax(4)-ax(3);
        axis([x-width/2 x+width/2 y-height/2 y+height/2]);
        zoom(2);    
    else
        X=[X;x];
        Y=[Y;y];
    end;
end
[X Y]

ginput(1) 中的 (1) 很重要,因此您一次只能获得一个 click/keypress。

回车键是默认的 ginput 中断键,returns 一个空的 b,由第一个 if 语句处理。

如果按下键 91 或 93,我们将分别缩小 (zoom(1/2)) 或放大 (zoom(2))。使用 axis 的几行将绘图置于光标的中心,这很重要,因此您可以放大图像的特定部分。

否则,将光标坐标 x,y 添加到您的坐标集 X,Y

作为替代方法,您可以使用 MATLAB 的 datacursormode 对象,它不会阻挡 zooming/panning 您的图形 window.

一个小例子(假定 R2014b 或更新版本):

h.myfig = figure;
h.myax = axes;

plot(h.myax, 1:10);

% Initialize data cursor object
cursorobj = datacursormode(h.myfig);
cursorobj.SnapToDataVertex = 'on'; % Snap to our plotted data, on by default

while ~waitforbuttonpress 
    % waitforbuttonpress returns 0 with click, 1 with key press
    % Does not trigger on ctrl, shift, alt, caps lock, num lock, or scroll lock
    cursorobj.Enable = 'on'; % Turn on the data cursor, hold alt to select multiple points
end
cursorobj.Enable = 'off';

mypoints = getCursorInfo(cursorobj);

请注意,您可能需要在图内单击 window 以触发数据游标。

这里我使用waitforbuttonpress来控制我们的while循环。如评论所述,waitforbuttonpress returns 0 用于鼠标按钮单击和 1 用于按键,但不是由 Ctrl[=43= 触发], Shift, Alt, Caps, Num,或 ScrLk 键。单击时按住 Alt 可以 select 多个点。

完成 selecting 点后,按下任何触发 waitforbuttonpress 的键,您的数据点将通过调用 getCursorInfo 输出,其中 returns 一个数据包含有关您的点的信息的结构。此数据结构包含 2 或 3 个字段,具体取决于绘制的内容。该结构将始终包含 Target(包含数据点的图形对象的句柄)和 Position(指定光标的 x、y、(和 z)坐标的数组)。如果您绘制了 linelineseries 对象,您还将拥有 DataIndex,这是对应于最近数据点的数据数组的标量索引。

还有一种方法是使用 enableDefaultInteractivity() 函数,它可以使用鼠标滚轮进行放大和缩小:

enableDefaultInteractivity(gca);
[x, y, b] = ginput();

它适用于我的 Matlab 版本(9.9.0.1524771 (R2020b) Update 2,在 Linux Fedora 上)。