copy Freehand object from a figure and pate into another figure

3 views (last 30 days)
Hi there,
I have used the drawfreehand function in matlab using the command below to draw an roi in my figure and save it:
z = drawfreehand();
save('roi.mat', 'z');
so now when i type z in the command window I will get the following Freehand object :
z =
Freehand with properties:
Position: [298×2 double]
Closed: 1
Label: ''
Multiclick: 0
Color: [0 0.4470 0.7410]
Parent: [1×1 Axes]
Visible: 'on'
Selected: 0
Now I would like to copy this freehand object and display it on another figure in the excat same position.
It would be noice if i can move it around as well on the new figure
could you please kindly help me with this issue?
Best,
Nikan

Accepted Answer

Image Analyst
Image Analyst on 1 Aug 2021
Edited: Image Analyst on 1 Aug 2021
In your other program, use load() to load it in and then use plot() to display it
figure(1);
rgbImage = imread('peppers.png');
imshow(rgbImage);
uiwait(msgbox('Draw a freehand roi'));
roi = drawfreehand('Color', 'yellow');
% Save it
save('roi.mat', 'roi');
% Make new figure
figure(2);
rgbImage = imread('peppers.png');
imshow(rgbImage);
% Recall ROI
s = load('roi.mat')
freehandROI = s.roi.Position;
% % Plot it over the second image.
% x = freehandROI(:, 1);
% y = freehandROI(:, 2);
% hold on;
% plot(x, y, 'y.-', 'LineWidth', 2, 'MarkerSize', 20);
% hold off;
uiwait(msgbox('Adjust the freehand roi'));
roi = drawfreehand('Position', freehandROI, 'Color', 'yellow');
  5 Comments
Adam Danz
Adam Danz on 3 Aug 2021
@Image Analyst, the solution in your original answer (currently commented out) is what I was referring to. Your updated version doesn't have this problem. I think your new approach is better than using a listener or uiwait, although I'd still prefer using copyobj and then editing the copied obj as needed.
f1 = figure();
ax1 = axes();
grid(ax1,'on')
f2 = figure();
ax2 = axes();
linkaxes([ax1,ax2])
roi = drawfreehand(ax1);
plot(ax2, roi.Position(:,1), roi.Position(:,2), '-o')
grid(ax2,'on')
Image Analyst
Image Analyst on 3 Aug 2021
Adam, I knew about that but intentionally left it off so that if someone ran it, they would see it wasn't connected and realize they had to do it. I guess I could have closed it but I think knowing that is what happens is a good thing?
So anyway, how to keep the code from blasting onwards? One way I'm going it is to have my script or GUI open a new, separate figure and then put a button on it that says "Accept" whereupon it will close the new figure and return to the original GUI or script. Then I think there's some calls to wait(), uiwait(), or uiresume() or something very confusing and non-intuitive that I don't remember off the top of my head. Kind of clunky but it works and I don't know of any more elegant, single window way of doing it. Do you?
I did find this code for GUIDE where I could popup a new figure and draw an ellipse on the same GUI:
%=====================================================================
% Get a elliptical mask.
function mask = GetManualMask(handles, rgbImage)
try
[rows, columns, numberOfColorChannels] = size(rgbImage);
mask = true(rows, columns); % Initialize so we'll have something in case an error is thrown.
hFig = figure;
imshow(rgbImage);
hFig.WindowState = 'maximized';
h = uicontrol('Position',[20 620 200 40],'String','Accept', 'FontSize', 12, 'FontWeight', 'bold', ...
'Callback','uiresume(gcbf)');
userPrompt = sprintf('Please draw out an ellipse.\nClick the Accept button to the left when done.');
msgboxw(userPrompt);
caption = sprintf('Please draw out an ellipse.  Close the window when done.');
title(caption, 'FontSize', 14);
% Have the user interactively drag out the ellipse and adjust its size and position.
roi = drawellipse();
xy = roi.Vertices;
% Quirky other stuff needed to let the user adjust the ellipse and get back the xy coordinates.
% The listener updates xy in the base workspace when the user changes the ellipse.
addlistener(roi, 'ROIMoved', @(src,evt) assignin('base','xy',src.Vertices));
uiwait(hFig);
xy = evalin('base', 'xy'); % Get the xy coordinates from the base workspace.
mask = poly2mask(xy(:, 1), xy(:, 2), rows, columns);
imshow(mask);
drawnow;
close(hFig);
catch ME
% Some error happened if you get here.
errorMessage = GetErrorMessage(ME); % Get error message with call traceback and file's date.
WarnUser(errorMessage); % Pop up error message to show user what it is. Also prints to command window or console window (if program is an executable).
end
return; % GetManualMask

Sign in to comment.

More Answers (1)

Adam Danz
Adam Danz on 1 Aug 2021
Edited: Adam Danz on 1 Aug 2021
You could use copyobj(z,ax) where z is an existing freehand object or a freehand object saved to a mat file and ax is the handle to the new axes.

Community Treasure Hunt

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

Start Hunting!