Calling ImageJ ops in a plugin; output types


I would like to use some functionality of the ops in the context of a plugin (command). Like elaborated in the doc and other posts I us a service instance to access the ops:

private OpService ops;

now when I call for instance some threshold method

Img<BitType> bw = (Img<BitType>) ops.threshold().huang(sec);

… I have to cast the output from Object to Img (and the syntax checker complains that it is a unchecked cast). However, there would be a function signature correponding to the call that is matching my call:

 <T extends RealType<T>> Img<BitType> huang(Img<T> in)

I must be doing something wrong… any ideas?

Hi @FelixM,

as far as I can tell there is not method in the ThreshholdNamespace that directly returns an Img<BitType>. They all seem to return IterableInterval<BitType> so a cast to Img<BitType> is not necessarily safe.

There is usually no need to use Img when calling ops, if you need an Img e.g. for showing it to a user, you can use this method from the create namespace.

true. But

fits Img<BitType>, right?

By no need you mean that you work on lower interfaces?

Anyway. I had a generic variable for my sec variable. Changing it to FloaType did the trick.

Nope, an IterableInterval<BitType> is not necessarily an Img<BitType>. But the following should work:

Img<FloatType> sec = ...; // e.g.
IterableInterval<BitType> bw = (Img<BitType>) ops.threshold().huang(sec);

it worked without casting

Img<BitType> bw = ops.threshold().huang(sec);

Ah! Because you are using a version of Ops earlier than 0.25.0. Since then, this change updated the threshold ops to use IterableInterval instead. So your code will break in the future, unfortunately.

thanks for the heads up.

IterableInterval is more general than Img, which is the union type of RandomAccessibleInterval and IterableInterval.

1 Like