imagej / pyimagej

Use ImageJ from Python
https://pyimagej.readthedocs.io/
Other
473 stars 82 forks source link

Using PyimageJ to collect width by height for individual objects. #274

Open BrandonUL opened 1 year ago

BrandonUL commented 1 year ago

Hello! I have been playing around with pyimagej by completing the tutorial notebooks but I have ran into a few errors. I am reaching out for help and to see if anyone has done similar work and maybe have used different programs or code.

A little background of what I am trying to do: I am currently trying to obtain the width and height of a singular object on an image, with the end goal of creating a batch system that allows me to insert the image into my code and obtain the dimensions automatically.

I have had luck using ImageJ by using the analyzing particles feature.

This is my process for Image J:

Convert cropped images to a stack:

Per the tutorial I first ran:

# HACK: # HACK: Work around ImagePlus#show() failure if no ImagePlus objects are already registered.
if ij.WindowManager.getIDList() is None:
    ij.py.run_macro('newImage("dummy", "8-bit", 1, 1, 1);')

which returns:

---------------------------------------------------------------------------
ImportError                               Traceback (most recent call last)
Cell In[13], line 2
      1 # HACK: # HACK: Work around ImagePlus#show() failure if no ImagePlus objects are already registered.
----> 2 if ij.WindowManager.getIDList() is None:
      3     ij.py.run_macro('newImage("dummy", "8-bit", 1, 1, 1);')

File ~/anaconda3/envs/pyimagej/lib/python3.10/site-packages/imagej/__init__.py:801, in GatewayAddons.WindowManager(self)
    795 @property
    796 def WindowManager(self):
    797     """Get the original ImageJ `WindowManager` class.
    798 
    799     :return: The `ij.WindowManager` class.
    800     """
--> 801     return self._access_legacy_class("ij.WindowManager")

File ~/anaconda3/envs/pyimagej/lib/python3.10/site-packages/imagej/__init__.py:804, in GatewayAddons._access_legacy_class(self, fqcn)
    803 def _access_legacy_class(self, fqcn: str):
--> 804     self._check_legacy_active(f"The {fqcn} class is not available.")
    805     class_name = fqcn[fqcn.rindex(".") + 1 :]
    806     property_name = f"_{class_name}"

File ~/anaconda3/envs/pyimagej/lib/python3.10/site-packages/imagej/__init__.py:819, in GatewayAddons._check_legacy_active(self, usage_context)
    817 def _check_legacy_active(self, usage_context=""):
    818     if not self.legacy or not self.legacy.isActive():
--> 819         raise ImportError(
    820             "The original ImageJ is not available in this environment. "
    821             f"{usage_context} See: "
    822             "https://github.com/imagej/pyimagej/blob/main/doc/Initialization.md"
    823         )

ImportError: The original ImageJ is not available in this environment. The ij.WindowManager class is not available. See: https://github.com/imagej/pyimagej/blob/main/doc/Initialization.md

As per the next tutorial:

# open test image and convert from Dataset to ImagePlus
dataset = ij.io().open('/Users/brandonulin/Downloads/Hognut/test_scan/test3.jpeg')
imp = ij.py.to_imageplus(dataset)

# show the image
ij.py.show(imp)

which returns:

[java.lang.Enum.toString] [INFO] Populating metadata
[java.lang.Enum.toString] [INFO] Populating metadata
[java.lang.Enum.toString] [INFO] Populating metadata
[java.lang.Enum.toString] [INFO] Populating metadata
[java.lang.Enum.toString] [INFO] Populating metadata
[java.lang.Enum.toString] [INFO] Populating metadata
---------------------------------------------------------------------------
ImportError                               Traceback (most recent call last)
Cell In[14], line 3
      1 # open test image and convert from Dataset to ImagePlus
      2 dataset = ij.io().open('/Users/brandonulin/Downloads/Hognut/test_scan/test3.jpeg')
----> 3 imp = ij.py.to_imageplus(dataset)
      5 # show the image
      6 ij.py.show(imp)

File ~/anaconda3/envs/pyimagej/lib/python3.10/site-packages/imagej/__init__.py:485, in ImageJPython.to_imageplus(self, data)
    476 def to_imageplus(self, data):
    477     """Convert the data into an ImageJ ImagePlus.
    478 
    479     Converts a Python image (e.g. xarray or numpy array) or Java image (e.g.
   (...)
    483     :return: An ij.ImagePlus.
    484     """
--> 485     self._ij._check_legacy_active("Conversion to ImagePlus is not supported.")
    486     return self._ij.convert().convert(self.to_dataset(data), jc.ImagePlus)

File ~/anaconda3/envs/pyimagej/lib/python3.10/site-packages/imagej/__init__.py:819, in GatewayAddons._check_legacy_active(self, usage_context)
    817 def _check_legacy_active(self, usage_context=""):
    818     if not self.legacy or not self.legacy.isActive():
--> 819         raise ImportError(
    820             "The original ImageJ is not available in this environment. "
    821             f"{usage_context} See: "
    822             "https://github.com/imagej/pyimagej/blob/main/doc/Initialization.md"
    823         )

ImportError: The original ImageJ is not available in this environment. Conversion to ImagePlus is not supported. See: https://github.com/imagej/pyimagej/blob/main/doc/Initialization.md

The last tutorial I tried before reaching out had to do with analyzing particles like on ImageJ but it also did not work. Here is the code:

imp = ij.openImage("/Users/brandonulin/Downloads/Hognut/test_scan/test3.jpeg")
imp2 = Duplicator().run(imp, 3, 3, 1, 1, 14, 14)
IJ.run(imp, "Enhance Contrast", "saturated=0.35")
IJ.setAutoThreshold(imp, "Moments dark")
IJ.run(imp, "Analyze Particles...", "  show=Overlay display clear")

Which returns:

---------------------------------------------------------------------------
AttributeError                            Traceback (most recent call last)
Cell In[24], line 1
----> 1 imp = ij.openImage("/Users/brandonulin/Downloads/Hognut/test_scan/test3.jpeg")
      2 imp2 = Duplicator().run(imp, 3, 3, 1, 1, 14, 14)
      3 IJ.run(imp, "Enhance Contrast", "saturated=0.35")

AttributeError: 'net.imagej.ImageJ' object has no attribute 'openImage'

Simple

Like I started off with, if anyone has experience with collecting width and heights of objects within an image using either pyimagej or other programs please let me know. Any and all help would be greatly appreciated as I am excited to use this package for my summer research project. I have also included the image of what I am trying to gather the dimensions of.

test3

ctrueden commented 1 year ago

@BrandonUL I don't have time to advise on the image analysis parts right now, but a couple of quick comments that might get you unstuck technically:

ij.py.run_macro('newImage("dummy", "8-bit", 1, 1, 1);')

Newer versions of ImageJ2 no longer require this hack. If you are using imagej.init() (noargs) or imagej.init('2.13.1') then you should be good to go already while running headless. :+1:

The original ImageJ is not available in this environment.

This happens when either:

A) You called imagej.init(add_legacy=False); or B) You already created an ImageJ2 gateway in the current Python runtime, and are now trying to create a second one. Only one gateway at a time can have support for the original ImageJ. If you are using Jupyter, then the TL;DR: is to restart your kernel, then rerun the imagej.init cell exactly once and do not rerun it again while developing your notebook.

ctrueden commented 1 year ago

@BrandonUL Were you able to make progress?

elevans commented 4 months ago

Hi @BrandonUL, just following up here. Did you make any progress or need any additional help here?