How can i hold the current image or axis with it zoom level and apply other functions like imfill without resetting the axis to it default state?

i have a bw image which i want to zooom in and select some point with the mouse as location for the imfill function, after zooming in and running imfill on the zoomed image, the axis get reset and makes it hard to select the right point i want with the mouse
please help. thanx.y

3 Comments

I'm not clear on your order of operations here, could you provide a small snippet of code and explanation:
I = imread('coins.png');
Ibw = I>100;
imfill(Ibw)
Doesn't allow me to zoom, what am I doing wrong?
He has it zoomed and scrolled (probably interactively by the user) to some location the user wants to inspect closely. Then the user clicks some button to do a fill process. Then he calls imshow() to put that filled image back into the axes. Calling imshow() will reinitialize the zooming to "fit". He wants it to be zoomed and scrolled to the exact location that it was at before the fill process was begun, so he can see that how that tiny blob he was looking at got filled in.
I'm going to post this last comment as an answer too since I think it is essentially what the OP wants.

Sign in to comment.

 Accepted Answer

Use the zoom object's ActionPostCallback to store some information about the zoom state,i.e. the axes' 'XLim'/'YLim'. Then after the second call to imshow, explicitly call set the limits with this state information.
doc zoom %for more info
More - you piqued my interest:
If you run this, you'll get one zoom in. It will then open a new figure where you can use imfill(). I recommend doing this on the coin that has black. Once you are done imfill()-ing, it will update the original image with the replacement part.
Note: If I had to do this myself, I would probably take a different approach and use imrect() instead of zoom. That way you could adjust the rectangle's location interactively until you feel it is correct. That could be done here too by having a pushbutton for the uiresume(). With how I put it the ActionPostCallback here, it only gives you one chance to zoom which is kind of harsh if you click a lot, like me...
function imfillZoom
%Make a figure that allows for one zoom in and then allows you to IMFILL
%
%MathWorks - Sean de Wolski - 1/3/2013
%
%Make figure and preallocate limits
hFig = figure;
limits = [];
%Show image
I = imread('coins.png');
Ibw = I>100;
hImage = imshow(Ibw);
%Create the zoom object
zoomObj = zoom;
set(zoomObj,'ActionPostCallback',@storeLimits); %doing this after zoom
set(zoomObj,'Enable','on'); %on
uiwait(hFig);
set(zoomObj,'ActionPostCallback',[]); %no longer necessary
%Now filling
limitsRounded = round(limits); %integers for indexing
IbwZoomed = Ibw(limitsRounded(2):limitsRounded(4),limitsRounded(1):limitsRounded(3)); %extract zoomed portion
tempFig = figure('name','IMFILL!','units',get(hFig,'units'),'position',get(hFig,'Position')); %poof temporary figure for IMFILL
IbwZoomed = imfill(IbwZoomed); %fill the zoomed part
if ishandle(tempFig); %if it still exists, get rid of it
close(tempFig);
end
Ibw(limitsRounded(2):limitsRounded(4),limitsRounded(1):limitsRounded(3)) = IbwZoomed; %update the other part
set(hImage,'CData',Ibw); %change the CData of the original image to the filled one
%Nested Functions
function storeLimits(~,evt)
limits(2,:) = get(evt.Axes,'YLim');
limits(1,:) = get(evt.Axes,'XLim');
uiresume(hFig);
end
end
Good Luck!

2 Comments

Great! Am tempted to accept this as an answer and qork around it to suit my needs. But i ll be saved if uiresume does not get triggered after a single zoom, which ll allow for multiple zoom and pan to the desire locations before selecting.fill locations.
I really appreciate ur response, thanks.
Sure just instead of putting the uiresume() in the callback, add a pushbutton, whose callback does it:
uicontrol('style','push','string','done zoomin''','callback',@(~,~)uiresume(hFig))

Sign in to comment.

More Answers (3)

Have you tried writing to the cdata property of the axes instead of calling imshow()?

1 Comment

No. but even if i write to de cdata directly and apply an zoom action before calling the imfill, the axes may reset. it seems calling the imfill reloads or refreshes the axis before it allows me to pixk the locations with the mouse

Sign in to comment.

imfill() does not operate on the image currently on the screen: imfill() displays the image you pass in the first argument and works on that.

3 Comments

100% correct. but the image axis returned by the imfill command has it zooming tools turned off, so u cant zoom to select locations. is there away around around this?
?? imfill does not return an image axis.
Have you considered selecting points with ginput() or the like, and then calling imfill() in non-interactive mode?
After calling ginput, the user has no chance of zooming in or pan to a particular location before selecting points. And ginput does not work on an image axes with zoom or pan already applied.

Sign in to comment.

Categories

Community Treasure Hunt

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

Start Hunting!