【问题标题】:MATLAB: How to store clicked coordinates using ButtonDownFcnMATLAB:如何使用 ButtonDownFcn 存储单击的坐标
【发布时间】:2013-03-04 13:02:57
【问题描述】:

目标:在一个图形中执行多次点击,其中包含使用 imshow 显示的图像,并保存“点击”点的坐标,以用于进一步的操作。

注意:我知道函数getpts/ginput,但我想在不使用它们的情况下执行此操作。这可以使用ButtonDownFcn 吗? (见以下代码)

function testClicks
img = ones(300); % image to display
h   = imshow(img,'Parent',gca);
set(h,'ButtonDownFcn',{@ax_bdfcn});

function ax_bdfcn(varargin)
a = get(gca,'CurrentPoint');
x = a(1,1);
y = a(1,2);

在这个阶段,变量xy 仅在ax_bdfcn 中“存在”。 如何使它们在 testClicks 函数中可用?这可以使用ButtonDownFcn 吗?这是一个好方法吗?

非常感谢。

EDIT1: 谢谢夏的回答。但我仍然无法完成我的意图。

function [xArray, yArray] = testClicks()
img = ones(300); % image to display
h   = imshow(img,'Parent',gca);
x = [];
y = [];
xArray = [];
yArray = [];
stop = 0;
while stop == 0;
    set(h,'ButtonDownFcn',{@ax_bdfcn});
    xArray = [xArray x];
    yArray = [yArray y];
        if length(xArray)>15
            stop = 1;
        end
end

    function ax_bdfcn(varargin)
        a = get(gca, 'CurrentPoint');
        assignin('caller', 'x',  a(1,1) );
        assignin('caller', 'y',  a(1,2) );
    end
end % must have end for nested functions

这段代码(有问题!)是我能得到的最接近我想要的代码(在所有点击之后,有一个包含点击点的 x 和 y 坐标的数组)。我显然不了解执行此任务的机制。有什么帮助吗?

【问题讨论】:

  • 您的代码的问题是testClicks(忽略while 循环)在创建图像后立即返回,因此xArrayyArray 为空。您可能需要使用assignin('base',...) 来克服这个问题。

标签: matlab save coordinates


【解决方案1】:

有几种方法

  1. 使用nested functions

    function testClicks
       img = ones(300); % image to display
       h   = imshow(img,'Parent',gca);
       set(h,'ButtonDownFcn',{@ax_bdfcn});
       x = []; % define "scope" of x and y 
       y = [];  
    
       % call back as nested function
       function ax_bdfcn(varargin)
           a = get(gca,'CurrentPoint');
           x = a(1,1); % set x and y at caller scope due to "nested"ness of function
           y = a(1,2);
       end  % close nested function
    end % must have end for nested functions
    
  2. 使用assignin

    function ax_bdfcn(varargin)
         a = get(gca, 'CurrentPoint');
         assignin('caller', 'x',  a(1) );
         assignin('caller', 'y',  a(2) ); 
    
  3. 使用图形句柄的'UserData'属性

    function ax_bdfcn(varargin)
         a = get(gca, 'CurrentPoint');
         set( gcf, 'UserData', a(1:2) );
    

    'UserData' 可以使用cp = get( gcf, 'UserData'); 访问(只要图还活着)。

编辑:
将单击的位置“传达”到'base' 工作区的方法示例

function ax_bdfcn(varargin)
   a = get(gca,'CurrentPoint');
   % the hard part - assign points to base
   if evalin('base', 'exist(''xArray'',''var'')')
      xArray = evalin('base','xArray');
   else 
      xArray = [];
   end
   xArray = [xArray a(1)]; % add the point
   assignin('base','xArray',xArray); % save to base
   % do the same for yArray

调用testClicks 后,工作区中没有xArrayyArray 变量(至少不应该有)。第一次单击后,这两个变量将“奇迹般地”创建。每隔一次单击后,这两个数组将增加它们的大小,直到您关闭图窗。

【讨论】:

  • +1 用于列出多种方法。就个人而言,如果可能的话,我会选择嵌套函数/闭包,否则 UserData。我会避免使用assignin,因为它更难调试。
  • 再次感谢@Shai。事实上,现在变量存储在工作区中,但这引发了 如何 在 testClicks 函数中使用它们的问题,因为它们似乎并不存在于该函数中......
  • @fnery 你可以使用assignin('caller',...)evalin('caller',...) 而不是'base'...
猜你喜欢
  • 2014-10-20
  • 1970-01-01
  • 2021-12-31
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
相关资源
最近更新 更多