ARGBType cannot be cast to RealType

Hi

I am trying to use imglib2 for some morphological operations:

final ImagePlus imp = new Opener().openImage(id);
Img<UnsignedByteType> img1 = ImagePlusAdapter.wrap(imp);

List<Shape> strel = StructuringElements.disk(6, 2, 0);
final Img<UnsignedByteType> op = Closing.close(img1, strel, 1);

But this throws me the following exception:

[ERROR] Module threw exception
java.lang.ClassCastException: net.imglib2.type.numeric.ARGBType cannot be cast to net.imglib2.type.numeric.RealType
    at net.imglib2.algorithm.morphology.Dilation.dilateFull(Dilation.java:698)
    at net.imglib2.algorithm.morphology.Dilation.dilate(Dilation.java:60)
    at net.imglib2.algorithm.morphology.Closing.close(Closing.java:48)
    at AllenJ2D.run(AllenJ2D.java:125)
    at org.scijava.command.CommandModule.run(CommandModule.java:201)
    at org.scijava.module.ModuleRunner.run(ModuleRunner.java:167)
    at org.scijava.module.ModuleRunner.call(ModuleRunner.java:126)
    at org.scijava.module.ModuleRunner.call(ModuleRunner.java:65)
    at org.scijava.thread.DefaultThreadService$2.call(DefaultThreadService.java:191)
    at java.util.concurrent.FutureTask.run(FutureTask.java:266)
    at java.util.concurrent.ThreadPoolExecutor.runWorker(ThreadPoolExecutor.java:1142)
    at java.util.concurrent.ThreadPoolExecutor$Worker.run(ThreadPoolExecutor.java:617)
    at java.lang.Thread.run(Thread.java:745)

I don’t really understand what’s happening here. Where does suddenly the ARGBType come from? Also I checked the tests

and here it’s used in the same way.
Does anybody have an idea why this exception jumps at me?

Felix

changing UnsignedByteType to FloatType helps… but it’s still unexpected…

ImagePlusAdapter.wrap has nothing enforcing the type at runtime. It delegates to a raw type method. I assume your input ImagePlus is Color_RGB type and thus you are actually getting an ARGBType-backed image, which then fails in the dilation.

What if you convert the input ImagePlus to grayscale before using the wrap function? Do you still get the error?

1 Like

The Closing.close method requires a RealType. ImagePlusAdapter.wrap only guarantees back a NativeType. The two types are independent hierarchies.

Using a FloatType works because it is one of the types that is both Real and Native. Did you call ImagePlusAdapter.wrapFloat in this case…?

1 Like

You are right. My bad.

the following prevents the exception indeed:

ImageConverter ic = new ImageConverter(imp);
ic.convertToGray8();
imp.updateImage();

Thanks for the explanation. I have to admit All the different pixel types and the generic types still confuse me some. I’ll have to reread

Thanks

1 Like

No worries at all, I’m glad we were able to quickly find something that works.

Generic are innately confusing, and that the API does not have an interface to unify Real and Native type can further complicate things.

I only glanced at that page but I’m actually not sure how much it will help with Types; it’s really a matter of experience and knowing which concrete Types are both Native and Real. Also in this case I feel like the API didn’t do much to help you, since you called a generic method with a legitimate generic parameter (UnsignedByteType is both Real and Native).

This might be a good opportunity to migrate to ImageJ Ops, which is built on ImgLib2 but is intended to have more robust type checking. In particular, using @Parameters will take care a lot of conversion issues automatically (e.g. write @ImgPlus in a script and it will accept an ImageJ 1.x ImagePlus as well).

Finally, you may be interested in this thread for the Real + Native type discussion.

2 Likes

glad to hear I am not the only one strugling with types…
I will follow the thread. Thanks again.