imagej / pyimagej

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

Error converting Java image back to Python #32

Closed ctrueden closed 3 years ago

ctrueden commented 5 years ago

Noticed by @thewtex.

$ python
Python 3.7.3 | packaged by conda-forge | (default, Mar 27 2019, 15:43:19)
[Clang 4.0.1 (tags/RELEASE_401/final)] :: Anaconda, Inc. on darwin
Type "help", "copyright", "credits" or "license" for more information.
>>> import imagej
>>> ij = imagej.init()
log4j:WARN No appenders could be found for logger (org.bushe.swing.event.EventService).
log4j:WARN Please initialize the log4j system properly.
log4j:WARN See http://logging.apache.org/log4j/1.2/faq.html#noconfig for more info.
>>> ij.getVersion()
'2.0.0-rc-71'
>>> import numpy as np
>>> z = np.zeros([5, 7])
>>> jz = ij.py.to_java(z)
>>> jz
<net/imglib2/python/ReferenceGuardingRandomAccessibleInterval at 0x1359e6f68 jclass=net/imglib2/python/ReferenceGuardingRandomAccessibleInterval jself=<LocalRef obj=0x7fd9c27362a0 at 0x10cb19e70>>
>>> ij.py.from_java(jz)
Traceback (most recent call last):
  File "<stdin>", line 1, in <module>
  File "/usr/local/miniconda3/envs/scijava/lib/python3.7/site-packages/imagej/imagej.py", line 225, in from_java
    return self.rai_to_numpy(rai)
  File "/usr/local/miniconda3/envs/scijava/lib/python3.7/site-packages/imagej/imagej.py", line 152, in rai_to_numpy
    self._ij.op().run("copy.rai", self.to_java(result), rai)
  File "jnius/jnius_export_class.pxi", line 1044, in jnius.JavaMultipleMethod.__call__
  File "jnius/jnius_export_class.pxi", line 766, in jnius.JavaMethod.__call__
  File "jnius/jnius_export_class.pxi", line 843, in jnius.JavaMethod.call_method
  File "jnius/jnius_utils.pxi", line 91, in jnius.check_exception
jnius.JavaException: JVM exception occurred: net.imglib2.python.ReferenceGuardingRandomAccessibleInterval cannot be cast to net.imglib2.IterableInterval
>>> imagej.imagej.__version__
'0.4.0'
ctrueden commented 5 years ago

This is a bug on the Java side. With 01a85190e7df9321beeb674a3914435df9bf5035, one can now dump the Java stack traces by setting DEBUG=1 environment variable. Here is the trace:

java.lang.ClassCastException: net.imglib2.python.ReferenceGuardingRandomAccessibleInterval cannot be cast to net.imglib2.IterableInterval
        at net.imagej.ops.map.MapUnaryComputers$IIToIIParallel.compute(MapUnaryComputers.java:87)
        at net.imagej.ops.copy.CopyRAI.compute(CopyRAI.java:90)
        at net.imagej.ops.copy.CopyRAI.compute(CopyRAI.java:54)
        at net.imagej.ops.special.hybrid.UnaryHybridCF.run(UnaryHybridCF.java:75)
        at net.imagej.ops.special.hybrid.UnaryHybridCF.run(UnaryHybridCF.java:97)
        at org.scijava.command.CommandModule.run(CommandModule.java:199)
        at net.imagej.ops.OpEnvironment.run(OpEnvironment.java:950)
        at net.imagej.ops.OpEnvironment.run(OpEnvironment.java:136)

Still investigating why this happens, though.

ctrueden commented 4 years ago

Hopefully this will be fixed by addressing #46 to behave differently. Then we will not trigger this bug in the copy.rai op.

elevans commented 3 years ago

@ctrueden I'm doing some cleanup on these old issues...I just tried this issue out again on pyimagej=1.0.0 and this no longer seems to be a problem since our move to JPype. I haven't looked into it but my guess is https://github.com/imagej/pyimagej/issues/46 resolved this for us. My output:

>>> import imagej
>>> ij = imagej.init()
log4j:WARN No appenders could be found for logger (org.bushe.swing.event.EventService).
log4j:WARN Please initialize the log4j system properly.
log4j:WARN See http://logging.apache.org/log4j/1.2/faq.html#noconfig for more info.
>>> ij.getVersion()
2.1.0/1.53c
>>> import numpy as np
>>> z = np.zeros([5, 7])
>>> jz = ij.py.to_java(z)
>>> jz
>>> <java object 'net.imglib2.python.ReferenceGuardingRandomAccessibleInterval'>
>>> ij.py.from_java(z)
array([[0., 0., 0., 0., 0., 0., 0.],
       [0., 0., 0., 0., 0., 0., 0.],
       [0., 0., 0., 0., 0., 0., 0.],
       [0., 0., 0., 0., 0., 0., 0.],
       [0., 0., 0., 0., 0., 0., 0.]])
ctrueden commented 3 years ago

@elevans Thanks. Note that #46 is still open—all that's needed is to use the Images.copy method from imagej-common in PyImageJ for the rai_to_numpy function. Someone just needs to test it. It's very likely faster than the current code.

elevans commented 3 years ago

@ctrueden I just pushed a branch to pyimagej testing this: rai-copy-speed. Images.copy is faster! I'll post the relevant details on issue #46.