Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Add conversion for BitType and BoolType imgs #264

Open
wants to merge 2 commits into
base: main
Choose a base branch
from

Conversation

gselzer
Copy link
Contributor

@gselzer gselzer commented Jun 5, 2023

Using PyImageJ, functionality that returns boolean type images, like thresholds and morphology Ops, returns those images as images of BitType and/or BoolType. PyImageJ normally converts these to DataArrays of float64, which seems suboptimal.

This change, utilizing imagej/imagej-ops#651, allows those BitType and/or BoolType images to become boolean arrays instead. Of course, we will need to wait for that PR to make its way into release before we can merge this PR.

@elevans is there a better place to put the tests I wrote?

@elevans
Copy link
Member

elevans commented Jun 15, 2023

@gselzer This looks great to me, very clean and simple. I think it makes sense to put your tests in tests/test_image_conversion.py. Just as a heads up, since JPype 1.0.0 you can create Java arrays like this:

from jpype import JLong
jarray = JLong[:] @ [15, 20, 30]

Instead of calling the JArray constructor!

@elevans
Copy link
Member

elevans commented Jan 29, 2024

@gselzer It looks like I can't convert BitType to NativeBoolType. What am I doing wrong?

Operating in headless mode - the original ImageJ will have limited functionality.
Traceback (most recent call last):
  File "Thread.java", line 829, in java.lang.Thread.run
java.lang.java.lang.ClassCastException: java.lang.ClassCastException: class net.imglib2.type.logic.BitType cannot be cast to class net.imglib2.type.logic.NativeBoolType (net.imglib2.type.logic.BitType and net.imglib2.type.logic.NativeBoolType are in unnamed module of loader 'app')

The above exception was the direct cause of the following exception:

Traceback (most recent call last):
  File "OpEnvironment.java", line 136, in net.imagej.ops.OpEnvironment.run
java.util.concurrent.java.util.concurrent.ExecutionException: java.util.concurrent.ExecutionException: java.lang.ClassCastException: class net.imglib2.type.logic.BitType cannot be cast to class net.imglib2.type.logic.NativeBoolType (net.imglib2.type.logic.BitType and net.imglib2.type.logic.NativeBoolType are in unnamed module of loader 'app')

The above exception was the direct cause of the following exception:

Traceback (most recent call last):
  File "OpEnvironment.java", line 136, in net.imagej.ops.OpEnvironment.run
Exception: Java Exception

The above exception was the direct cause of the following exception:

Traceback (most recent call last):
  File "<stdin>", line 1, in <module>
  File "/home/edward/Documents/repos/loci/pyimagej/src/imagej/__init__.py", line 193, in from_java
    return sj.to_python(data)
           ^^^^^^^^^^^^^^^^^^
  File "/home/edward/Documents/repos/loci/scyjava/src/scyjava/_convert.py", line 553, in to_python
    return _convert(data, py_converters)
           ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
  File "/home/edward/Documents/repos/loci/scyjava/src/scyjava/_convert.py", line 104, in _convert
    return converter.convert(obj, **hints)
           ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
  File "/home/edward/Documents/repos/loci/scyjava/src/scyjava/_convert.py", line 74, in convert
    else self.converter(obj)
         ^^^^^^^^^^^^^^^^^^^
  File "/home/edward/Documents/repos/loci/pyimagej/src/imagej/__init__.py", line 663, in <lambda>
    converter=lambda obj: convert.java_to_ndarray(self._ij, obj),
                          ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
  File "/home/edward/Documents/repos/loci/pyimagej/src/imagej/convert.py", line 203, in java_to_ndarray
    images.copy_rai_into_ndarray(ij, rai, narr)
  File "/home/edward/Documents/repos/loci/pyimagej/src/imagej/images.py", line 166, in copy_rai_into_ndarray
    ij.op().run("copy.rai", sj.to_java(narr), rai)
java.lang.java.lang.RuntimeException: java.lang.RuntimeException: java.util.concurrent.ExecutionException: java.lang.ClassCastException: class net.imglib2.type.logic.BitType cannot be cast to class net.imglib2.type.logic.NativeBoolType (net.imglib2.type.logic.BitType and net.imglib2.type.logic.NativeBoolType are in unnamed module of loader 'app')

@gselzer
Copy link
Contributor Author

gselzer commented Jan 29, 2024

Hmm, fails on my machine too @elevans. Looks like the object sj.to_java(narr) is a DefaultDataset with NativeBoolType elements, while rai is an ArrayImg<BitType>. Naturally, the matching copy Op doesn't handle that, because the Ops there require elements be of the same type.
Options:

  1. Write a better Op that can copy between BooleanTypes. Would take a little while to get dependable releases but probably the most correct option.
  2. Find some more explicit way to copy the images, where you can make use of the fact that the element types may be different. Unfortunately, ImgUtil.copy can't handle different booleanType implementations either...

I'd prefer (1).

@elevans
Copy link
Member

elevans commented Jul 19, 2024

This branch passes test successfully with imagej-ops version 2.1.0 which contains the necessary patch for the BitType and BoolType to be converted directly to boolean arrays. A new release of pom-scijava is needed to bumps the imagej ops version requirements.

Copy link
Member

@elevans elevans left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Looks good!

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
enhancement New feature or request
Projects
None yet
Development

Successfully merging this pull request may close these issues.

2 participants