Importing ROI coordinates for an image stack

I have an image stack and would like to draw ROIs with specific coordinates on the images. Each image in the stack would have a different ROI. Is there a way to do this if I had, for instance, a text file with the XY coordinates for the ROI and the corresponding image frame?
Edit/Selection/Specify would let me input the coordinates manually slice by slice, but my stacks are quite large (few hundred slices), so I am wondering if there is a faster way.
File/Import/XY Coordinates only allows one set of coordinates to be imported, so the same ROI gets added to every slice.
Thank you!

Use the ROI Manager to draw your ROI on the specific slice. You can save and reload your ROI’s easily, see:

https://imagej.nih.gov/ij/docs/guide/146-30.html#sub:ROI-Manager

If you want to import custom x,y values as ROI’s use the macro language to read the file and create your ROI’s on a specific slice which you can then add to the ROI Manager.

A builtin command is available, too, see:

https://imagej.nih.gov/ij/plugins/roi-importer.html

1 Like

Use the Macro Recorder of ImageJ to get the commands to read,create ROI’s and add them to the ROI Manager:

https://imagej.nih.gov/ij/docs/guide/146-31.html#sub:Record

1 Like

Thank you very much for the reply! The ROI importer command is almost exactly what I need, except it only lets you import one set of coordinates for the stack, and the resulting ROI is placed on each slice in the stack.
Is there is a way to import XY coordinates that are unique to each slice (the coordinates would all be contained in a single txt file)?
Thank you again for your help.

So basically each ROI has a X,Y but also Z coordinates if we consider the slice position.
Well if you feel confortable with another scripting language than the IJ1macro you can use the Roi and RoiManager class, in a script that would loop over the file lines.

For instance with Jython it would look like (I did not tested it and you need to rearrange according to the content of your file):

from ij.gui import Roi
from ij.plugin.frame import RoiManager

yourFile = open("PathtoFile.txt", 'r')

RM = RoiManager()
rm = RM.getRoiManager()

for line in yourFile: # assumning 1 Roi per line
      X, Y, Z, Width, Height = map( int, line.rstrip().split(',') )     
      roi = Roi(X, Y, Width, Height) #  if you have rectangular ROI
      roi.setPosition(Z) # set ROI Z-position/slice 

      rm.add(None, roi, int(Z)) # Trick to be able to set Z-position when less images than the number of ROI. line will appear as a digit index before the Roi Name  

# close file once done
yourFile.close()
				 
# Show All ROI + Associate ROI to slices  
rm.runCommand("Associate", "true")	 
rm.runCommand("Show All with labels")
2 Likes

Sorry for the late reply.
This is exactly the solution I was looking for. Thank you so much!

Hi LThomas,
I work with large image stacks and your script would be absolutely great for me if I get it to work. But so far no luck, I get the following error:

TypeError: ij.gui.Roi(): expected 1 or 3-5 args; got 2

I just need to import lists with X,Y,Z coordinates (not Width or Height) so I deleted the corresponding text from the script. My test text file looks like this:

68,50,50
300,60,05
400,70,100
200,80,200
100,90,250
50,100,330

I hope you can help.

Perhpas I do need Width and Height, so I tried again and get a new error:
TypeError: setPosition(): 1st arg can’t be coerced to ij.ImagePlus, int
Here is a screen capture:
Screen Shot

Hi @Domingo,
I think It was a mistake in the original script.
I did not convert Z to an integer so it was still a string, and therefore not recognized by the command.

Can you try replacing roi.setPosition(Z) with roi.setPosition(int(Z))
I corrected it in my original message.

If you want just points as roi and not rectangle you can replace
roi = Roi(blabla...)
by
roi = PointRoi(int(X), int(Y))
Just make sure to import PointRoi instead of Roi at the top of the script.

Also instead of screen capture you can copy past your code here and use ``` to delimitate code blocks (one triple quotes before the code block and another triple after the code block).
So that we can edit your code directly :wink:

Thanks for replying so quickly. (int(Z)) fixes the error I got for line 12, but now there is a new error at line 14. I have tried to replace “line” with int(line) but no luck.

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

yourFile = open("PathtoFilePoints.txt", 'r')

RM = RoiManager()
rm = RM.getRoiManager()

for line in yourFile: # assumning 1 Roi per line
      X, Y, Z  = line.rstrip().split(',')
      roi = PointRoi(int(X), int(Y)) #  if you have rectangular ROI
      roi.setPosition(int(Z)) # set ROI Z-position/slice 

      rm.add(None, roi, line) # Trick to be able to set Z-position when less images than the number of ROI. line will appear as a digit index before the Roi Name  

# close file once done
yourFile.close()
				 
# Show All ROI + Associate ROI to slices  
rm.runCommand("Associate", "true")	 
rm.runCommand("Show All with labels")

rm.add(None, roi, line) # Trick to be able to set Z-position when less images than the number of ROI. line will appear as a digit index before the Roi Name
TypeError: add(): 3rd arg can’t be coerced to int

Oups another issue in the initial script.
replace
rm.add(None, roi, line)
with
rm.add(None, roi, int(Z))

New error:
X, Y, Z = line.rstrip().split(’,’)
ValueError: too many values to unpack

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

yourFile = open("PathtoFilePoints.txt", 'r')

RM = RoiManager()
rm = RM.getRoiManager()

for line in yourFile: # assumning 1 Roi per line
      X, Y, Z  = line.rstrip().split(',')
      roi = PointRoi(int(X), int(Y)) #  if you have rectangular ROI
      roi.setPosition(int(Z)) # set ROI Z-position/slice 

      rm.add(None, roi, int(Z)) # Trick to be able to set Z-position when less images than the number of ROI. line will appear as a digit index before the Roi Name  

# close file once done
yourFile.close()
				 
# Show All ROI + Associate ROI to slices  
rm.runCommand("Associate", "true")	 
rm.runCommand("Show All with labels")

The file works for me with a text file containing

68,50,50
300,60,05
400,70,100
200,80,200
100,90,250
50,100,330

If you have more values you have to add variables after X ,Y, Z in the for-loop body.

I will stop here debugging the code, I proposed a working solution but I cannot adapt it for everyone, sorry :sweat_smile:
Try to understand the code, also a lot of ressources for scripting are available either on the ImageJ website or to learn basics of python scripting.

Or try to find someone in your working environment that can help you, good luck !

1 Like

I appreciate your help. Many thanks!

10 minutes later: It works now !!!
there was a problem with the text file. Very grateful.

1 Like