Accessing an ROI move listener in another function so to delete it
5 次查看(过去 30 天)
显示 更早的评论
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.
采纳的回答
Tommy
2020-7-5
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 个评论
Tommy
2020-7-5
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.
更多回答(0 个)
另请参阅
Community Treasure Hunt
Find the treasures in MATLAB Central and discover how the community can help you!
Start Hunting!