Issue with ROI Manager?

Hi all,

I’m having a weird issue using the ROI Manager and you should also be able to find this error here:

#@ ImagePlus imp 

from ij import IJ, ImagePlus
from ij.plugin.frame import RoiManager
from ij.gui import PointRoi

import os

desktop = os.path.expanduser("~/Desktop")

rm_image = RoiManager(False)
roi = PointRoi(10, 10)
roi.setPosition(2, 2, 1)

rm_image.addRoi(roi)
rm_image.runCommand("Save", os.path.join(desktop, "test.zip"))

The script creates a PointRoi, sets the position (channel, slice, frame) and saves it via the ROI Manager. Printing these info works as well.

However, when opening the saved ROI via the ROI Manager, those infos are lost.

Am I missing something ?

Thanks.

1 Like

By the way, I also tried in Groovy previously with the same error as you can see here.

This new post has a small code to test it so I guess it’s better to keep this one.

Hello Iguerard -

I believe that you are correct in that the channel, slice, and frame
are not saved.

Roi does have channel, slice, and frame properties. That is,
these are properties of the Roi itself. However, Rois are written
out by RoiEncoder, and, as you can see from its source, it does
not write these properties out.

(Interestingly, Rois are read in by RoiDecoder, and it does – at least
for some ROI file formats – read in the channel, slice, and frame
properties.)

Thanks, mm

I am not able to reproduce this problem. Here is the Javascript I used for testing:

  rm = new RoiManager(false)
  roi = new PointRoi(10, 10)
  roi.setPosition(2, 2, 1)
  rm.addRoi(roi)
  path = IJ.getDir("home")+"desktop/point.roi";
  rm.runCommand("Save", path)
  rm.runCommand("Open", path)
  roi2 = rm.getRoi(1)
  print(roi2.getCPosition()+", "+roi2.getZPosition()+", "+roi2.getTPosition());

And here is the output:

2, 2, 1

@Wayne You are using the same RoiManager instance to recall the saved ROI.
I can reproduce @lguerard behaviour if I try to run your script in 2 times, first saving the Roi, then open a new RoiManager window and in a new script inspecting the saved Roi.

In this scenario I always get 0,0,0 using any of the 2 scripts above for ROI creation.

Below the Jython scripts,

  1. Roi creation
from ij.gui import PointRoi
from ij.plugin.frame import RoiManager
from ij import IJ

rm = RoiManager(False)
roi = PointRoi(10, 10)
roi.setPosition(2, 2, 1)
rm.addRoi(roi)

path = IJ.getDir("home")+"desktop/point.roi";
rm.runCommand("Save", path)

Then opening the roi manager (pressing t) and More>Open... to load point.roi.

  1. 2nd script printing the Roi dimensions
from ij.plugin.frame import RoiManager

RM = RoiManager()
rm = RM.getRoiManager()
roi = rm.getRoi(0)
print(str(roi.getCPosition())+", "+str(roi.getZPosition())+", "+str(roi.getTPosition()))

yield 0,0,0

1 Like

Indeed, I’m doing it in two times like you say and the positions are not there anymore.

Thanks for pointing that out ! If the RoiDecoder tries to read it, then I guess it’s a mistake that the RoiEncoder doesn’t write it ? cc @Wayne and @ctrueden

I am unable to reproduce this problem using two ROI Manager instances. The following JavaScript outputs “2, 2, 1”.

  rm = new RoiManager(false)
  roi = new PointRoi(10, 10)
  roi.setPosition(2, 2, 1)
  rm.addRoi(roi)
  path = IJ.getDir("home")+"desktop/point.roi";
  rm.runCommand("Save", path)
  rm2 = new RoiManager()
  rm2.runCommand("Open", path)
  roi2 = rm2.getRoi(0)
  print(roi2.getCPosition()+", "+roi2.getZPosition()+", "+roi2.getTPosition());

This is getting weirder and weirder…

I used exactly your code and set the language to Groovy and go 0,1,1. Same result that with Python.

import ij.IJ
import ij.plugin.frame.RoiManager
import ij.gui.PointRoi

rm = new RoiManager(false)
roi = new PointRoi(10, 10)
roi.setPosition(2, 2, 1)
rm.addRoi(roi)
path = IJ.getDir("home")+"desktop/point.roi";
rm.runCommand("Save", path)
rm2 = new RoiManager()
rm2.runCommand("Open", path)
roi2 = rm2.getRoi(0)
print(roi2.getCPosition()+", "+roi2.getZPosition()+", "+roi2.getTPosition());

