Problem with uiwait; broken by impoly / imroi / roipoly
Afficher commentaires plus anciens
I need a GUI where the user can draw several polygons in an image, and when he is done, the polygon vertices are saved.
So I created a GUI with guide, with an axes with the image, and two pushbuttons. I used 'uiwait' as proposed in guide at the end of the Opening Function. One button 'New' let's the user draw a polyon using 'impoly'. The other button 'OK' calls 'uiresume', so that the code jumps to the Output Function.
The problem is:
Apparently the 'imroi' functions like 'impoly' break 'uiwait' early, and as soon as the first polygon is closed, the Output Function is called. I found two other posts indicating this. The only answer they found was to use 'roipolyold'. But since it is supposed to be removed in future releases, and I'm otherwise quite happy with 'imploly', I would really like to find another solution. I tried avoiding 'uiwait' und using 'waitfor' instead, but it always closed the figure right after opening and then got stuck on 'waitfor'.
I will be happy about any clues or ideas as to how I could get around this. Thanks!
Réponses (4)
Image Analyst
le 28 Août 2014
0 votes
Store the results of each polygon (the vertex coordinates) in a global variable cell array. Each time you click the button and draw a polygon, by whatever method, add it to the cell array variable as a new cell.
8 commentaires
Aline
le 3 Sep 2014
Image Analyst
le 3 Sep 2014
Modifié(e) : Image Analyst
le 3 Sep 2014
Huh? Why does your gui shut down? You must be doing something to shut it down. Do you have a script, or a GUIDE-based gui?
I don't even use uiwait or uiresume in code around calls to roipoly. Here is for a pushbutton callback from one of my functions:
%=====================================================================
% --- Executes on button press in btnDrawNewMask.
function btnDrawNewMask_Callback(hObject, eventdata, handles)
% hObject handle to btnDrawNewMask (see GCBO)
% eventdata reserved - to be defined in a future version of MATLAB
% handles structure with handles and user data (see GUIDATA)
try
% Prompt user to draw a region on the image.
message = sprintf('Draw a polygon (with left clicks) over the image.\nRight click the last vertex point to finish drawing.\n\nIMPORTANT NOTE: you must move inside the polygon and\neither (a) double-click, or (b) right click and select Create Mask from the context menu\nin order to continue towards saving the mask.');
msgboxw(message);
% Get binary image that is a mask representing the region they drew.
% binaryMask is an image of Logical data type.
axes(handles.ImageViewer); % Switch current figure back to image box.
binaryMask = roipoly; % drop the binaryMask= and ; to see the binary image mask
imshow(binaryMask);
reply = questdlg({'Do you want to save the mask', 'to disk as a template?'},'Save image?', 'Yes','No', 'Yes');
% reply = '' for Upper right X, 'Yes' for Yes, 'No' for No.
%uiwait();
if strcmpi(reply, 'Yes')
[fileName, folder] = uiputfile([handles.maskFolder '\TFC_Mask.png'],'Save mask file name');
[folder, baseFileName, ext] = fileparts(fileName);
maskFileName = fullfile(handles.maskFolder, [baseFileName '.png']);
% Save the mask image for later recall if desired.
imwrite(binaryMask, maskFileName, 'png');
% Refresh the listbox of mask filenames.
% Load list of mask images in the app\masks folder.
handles=LoadMaskLists(handles);
end
% guidata(hObject, handles);
catch ME
errorMessage = sprintf('Error in function %s() at line %d.\n\nError Message:\n%s', ...
ME.stack(1).name, ME.stack(1).line, ME.message);
set(handles.txtInfo, 'String', errorMessage);
WarnUser(errorMessage);
end
Aline
le 5 Sep 2014
Image Analyst
le 5 Sep 2014
It all depends on where the uiwait()s and uiresume()s are. After the OpeningFcn(), GUIDE will put this:
% UIWAIT makes untitled wait for user response (see UIRESUME)
% uiwait(handles.figure1);
It's commented out. In my apps I don't see it so I think I must usually delete it since it's not needed. Did you uncomment it?
Aline
le 5 Sep 2014
Image Analyst
le 5 Sep 2014
I would not do that. It should work fine without doing any of that.
Aline
le 5 Sep 2014
Image Analyst
le 5 Sep 2014
I suggest you put lines in like this to every function to see when they get run:
fprintf('Now entering blahblahblah()...\n')
% code for blahblahblah()
fprintf('Now leaving blahblahblah()...\n')
You'll see the OutputFcn() gets run both on startup and shutdown. I usually have a button called btnExit, but you can call it OK if that's what you want. When the user clicks it, this is the code that runs to shutdown the GUI:
%=====================================================
% --- Executes on button press in btnExit.
function btnExit_Callback(hObject, eventdata, handles)
% hObject handle to btnExit (see GCBO)
% eventdata reserved - to be defined in a future version of MATLAB
% handles structure with handles and user data (see GUIDATA)
try
fprintf(1, 'Just entered btnExit_Callback...\n');
fprintf('Saving settings and parameters...');
SaveUserSettings(handles, 1);
% Get rid of variables from the global workspace so that they aren't
% hanging around the next time we try to run this m-file.
clear global;
% Cause it to shutdown.
delete(handles.figMainWindow);
fprintf(1, 'Leaving btnExit_Callback.\n');
catch ME
errorMessage = sprintf('Error in function btnExit_Callback.\nError Message:\n%s', ME.message);
WarnUser(errorMessage);
end
SaveUserSettings() is a custom written routine where I save the state of all controls on the GUI (checkbox states, scroll bar values, etc.). WarnUser is simply this:
%======================================================
% Warn user via the command window and a popup message.
function WarnUser(warningMessage)
fprintf(1, '%s\n', warningMessage);
uiwait(warndlg(warningMessage));
return; % from WarnUser()
Aline
le 5 Sep 2014
Jan
le 19 Oct 2014
0 votes
I recently experienced a very similar problem: The callback function of a button drawed several ROIs from memory using imellipse . Thereafter, a uiwait(f) was called for the user to corrigate these ROIs. However, this uiwait(f) did not work.
Solution: call uiwait twice, like you did. Alternatively, You can call pause(0.001) before calling uiwait (once).
I did not got to the root of this problem, but this worked for me. Apperently there are indeed some problems when combining imroi functions and uiwait.
I too experienced the same problem (in R2014b) and found that re-calling `uiwait` in the `impoly`-containing callback function was necessary. Would be interested to know the reason the original `uiwait` is neglected in this case.
Catégories
En savoir plus sur ROI-Based Processing dans Centre d'aide et File Exchange
Produits
Community Treasure Hunt
Find the treasures in MATLAB Central and discover how the community can help you!
Start Hunting!