I have created a small GUI to enable editing of ROIs in MR datasets with multiple frames and slices. Inside the GUI I use impoly, imrect or imellipse to draw ROIs.
I would like to be able to return a drawn ROI to the commandline e.g.:
roi=guifunction(image);
inside the GUI I have uncommented uiwait(handles.figure1); and execution stops while my GUI is running untill I draw the first ROI. It seems as if impoly and other im... functions resumes the commandline and returns the ROIs to early.
Is there some way of avoiding this?
I also tried h=impoly(handles.axes); pos=wait(h); but this only makes it possible to edit the ROI. As soon as I doubleclick the ROI to "close" it the gui returns the outputs I have selected.
Here's some freehand drawing ROI code that may help you:
% Change the current folder to the folder of this m-file.
if(~isdeployed)
cd(fileparts(which(mfilename)));
end
clc; % Clear command window.
clear; % Delete all variables.
close all; % Close all figure windows except those created by imtool.
imtool close all; % Close all figure windows created by imtool.
workspace; % Make sure the workspace panel is showing.
fontSize = 20;
% Read in standard MATLAB gray scale demo image.
grayImage = imread('cameraman.tif');
subplot(2, 2, 1);
imshow(grayImage, []);
title('Original Grayscale Image', 'FontSize', fontSize);
set(gcf, 'Position', get(0,'Screensize')); % Maximize figure.
message = sprintf('Left click and hold to begin drawing.\nSimply lift
the mouse button to finish');
uiwait(msgbox(message));
hFH = imfreehand();
% Create a binary image ("mask") from the ROI object.
binaryImage = hFH.createMask();
% Display the freehand mask.
subplot(2, 2, 2);
imshow(binaryImage);
title('Binary mask of the region', 'FontSize', fontSize);
% Calculate the area, in pixels, that they drew.
numberOfPixels1 = sum(binaryImage(:))
% Another way to calculate it that takes fractional pixels into
account.
numberOfPixels2 = bwarea(binaryImage)
% Get coordinates of the boundary of the freehand drawn region.
structBoundaries = bwboundaries(binaryImage);
xy=structBoundaries{1}; % Get n by 2 array of x,y coordinates.
x = xy(:, 2); % Columns.
y = xy(:, 1); % Rows.
subplot(2, 2, 1); % Plot over original image.
hold on; % Don't blow away the image.
plot(x, y, 'LineWidth', 2);
% Burn line into image by setting it to 255 wherever the mask is true.
burnedImage = grayImage;
burnedImage(binaryImage) = 255;
% Display the image with the mask "burned in."
subplot(2, 2, 3);
imshow(burnedImage);
title('New image with mask burned into image', 'FontSize', fontSize);
% Mask the image and display it.
% Will keep only the part of the image that's inside the mask, zero
outside mask.
maskedImage = grayImage;
maskedImage(~binaryImage) = 0;
subplot(2, 2, 4);
imshow(maskedImage);
title('Masked Image', 'FontSize', fontSize);
% Calculate the mean
meanGL = mean(maskedImage(binaryImage));
% Report results.
message = sprintf('Mean value within drawn area = %.3f\nNumber of
pixels = %d\nArea in pixels = %.2f', ...
meanGL, numberOfPixels1, numberOfPixels2);
msgbox(message);
I have generated a quick example using guide. The GUI contains a figure window, one button which initiates the impoly command and the goal is to return multiple ROIs drawn in the gui, when closing the gui.
The file is available her: http://alberg.dk/testgui.zip
1) run the file as roi=testgui();
2) as soon as the first roi is drawn it is returned in the roi variable (which I don't want)
3) More rois can be drawn but will of course not be returned to the roi variable outside the gui
Cheers
David
testgui.m (testgui.fig can be dowloaded from the above link):
function varargout = testgui(varargin)
% TESTGUI M-file for testgui.fig
% TESTGUI, by itself, creates a new TESTGUI or raises the existing
% singleton*.
%
% H = TESTGUI returns the handle to a new TESTGUI or the handle to
% the existing singleton*.
%
% TESTGUI('CALLBACK',hObject,eventData,handles,...) calls the local
% function named CALLBACK in TESTGUI.M with the given input arguments.
%
% TESTGUI('Property','Value',...) creates a new TESTGUI or raises the
% existing singleton*. Starting from the left, property value pairs are
% applied to the GUI before testgui_OpeningFcn gets called. An
% unrecognized property name or invalid value makes property application
% stop. All inputs are passed to testgui_OpeningFcn via varargin.
%
% *See GUI Options on GUIDE's Tools menu. Choose "GUI allows only one
% instance to run (singleton)".
%
% See also: GUIDE, GUIDATA, GUIHANDLES
% Edit the above text to modify the response to help testgui
% Last Modified by GUIDE v2.5 15-Nov-2010 11:54:21
% Begin initialization code - DO NOT EDIT
gui_Singleton = 1;
gui_State = struct('gui_Name', mfilename, ...
'gui_Singleton', gui_Singleton, ...
'gui_OpeningFcn', @testgui_OpeningFcn, ...
'gui_OutputFcn', @testgui_OutputFcn, ...
'gui_LayoutFcn', [] , ...
'gui_Callback', []);
if nargin && ischar(varargin{1})
gui_State.gui_Callback = str2func(varargin{1});
end
if nargout
[varargout{1:nargout}] = gui_mainfcn(gui_State, varargin{:});
else
gui_mainfcn(gui_State, varargin{:});
end
% End initialization code - DO NOT EDIT
% --- Executes just before testgui is made visible.
function testgui_OpeningFcn(hObject, eventdata, handles, varargin)
% This function has no output args, see OutputFcn.
% hObject handle to figure
% eventdata reserved - to be defined in a future version of MATLAB
% handles structure with handles and user data (see GUIDATA)
% varargin command line arguments to testgui (see VARARGIN)
% Choose default command line output for testgui
handles.output = hObject;
% Update handles structure
grayImage = imread('cameraman.tif');
imagesc(grayImage);axis off image;colormap gray;
handles.roicounter=0;
guidata(hObject, handles);
% UIWAIT makes testgui wait for user response (see UIRESUME)
uiwait(handles.figure1);
% --- Outputs from this function are returned to the command line.
function varargout = testgui_OutputFcn(hObject, eventdata, handles)
% varargout cell array for returning output args (see VARARGOUT);
% hObject handle to figure
% eventdata reserved - to be defined in a future version of MATLAB
% handles structure with handles and user data (see GUIDATA)
% Get default command line output from handles structure
varargout{1} = handles.rois;
% --- Executes on button press in pushbutton1.
function pushbutton1_Callback(hObject, eventdata, handles)
% hObject handle to pushbutton1 (see GCBO)
% eventdata reserved - to be defined in a future version of MATLAB
% handles structure with handles and user data (see GUIDATA)
h=impoly;
handles.roicounter=handles.roicounter+1;
handles.rois{handles.roicounter}=h.getPosition;
guidata(hObject,handles);
ImageAnalyst <imagea...@mailinator.com> wrote in message <5bfae07c-31cc-4f32...@v23g2000vbi.googlegroups.com>...
I would use roipolyold instead of impoly. Then ask the user for
confirmation if they like the ROI they just drew and want to keep it.
It just seems a little easier. Otherwise you'll have to give your use
instructions on how to close the polygon and then finish it off and
exit out of drawing mode.
When you take the mean of the masked image, what exactly are taking the mean of? Are you getting the mean rgb, greyscale? If rgb, can you select red, green, blue individually?
Thanks,
Jeff
% Extract the individual red, green, and blue color planes.
redPlane = rgbImage(:, :, 1);
greenPlane = rgbImage(:, :, 2);
bluePlane = rgbImage(:, :, 3);
maskedRed = redPlane .* mask;
maskedGreen = greenPlane .* mask;
maskedBlue = bluePlane .* mask;
and then basically do the same thing to each color plane as you did to
the gray scale image to get the means of each color plane.