Reputation: 758
Goal: To perform several clicks in one figure, containing an image displayed with imshow and save the coordinates of the "clicked" point(s), to be used in further operations.
Notes: I know about the functions getpts
/ginput
but I would like to perform this without using them. Is this possible using ButtonDownFcn
? (see the following code)
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);
At this stage the variables x
and y
only "live" inside ax_bdfcn
.
How can I make them available in the testClicks
function? Is this possible using ButtonDownFcn
? Is this a good approach?
Thanks a lot.
EDIT1: Thanks for the answer Shai. But I still cannot accomplish what I intended.
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
This code (buggy!) is the closest I can get to what I want (after all the clicking, having an array with the x and y coordinates of the clicked points). I am clealy not understanding the mechanics for the implementation of this task. Any help?
Upvotes: 2
Views: 5924
Reputation: 114796
There are several ways
Using 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
Using assignin
function ax_bdfcn(varargin)
a = get(gca, 'CurrentPoint');
assignin('caller', 'x', a(1) );
assignin('caller', 'y', a(2) );
Using 'UserData'
property of figure handle
function ax_bdfcn(varargin)
a = get(gca, 'CurrentPoint');
set( gcf, 'UserData', a(1:2) );
'UserData'
can be accessed (as long as the figure is alive) using cp = get( gcf, 'UserData');
.
EDIT:
An example of a way to "communicate" the clicked locations to 'base'
workspace
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
After calling testClicks
there are NO xArray
or yArray
variables in the workspace (at least there shouldn't). After the first click these two variables will "miraculously" be created. After every other click these two arrays will increase their size until you close the figure.
Upvotes: 3