MATLAB Answers

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

6 views (last 30 days)
Harry Andrews
Harry Andrews on 26 Jul 2018
Answered: Tim Jackman on 21 Sep 2018
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
Harry Andrews
Harry Andrews on 26 Jul 2018
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

Guillaume
Guillaume on 26 Jul 2018
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
Guillaume
Guillaume on 26 Jul 2018
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)

Tim Jackman
Tim Jackman on 21 Sep 2018
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!

Translated by