Hello Wayne and Friends -

Here is some more information about what might be going on.

It looks like adding an Roi to the RoiManager causes
the (copy of the) Roi in the RoiManager to be given
the hyperstack location of the open (has focus?) image.

That is, it looks like the loss of the Roi's hyperstack
location is associated with passing the Roi through the
RoiManager and is not related to saving / reopening
the Roi.

If no image is open, the RoiManager's Roi keeps the
Roi's hyperstack location. If a non-hyperstack image
is open, the hyperstack location is lost. If a hyperstack
is open, the Roi picks up the hyperstack location of
the hyperstack’s currently displayed hyperslice.

My hint for tracking this down was the appearance of

#@ ImagePlus imp

in the script Iguerard originally posted.

Here is a demo script and its output:

from ij import IJ
from ij.gui import PointRoi
from ij.plugin.frame import RoiManager

print 'version =', IJ.getFullVersion()

rm = RoiManager (False)

print 'with no image ...'

roi = PointRoi (10, 10)
roi.setPosition (2, 2, 1)

print 'roi ...'
print  'C =', roi.getCPosition(), ', Z =', roi.getZPosition(), ', T =', roi.getTPosition()

rm.addRoi (roi)
roi_check = rm.getRoi (0)
rm.reset()

print 'roi_check ...'
print  'C =', roi_check.getCPosition(), ', Z =', roi_check.getZPosition(), ', T =', roi_check.getTPosition()

print 'with image ...'

imp = IJ.createImage ('plain image', '8-bit ramp', 256, 256, 1)
imp.show()

roi = PointRoi (20, 20)
roi.setPosition (3, 3, 2)

print 'roi ...'
print  'C =', roi.getCPosition(), ', Z =', roi.getZPosition(), ', T =', roi.getTPosition()

rm.addRoi (roi)
roi_check = rm.getRoi (0)
rm.reset()

print 'roi_check ...'
print  'C =', roi_check.getCPosition(), ', Z =', roi_check.getZPosition(), ', T =', roi_check.getTPosition()

imp.close()

print 'with hyperstack ...'

imp = IJ.createHyperStack ('hyperstack', 256, 256, 10, 10, 20, 8)
imp.setC (8)
imp.setZ (7)
imp.setT (6)
imp.show()

roi = PointRoi (30, 30)
roi.setPosition (4, 4, 3)

print 'roi ...'
print  'C =', roi.getCPosition(), ', Z =', roi.getZPosition(), ', T =', roi.getTPosition()

rm.addRoi (roi)
roi_check = rm.getRoi (0)
rm.reset()

print 'roi_check ...'
print  'C =', roi_check.getCPosition(), ', Z =', roi_check.getZPosition(), ', T =', roi_check.getTPosition()
version = 1.52r38
with no image ...
roi ...
C = 2 , Z = 2 , T = 1
roi_check ...
C = 2 , Z = 2 , T = 1
with image ...
roi ...
C = 3 , Z = 3 , T = 2
roi_check ...
C = 0 , Z = 0 , T = 0
with hyperstack ...
roi ...
C = 4 , Z = 4 , T = 3
roi_check ...
C = 8 , Z = 7 , T = 6

(My earlier claim that RoiEncoder doesn’t write out the
hyperstack location was simply wrong. It is written out
by RoiEncoder.putHeader2().)

Thanks, mm

2 Likes

Thanks to @mountain_man, this bug is fixed in the latest ImageJ daily build (1.52r55). The following JavaScript reproduces the problem. With the daily build, it outputs “2, 2, 1”. With earlier versions of ImageJ, it outputs “0, 0, 0”.

  IJ.createImage("Untitled","8-bit black",200,200,1).show()
  rm = new RoiManager(false)
  roi = new PointRoi(10, 10)
  roi.setPosition(2, 2, 1)
  rm.addRoi(roi)
  roi2 = rm.getRoi(0)
  print(roi2.getCPosition()+", "+roi2.getZPosition()+", "+roi2.getTPosition());
2 Likes

Hello Wayne -

I can confirm that, running 1.52r55, an Roi’s hyperstack
location is no longer lost by adding it to the RoiManager,
regardless of whether an image or hyperstack is open.

(I checked by running my previously posted test script,
which does more or less the same thing as the script
Wayne just posted.)

Thanks, mm

1 Like

Same here, it’s working with 1.52r55.

Thanks all of you ! :slight_smile:

1 Like