Problems using imellipse and imfreehand in the same function

1 view (last 30 days)
Hi,
I am developing a very simple GUI that will allow users to circle parts of a pixel or select a region by freehand drawing a shape. I want the user to be able to choose which type of selection method they use and have the program repeat using that command until they have selected the other method, or pushed a "Stop Selection" button.
The problem is that everything works perfectly, including the stop selection button, but when I try and change the method of selection (i.e imellipse to imfreehand), it tries to draw both of the region outline previews at the same, gets all buggy, and just is not good, at this point though, its not throwing any matlab errors. I think it has something to do with how the:
han=imfreehand;
position = wait(han);
code works and specifically the wait command which I do not entirely understand. The part that most confuses me is how the stop selection button works perfectly, but when I try and change the method, it doesn't work at all.
I have uploaded the fig window, the mfile, and a sample image here so you can feel free to download it and play around with it, its kind of fun actually! :)
And if you could figure out my logic mistake, that would be fantastic!!
The code for the mfile is attached below, I just included the callbacks actually being used.
Here are my main variables and a brief explanation:
%Main Variables:
%gray - Grayscale image matrix (Never changes)
%plot_points - the points that are plotted
%pp_new - plot points that are new or from the most recent shape,
%plotted in different color
%init_map - This recoreds how many times a shape was drawn over the
%pixels, to be used later
%stop_trigger, if 1, it should not ask user to draw shape
%draw_choice, 1 for ellipse, 2 for free draw
% --- Executes on button press in stop_selection.
function stop_selection_Callback(hObject, eventdata, handles)
global stop_trigger
global plot_points
global pp_new
global gray
stop_trigger=0;%Set stop trigger to 0
imshow(gray) %Display the background image on the axes
try %If there is data to plot..
hold on
plot(plot_points(:,2), plot_points(:,1), 'r', 'LineWidth', 2)
%Plot the border
plot(pp_new(:,2), pp_new(:,1), 'b', 'LineWidth', 2)
%Plot latest selection in blue
hold off
end
guidata(hObject, handles)
% --- Executes on button press in draw_ellipse.
function draw_ellipse_Callback(hObject, eventdata, handles)
global draw_choice %1-Ellipse; 2-Freedraw
draw_choice=1; %Set draw choice to ellipse
draw_image(hObject, eventdata, handles) %Call image function
guidata(hObject, handles)
% --- Executes on button press in freedraw_shape.
function freedraw_shape_Callback(hObject, eventdata, handles)
global draw_choice %1-Ellipse; 2-Freedraw
draw_choice=2; %Set draw choice to freedraw
draw_image(hObject, eventdata, handles) %Call image function
guidata(hObject, handles)
function draw_image(hObject, eventdata, handles)
global stop_trigger
global gray
global plot_points
global pp_new
global init_map
global draw_choice %1-Ellipse; 2-Freedraw
stop_trigger=1;
while stop_trigger
%If undo
%UNDO (subtract plot_points matrix addition)
%else
while draw_choice==1 && stop_trigger
%While user hasn't pushed a button to change the settings
han=imellipse;
%Get handles from imellipse?
position = wait(han);
%Wait for user to finalize selection
try
BW = createMask(han); %Create a logic mat of the area selected
catch %#ok<*CTCH>
stop_trigger=0;
%If you can't do that, we know there was an error with the
%selection, and we shouldnt try and plot anything
end
if stop_trigger
%i.e there was no problem above
[pp_new,L] = bwboundaries(BW,'noholes');
%Get boundries of the mask created of the shape selected
pp_new=pp_new{1};
%Get the coordinates out of the array
plot_points = [ [NaN NaN]' plot_points' [NaN NaN]' pp_new']'; %#ok<*AGROW>
%Plot boundry points, this is all of the boundries of all
%shapes together, they just get appended to the list with NaN's
%seperating each entry
init_map=init_map+BW;
%init_map reflects how many times a pixel was selected, to be
%used later
imshow(gray)
%Show image again
hold on
plot(plot_points(:,2), plot_points(:,1), 'r', 'LineWidth', 2)
%Plot all the borders
plot(pp_new(:,2), pp_new(:,1), 'b', 'LineWidth', 2)
%Plot latest selection in blue (highlights over)
hold off
end
end
while draw_choice==2 && stop_trigger
%While user hasn't pushed a button to change the settings
han=imfreehand;
%Get handles from freehand ROI
position = wait(han);
%Wait for user to finalize selection
try
BW = createMask(han); %Create a logic mat of the area selected
catch %#ok<*CTCH>
stop_trigger=0;
%If you can't do that, we know there was an error with the
%selection, and we shouldnt try and plot anything
end
if stop_trigger
%i.e there was no problem above
[pp_new,L] = bwboundaries(BW,'noholes');
%Get boundries of the mask created of the shape selected
pp_new=pp_new{1};
%Get the coordinates out of the array
plot_points = [ [NaN NaN]' plot_points' [NaN NaN]' pp_new']'; %#ok<*AGROW>
%Plot boundry points, this is all of the boundries of all
%shapes together, they just get appended to the list with NaN's
%seperating each entry
init_map=init_map+BW;
%init_map reflects how many times a pixel was selected, to be
%used later
imshow(gray)
%Show image again
hold on
plot(plot_points(:,2), plot_points(:,1), 'r', 'LineWidth', 2)
%Plot all the borders
plot(pp_new(:,2), pp_new(:,1), 'b', 'LineWidth', 2)
%Plot latest selection in blue (highlights over)
hold off
end
end
end %End of while stop_trigger loop
guidata(hObject, handles)

Answers (3)

Image Analyst
Image Analyst on 1 Jul 2012
I've seen this before, and it's been discussed here before - I don't have the link though. Basically you're in a loop and you want to be able to click a button to set a flag that will let you bail out of the loop. There are at least two solutions. One, is to use a checkbox instead of a pushbutton, and the other (better) solution is to replace stop_trigger with handles.stop_trigger everywhere, except in the "global stop_trigger" statements which you can then get rid of. Try that. I guarantee it will work.
  3 Comments
Image Analyst
Image Analyst on 1 Jul 2012
I did download your files, put in the fix to make your image grayscale so it wouldn't crash, then put in my fix, and it worked perfectly. I could draw multiple ellipses, click Stop Selection, then draw multiple freehand areas. If you go right from draw ellipse to draw freehand, it still seems to have problems though - haven't had time to figure that out yet.
Shaun VanWeelden
Shaun VanWeelden on 31 Oct 2012
This question is from back in the beginning of July, and I never got back to your last comment, I knew that when pushing Stop Selection, it would work, that worked from the start, the thing is its annoying and easy to forget to push "Stop Selection" every time you want to change. The problem definitely still remains of how to go seamlessly from one to the other without breaking in the middle. Right now, I am encapsulating most of it in try and catch calls, which will pretty much allow you to click a couple times which some how ends it with no errors and then you can start fresh, but that is certainly not ideal either. I have developed every part of the code outside of that substantially since July, but if you are up to a challenge, or have another idea that comes to mind about solving this, it is still very much a problem. Thanks!

Sign in to comment.


Stavros
Stavros on 9 Jun 2013
I have been having the same problem. I guess the OP didn't find a solution after all?

Ramaprasad Kulkarni
Ramaprasad Kulkarni on 16 Sep 2013
I too am working on similar problem except that I have option of users updating a new image on the axes in which an image and ellipse was displayed. When a new image gets updated, the handles to the ellipse is deleted. I don't know how to retain it. If OP or anyone else finds a solution, please share it.

Community Treasure Hunt

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

Start Hunting!