MATLAB Answers

Accessing an ROI move listener in another function so to delete it

13 views (last 30 days)
Jason
Jason on 2 Jul 2020
Edited: Jason on 6 Jul 2020
Hello.
I am using listeners to allow a user to reshape an ellipse ROI (i.e. orange shape) to then apply a mask to an image (then perfrom analysis on that part of the image). I'm using appdesigner
I store the centre and radius of the ROI as global variables (public properties)
I have a pushbutton that allows the user to view and change the shape of the ROI. This is my code.
%get current stored ROI ellipse parameters
r=app.ROIradius;
xc=app.ROIxc;
yc=app.ROIyc;
ax=app.UIAxes3; %This is the UIAxes my image is on.
IM=double(getimage(ax));
[sy,sx]=size(IM);
%Delete any previous ROI
t=findobj(ax,'Type','images.roi.Ellipse');
delete(t);
%Draw ROI using current saved parameters and add a listener to allow it to be changed
h = images.roi.Ellipse(ax,'Center',[xc yc],'Semiaxes',[r r],'Color','r','StripeColor','g','LineWidth',1); %1/e^2 = 1.699xfwhm
h.FaceAlpha = 0.3;
h.DrawingArea=[1 1 sx sy];
h.FixedAspectRatio=true; %ensure a circle
% Listen for mouse movement of the ROI
l=addlistener(h,'MovingROI',@app.allevents);
Then in my allevents function that is attached to the listener: (Perhaps I should have a MovedROI, rather than moving?)
function allevents(app,src,evt)
evname = evt.EventName;
switch(evname)
case{'MovingROI'}
disp(['ROI moving Current Center: ' mat2str(evt.CurrentCenter)]);
disp(['ROI moving Current SemiAxes: ' mat2str(evt.CurrentSemiAxes)]);
c=evt.CurrentCenter;
app.ROIxc=c(1);
app.ROIyc=c(2);
r=evt.CurrentSemiAxes;
app.ROIradius=r(1);
...
case ..
end
I then have another button to create the mask.
r=round(app.ROIradius); xc=round(app.ROIxc); yc=round(app.ROIyc);
circ = drawcircle('Center',[xc,yc],'Radius',r);
BW = createMask(circ,IM);
figure
subplot(1,2,1)
imshow(BW)
IM(~BW) = 0 ; %Apply the mask
subplot(1,2,2)
hi=0.8*max(IM(:))
lo=min(IM(:))
imshow(IM,[lo hi])
My issue is that the listener is still present. does it matter? I can't work out how to delete it from another pushbutton and still do what I want to do.

Accepted Answer

Tommy
Tommy on 5 Jul 2020
Assuming you don't want to delete the ellipse, you could instead delete the listener within your button's callback function. You can pass the listener to that function in a number of ways, one of which is to save the listener within (or as) a property of your app. Another possibility is to directly pass the listener to your button's callback property. I hope the following helps illustrate this, even though it is simply a script and not tied to an object like in appdesigner:
f = uifigure;
ax = axes(f, 'Position', [0.1, 0.6, 0.8, 0.4]);
b = uibutton(f,...
'Position', [0.1*f.Position(3), 0.1*f.Position(4), 0.8*f.Position(3), 0.4*f.Position(4)],...
'ButtonPushedFcn', @buttonpress);
% Draw ROI
h = images.roi.Ellipse(ax, 'Center', [0.5 0.5],...
'Semiaxes', [0.3 0.3]);
% Listen for mouse movement of the ROI
l = addlistener(h, 'MovingROI', @allevents);
% Update button's callback, passing in the listener l
b.ButtonPushedFcn = {b.ButtonPushedFcn, l};
function allevents(~, evt)
evname = evt.EventName;
if strcmp(evname, 'MovingROI')
disp(['ROI moving Current Center: ' mat2str(evt.CurrentCenter)]);
disp(['ROI moving Current SemiAxes: ' mat2str(evt.CurrentSemiAxes)]);
end
end
function buttonpress(src, ~, l)
if nargin > 2 % if nargin > 3 in appdesigner, I believe
delete(l)
% src.ButtonPushedFcn = @buttonpress;
end
end

  3 Comments

Jason
Jason on 5 Jul 2020
Hi Tommy, thanks, I will explore your idea. I actually dont need the ellipse so would it actually be easier to delete this in the 2nd button callback?
Tommy
Tommy on 5 Jul 2020
Possibly easier, as you could use findobj() as you do above instead of storing the ellipse or passing it to the callback directly. I kind of figured the decision to delete the ellipse or not would depend on whether you want it to continue to show within the axes.
Jason
Jason on 6 Jul 2020
So I've an idea from Tommy.
when I create the listener, I assign it to an app property:
app.l=addlistener(h,'MovingROI',@app.allevents);
This then appears to allow me to delete it in other functions / button callbacks
L=app.l;
delete(L);

Sign in to comment.

More Answers (0)

Products


Release

R2019b

Community Treasure Hunt

Find the treasures in MATLAB Central and discover how the community can help you!

Start Hunting!

Translated by