Create and save imfreehand() positions until the user clicks a button to finish
You are now following this question
- You will see updates in your followed content feed.
- You may receive emails, depending on your communication preferences.
An Error Occurred
Unable to complete the action because of changes made to the page. Reload the page to see its updated state.
Show older comments
Hi,
I want an image to open and the user to draw ROI with imfreehand() until they are finished - with the co-ordinates saved into structured array - - the following code does it for 3 regions of interest - - but how can i do this until the user is finished? Would be good to have an undo button too - which not only deletes the region of interest but also deletes xy co-ordinates in the array. Thanks!!
img = imread('myfig.jpg')
imshow(img)
i = 1;
for i = 1:3
hFH(i) = imfreehand();
xy{i} = hFH(i).getPosition;
end
Accepted Answer
Marc Jakobi
on 7 Oct 2016
Edited: Marc Jakobi
on 7 Oct 2016
You could use
img = imread('myfig.jpg')
imshow(img)
i = 1;
finished = 'NO';
i = 1;
while strcmpi(finished,'NO')
hFH(i) = imfreehand();
finished = questdlg('Finished?', ...
'confirmation', ...
'YES', 'NO', 'UNDO', 'NO');
if strcmpi(finished, 'UNDO')
delete(hFH(i))
finished = 'NO';
else
xy{i} = hFH(i).getPosition;
i = i + 1;
end
end
7 Comments
cgenes
on 7 Oct 2016
This is great thanks! but rather than a dialogue box how about a push button? i'm getting confused about how to interrogate the status of the push button in the while loop
Here's one way you could do it using push buttons in the figure. This is a simple trick that uses the axes's 'Tag' property to decide on what to do.
You will have to play around with the 'Position' properties to get them in the correct positions. I set the units to 'normalized', which is respective to the figure's position, which in turn is normalized to the computer screen.
img = imread('myfig.jpg');
%position vector is [left, bottom, width, height]
f = figure('Units','normalized', ...
'Position',[0.25 0.25 0.5 0.5]);
ax = axes('Position',[0 0 0.8 1]);
imshow(img)
nextButton = uicontrol('String', 'NEXT', 'Style', ...
'pushbutton', 'Units', 'normalized', 'FontSize', 14);
nextButton.Position = [0.8 0.8 0.1 0.05];
% This function executes when the button is clicked
nextButton.Callback = 'set(gca,''Tag'',''continue'');';
undoButton = uicontrol('String', 'UNDO', 'Style', ...
'pushbutton', 'Units', 'normalized', 'FontSize', 14);
undoButton.Position = [0.8 0.7 0.1 0.05];
undoButton.Callback = 'set(gca,''Tag'',''undo'');';
finishButton = uicontrol('String', 'FINISHED', 'Style', ...
'pushbutton', 'Units', 'normalized', 'FontSize', 14);
finishButton.Position = [0.8 0.6 0.1 0.05];
finishButton.Callback = 'set(gca,''Tag'',''finished'');';
ax.Tag = 'continue';
i = 1;
while strcmp(ax.Tag, 'continue')
hFH(i) = imfreehand();
ax.Tag = 'waiting';
%wait for ax.Tag to be changed by button click
waitfor(ax,'Tag')
if strcmp(ax.Tag, 'undo')
delete(hFH(i))
ax.Tag = 'continue';
elseif strcmp(ax.Tag, 'continue') || strcmp(ax.Tag, 'finished')
xy{i} = hFH(i).getPosition;
i = i + 1;
end
end
close(f)
cgenes
on 8 Oct 2016
This is brilliant thanks very much! :-) The delete in the dialogue box approach seems to just delete the region of interest on the image but not the data saved in the array, while in the push button example it deletes the saved XY co-ordinates too. Odd.
Just one last thing (sorry!!) when I click on the zoom in button on the figure (which is very useful) none of the buttons ('next', 'finish', 'undo') - work any more! is there an easy way to fix this?
That's because clicking on the zoom button stops the imfreehand() function. That can be solved with another waitfor() trick. P. S. if you like my answer, please accept it ;)
This version should be almost fool proof:
img = imread('myfig.jpg');
f = figure('Units','normalized', ...
'Position',[0.25 0.25 0.5 0.5]);
ax = axes('Position',[0 0 0.8 1]);
imshow(img)
nextButton = uicontrol('String', 'GET DATA', 'Style', ...
'pushbutton', 'Units', 'normalized', 'FontSize', 14);
nextButton.Position = [0.8 0.8 0.13 0.05];
% This function executes when the button is clicked
nextButton.Callback = 'set(gca,''Tag'',''continue'');';
undoButton = uicontrol('String', 'UNDO', 'Style', ...
'pushbutton', 'Units', 'normalized', 'FontSize', 14);
undoButton.Position = [0.8 0.7 0.13 0.05];
undoButton.Callback = 'set(gca,''Tag'',''undo'');';
undoButton.Enable = 'off';
finishButton = uicontrol('String', 'FINISHED', 'Style', ...
'pushbutton', 'Units', 'normalized', 'FontSize', 14);
finishButton.Position = [0.8 0.6 0.13 0.05];
finishButton.Callback = 'set(gca,''Tag'',''finished'');';
finishButton.Enable = 'off';
infoBox = uicontrol('String',{'Zoom in or out of image.',...
'Click GET DATA to place freehand region.'},'Style','Text',...
'Units', 'normalized', 'BackgroundColor', [1 1 1]);
infoBox.Position = [0.7 0.2 0.8 0.3];
infoBox.HorizontalAlignment = 'left';
infoBox.FontSize = 11;
ax.Tag = 'continue';
i = 1;
while strcmp(ax.Tag, 'continue')
ax.Tag = 'waiting';
waitfor(ax,'Tag')
f.MenuBar = 'none';
infoBox.String{1} = 'Place freehand region.';
infoBox.String{2} = '';
hFH(i) = imfreehand();
infoBox.String{1} = 'Click a button to continue.';
nextButton.String = 'NEXT';
undoButton.Enable = 'on';
finishButton.Enable = 'on';
ax.Tag = 'waiting';
%wait for ax.Tag to be changed by button click
waitfor(ax,'Tag')
if strcmp(ax.Tag, 'undo')
delete(hFH(i))
ax.Tag = 'continue';
elseif strcmp(ax.Tag, 'continue') || strcmp(ax.Tag, 'finished')
xy{i} = hFH(i).getPosition;
i = i + 1;
end
undoButton.Enable = 'off';
finishButton.Enable = 'off';
f.MenuBar = 'figure';
nextButton.String = 'GET DATA';
infoBox.String{1} = 'Zoom in or out of image.';
infoBox.String{2} = 'Click GET DATA to place freehand region.';
end
close(f)
cgenes
on 10 Oct 2016
This is great!!! - -thanks very much !! :-) I am going to try and incorporate a "back" button as well, just in case they start doing a ROI but then think better of it - i'll have a think about that Charlie
Marc Jakobi
on 10 Oct 2016
No problem :) I would suggest you look into object oriented programming in Matlab. If you create your GUI as a class, it'll be a lot more flexible if you ever have to make changes.
Hashir Tanveer
on 20 Feb 2020
Hi Marc, How can i extract or separate the ROI based on the coordinates of that same ROI. I want to use those coordinates to crop the ROI of many images of same scene. Can you help me in that?
More Answers (0)
Categories
Find more on Convert Image Type in Help Center and File Exchange
See Also
Community Treasure Hunt
Find the treasures in MATLAB Central and discover how the community can help you!
Start Hunting!Select a Web Site
Choose a web site to get translated content where available and see local events and offers. Based on your location, we recommend that you select: .
You can also select a web site from the following list
How to Get Best Site Performance
Select the China site (in Chinese or English) for best site performance. Other MathWorks country sites are not optimized for visits from your location.
Americas
- América Latina (Español)
- Canada (English)
- United States (English)
Europe
- Belgium (English)
- Denmark (English)
- Deutschland (Deutsch)
- España (Español)
- Finland (English)
- France (Français)
- Ireland (English)
- Italia (Italiano)
- Luxembourg (English)
- Netherlands (English)
- Norway (English)
- Österreich (Deutsch)
- Portugal (English)
- Sweden (English)
- Switzerland
- United Kingdom (English)