How to create ROI object handle?

h = figure;
imshow(imread('pout.tif'));
imrect();
hg = findobj(h,'Type','hggroup')
% How can I "create" a ROI object so that I can call createMask()?
I'm trying to get ROI object handle, but it seems that it can not be retrieved after creation. Through property inspector, I found hggroup might be related to it. However, it is not the same as the handle returned by imrect().
Can I use hg to create a handle so that I can call createMask()?
Edit:
The main problem is that I have to get the ROI object after its creation. In my application, the ROI creation is done in a callback, thus I can not get an output from it. So I need to find out information about ROI object from figure handle.

Respuestas (3)

Eric Delgado
Eric Delgado el 30 de Sept. de 2022
figure;
imshow(imread('pout.tif'));
% Directly draw your rectangle using your mouse:
roi = drawrectangle;
% Draw your rectangle programmatically:
% roi = images.roi.Rectangle(gca,'Position',[x,y,W,H]);

4 comentarios

Xingwang Yong
Xingwang Yong el 3 de Oct. de 2022
This is trivial if I use the output of drawrectangle() or output of imrect() directly. What I want is to retrive the ROI object AFTER creattion. I should have made my question clear. I've edited the original question.
So... imrect() is not recommended by Mathworks anymore. A good approach is to replace it by drawrectangle and use findobj (or findall) to get your roi handle.
fig = figure;
ax1 = axes(fig);
imshow(imread('pout.tif'));
roi = drawrectangle;
h = findobj('Parent', ax1, 'Type', 'images.roi.rectangle')
% h = findall(groot, 'Parent', ax1, 'Type', 'images.roi.rectangle');
The handle for a uirect() has just one public property ("Deletable"). If you use struct to see its implementation, you will get a few more...
fig = figure;
ax1 = axes(fig);
imshow(imread('pout.tif'));
h = imrect()
% h =
% imrect with properties:
% Deletable: 1
h = struct(h)
% h =
% struct with fields:
% api: [1×1 struct]
% h_group: [1×1 Group]
% draw_api: [1×1 struct]
% graphicsDeletedListener: [1×1 event.listener]
% Deletable: 1
% hDeleteContextItem: [1×1 Menu]
isequal(findobj('Type', 'hggroup'), h.h_group)
% ans =
% logical
% 1
Xingwang Yong
Xingwang Yong el 3 de Oct. de 2022
Thanks for your clarification. It seems it is not possible to go back to h given that I only have h.h_group. I hesitated to migrate to drawrectangle() because my application use old-style imrect() intensively. It might take me some time to do the migration.

Iniciar sesión para comentar.

Image Analyst
Image Analyst el 3 de Oct. de 2022
Try this:
h = figure;
imshow(imread('pout.tif'));
uiwait(helpdlg('Drag out a box'))
rRect = imrect();
pos = rRect.getPosition
mask = rRect.createMask;
figure;
imshow(mask)

7 comentarios

Instead, I want to get ROI object from the figure handle. i.e.
h = figure;
imshow(imread('pout.tif'));
imrect(); % not use the output of imrect()
roi_object = findobj(h, '','')
mask = roi_object.createMask;
I know this seems a little bit weird. Inside an ui callback function, I created a ROI using imrect(), then I want to use the ROI object in another callback function. You might say I can use techniques to pass arguments between GUI callbacks, as explained here. However, this is not possible in my appilication due to some sophiscated reasons. So I was wondering if I can get information of ROI object from the figure handle.
Not really sure what the sophisticated reasons are. One of the several methods mentioned is the FAQ is to attach your roi variable to your global handles structure: handles in GUIDE or app in AppDesigner.
handles.roi = rRect;
If it's in a callback you're all set otherwise if you're in a non-callback function you'll have to use guidata (like at the end of your startup function) to make the attachment to handles permanent. Then in whatever function you're in you can just do
rRect = handles.roi;
mask = rRect.createMask;
So tell me why that is not possible.
Xingwang Yong
Xingwang Yong el 4 de Oct. de 2022
The word "not possible" I used is not accurate. I haven't tried this technique. But I think it would be tedious. I have several types of ROIs, including rect, ellipse, poly, freehand, these ROIs are constantly changing due to user interaction. Thus I need to save the ROI object into handles in every callback.
Image Analyst
Image Analyst el 4 de Oct. de 2022
Yes, if you need to save them for later. Otherwise they'll just be used within the current scope (current function). Do you need to save them for recalling them later or somewhere else? If so then you'll need a line of code to save it as soon as you've created it. How else can you recall it if you don't save it? If you don't need it later, then just use it locally/temporarily and don't worry about saving it to a global variable.
Xingwang Yong
Xingwang Yong el 4 de Oct. de 2022
Yes, I need to use them later.
How else can you recall it if you don't save it?
It might be possible. As I showed in the original question, I can get some information of ROI object from figure handle. As shown by Simon Chan, for simple ROI, the information inside figure handle is enough to create a mask.
Image Analyst
Image Analyst el 4 de Oct. de 2022
Well then you'll need to save them. What Simon showed you only works as long as the graphical roi object is still there in the axes. If you ever cleared the axes, like by displaying a different image, then it will be gone and there's no way to get it back. So if you ever plan on displaying an image, drawing an roi, and then displaying another image, you'll have to have the roi saved into a variable, rather than an object in the axes container. I don't recommend Simon's solution in the more general case of using one or more ROIs on one or more images, which is what it sounds like what you want to do.
Xingwang Yong
Xingwang Yong el 5 de Oct. de 2022
Yes, Simon's method would fail when facing sophiscated ROIs, e.g. freehand. If I can not gather enough info from figure handle, saving a variable is the only way that works.

Iniciar sesión para comentar.

Simon Chan
Simon Chan el 3 de Oct. de 2022
You may try the following:
h = figure;
imshow(imread('pout.tif'));
imrect(); % not use the output of imrect()
ax=gca;
hAx=findobj(ax.Children,'-regexp','Tag','corner marker');
x = cat(1,hAx.XData);
y = cat(1,hAx.YData);
roi = [min(x) min(y), max(x)-min(x) max(y)-min(y)]

3 comentarios

Xingwang Yong
Xingwang Yong el 3 de Oct. de 2022
Although ROI boundary information can also be retrieved from hggroup, your method make this very straightforward. Yes, your method would work for rectangular ROI and presumably for ellipse ROI, however, it is difficult to apply this to freehand or polygon ROI.
It would be ideal if we can construct a ROI object from figure handle. If we can't, I think your method is best.
You may need to tackle them differently:
h = figure;
imshow(imread('pout.tif'));
drawpolygon
ax = gca;
hAx = findobj(ax.Children,'-property','Position');
hAx.Position % Gives you the vertices for drawpolygon
Xingwang Yong
Xingwang Yong el 3 de Oct. de 2022
Yes. Although this is a little bit tedious, at least it works. Thank you Simon.

Iniciar sesión para comentar.

Productos

Versión

R2020a

Etiquetas

Preguntada:

el 30 de Sept. de 2022

Comentada:

el 5 de Oct. de 2022

Community Treasure Hunt

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

Start Hunting!

Translated by