3D ROI Manager Jython

fiji
3d
imagej

#1

Hi all,

Is there any documentation for using the 3D ROI Manager in python ?
I know there are a couple of functions available using the macro language, but it doesn’t work in Jython as it’s using macro extensions.

Thanks.


#2

hi @lguerard,

Yes it is a bit difficult to use the functions hiding in macro extensions. I would refer you to the code of the 3D suite library. Basically you have to create a population of 3D objects and loop over the objects. Here a basic Jython example :

from mcib3d.geom import Objects3DPopulation
from mcib3d.image3d import ImageInt
from ij import IJ,WindowManager

# get current image, an image with labelled objects
plus=WindowManager.getCurrentImage()
# wrap ImagePlus into 3D suite image format
img=ImageInt.wrap(plus)
# create a population of 3D objects
pop=Objects3DPopulation(img)
nb=pop.getNbObjects()
# loop over the objects
for i in range(0,nb):
	obj=pop.getObject(i)
	print(obj.getVolumeUnit())

Hope this helps

Best

Thomas


#3

Hi @ThomasBoudier

Thanks a lot for your help, I could find everything I wanted (so far at least !) thanks to your example and github :slight_smile:

For those interested, I was able to get the Volume, Mean Intensity and Feret Diameter that way

from mcib3d.geom import Objects3DPopulation
from mcib3d.image3d import ImageInt, ImageHandler
from ij import IJ,WindowManager

img = ImageInt.wrap(impWatershed)
# create a population of 3D objects
pop = Objects3DPopulation(img)
nb = pop.getNbObjects()
IHimp2 = ImageHandler.wrap(imp2)
# loop over the objects
for i in range(0, nb):
    obj = pop.getObject(i)
    # print(obj.getVolumeUnit())
    # print(obj.getIntegratedDensity())
    
    # Measure volume unit
    print(obj.getMeasure(2))

    # Measure mean intensity
    print(obj.getPixMeanValue(IHimp2))

    # Measure feret
    print(obj.getFeret())

#4

Hi @ThomasBoudier,

Sorry again for bothering you, I still have a question about the 3D Object Population.

In the GUI of the manager, you can easily discard objects touchins the edges in XY and objects touching the edges in Z. And these are separate.

Is it possible to do the same thing via script ? I only saw the touchingBorders function which does it for XY AND Z. Is there an easy way to do it ? Or should I just use:

   public boolean touchBorders(ImageHandler img, boolean Z) {
       int[] bb = getBoundingBox();
       // 0
       if ((bb[0] <= 0) || (bb[2] <= 0)) {
           return true;
       }
       #if (Z && (bb[4] <= 0)) {
       #    return true;
       #}
       // max
       if ((bb[1] >= img.sizeX - 1) || (bb[3] >= img.sizeY - 1)) {
           return true;
       }
       return Z && (bb[5] >= img.sizeZ - 1);
   }

Thanks !