How to Move Multiple ROI's at the same time?

Hi Everyone :)
I have 4 ROI's on an image, and I want to move the left two, and then the right two collectively in the figure (So grouping two ROIs to move simultaneously). Is there a way to do this?
Thank You!!

4 Comments

What does "move a roi in a figure" actually mean?
This will create a figure:
figure;
What is supposed to move, and where is it supposed to move in there?
Sorry, I'm awful at explaining myself thoroughly, thanks for helping!
The image below is what I have, with 4 ROI regions set in the code.
I now want to move (drag and drop) the left two (and right two - but separately) as a group.
How are these roi created in your image?
Below is the impoly definitions. The Coords LPP1 etc. are set elsewhere, but are just pixel coordinates within the image.
LPutamen = impoly(gca,[LPP1; LPP2; LPP3; LPP4]);
RPutamen = impoly(gca,[RPP1; RPP2; RPP3; RPP4]);
LCaudate = impoly(gca,[LCP1; LCP2; LCP3; LCP4; LCP5]);
RCaudate = impoly(gca,[RCP1; RCP2; RCP3; RCP4; RCP5]);

Sign in to comment.

 Accepted Answer

What you want is not really supported by impoly. You could sort of fake it by merging the two polygon positions separated with row of nans and ending with another row of nan to prevent the closing of the final polygon.
mergedcoordinates = [[LPP1; LPP2; LPP3; LPP4; %original poly
LPP1; %to close the first polygon
nan nan; %to separate the 2nd polygon
RPP1; RPP2; RPP3; RPP4; %2nd polygon
RPP1; %to close the 2nd polygon
nan nan] %to prevent closing back to LPP1
mergedpoly = impoly(gca, mergedcoordinates);
This works in that you can drag both polygon together but breaks a lot of other things (such as impoly.createMask.

2 Comments

Ah, this is great, but unfortunately doesn't work for exactly the reason you mentioned. It's not a massive problem, I think I'll just do without!
Thank you for your help!
Actually, I've just thought of a way how you could implement what you want properly. As I'm just about to head out, I'll leave the implementation details to the reader...
  • For each impoly that needs to be linked, add a position callback with addNewPositionCallback
  • Whenever a callback is called move the linked polygons.
Two tricky bits there: The position callback doesn't tell you what the original position was. You'd have to keep track of that somehow. The second tricky bit is to prevent circular calling of callbacks. When a polygon is moved by a callback it mustn't trigger its own callback.
The callback would be something like:
function movecallback(sourcepoly, linkedpolys, newposition)
%sourcepoly: handle to impoly that triggered the callback
%linkedpolys: cell array of handles of impoly. All the polygons linked to sourcepoly
%newposition: new position of sourcepoly (from position callback)
%work out how much sourcepoly has moved
deltapos = ????
%work out how to prevent circular calling of callbacks
????
%move linked polygons
cellfun(@(lp) lp.setPosition(lp.getPosition + deltapos), linkedpolys);
end
And you'll attach the callbacks with for example:
LPutamen.addNewPositionCallback(@(pos) movecallback(LPutamen, {RPutamen}, pos));
RPutamen.addNewPositionCallback(@(pos) movecallback(RPutamen, {LPutamen}, pos));

Sign in to comment.

More Answers (1)

This should be doable with drawpolygon, the new ROI released with 18b. Here is an example that allows you draw two polygons, and then wire them up such that any translation applied to one ROI is also applied to the other.
figure;
hAx = axes;
% Construct two Polygons
hROI1 = drawpolygon(hAx,'Tag','ROI1','InteractionsAllowed','translate');
hROI2 = drawpolygon(hAx,'Tag','ROI2','Color',[1 0 0],'InteractionsAllowed','translate');
% Add listener to update the other ROI when moved
addlistener(hROI1,'MovingROI',@movingCallback);
addlistener(hROI2,'MovingROI',@movingCallback);
function movingCallback(~,evt)
% Use findobj to identify which ROI moved
hROI1 = findobj(gcf,'Tag','ROI1');
hROI2 = findobj(gcf,'Tag','ROI2');
delta = evt.CurrentPosition(1,:) - evt.PreviousPosition(1,:);
% If we move one ROI, set the position of the other
if evt.Source == hROI1
hROI2.Position = hROI2.Position + delta;
else
hROI1.Position = hROI1.Position + delta;
end
end

Tags

Community Treasure Hunt

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

Start Hunting!