How to convert Img<T> to Img<LongType >?

imglib2
imagej
histogram

#1

Hello,
I would like to get the histogram of an Img and found the class DiscreteFrequencyDistribution(Img img). I think this could work.
But how can I check what type Img actually is?
And how can I convert the Img if it is not a LongType to LongType?

Many thanks in advance,
Helmut


#2

Hi @iqmmug,

You can call a convert op to get an Img. For this you don’t need to know the actual runtime type of your Img. Assuming your coding in Java, you’d call

final ImageJ imageJ = new ImageJ();
final Img<LongType> longImg = imageJ.op().convert().int64(img) ;

Best regards,
Richard


#3

Hi Richard,
Thanks a lot for your answer. imageJ.op().convert(). is resolvable, but unfortunately .int64 is not resolvable (“The method int64(Img) is undefined for the type ConvertNamespace”). I am using net.imagej.ImageJ. Using ij.imagej.ImageJ op() ist not resolvable. In the JavaDocs of net.imagj I have found the class ConvertImages.Uint64, but again not resolvable.

Any further suggestions?
Best,
Helmut


#4

Hello Richard (and Helmut) -

But a word of caution:

It’s true that the code you write does not explicitly need to know
the specific type of the Img<> that you wish to convert. But not
all types can be converted from one to another, and trying to do
so with incompatible types will throw a ClassCastException.

Here is an IJ1-style Fiji plugin that illustrates this behavior:

import ij.*;
import ij.gui.*;
import ij.plugin.*;

import net.imagej.legacy.IJ1Helper;
import net.imagej.ops.OpService;
import net.imglib2.img.Img;
import net.imglib2.img.display.imagej.ImageJFunctions;
import net.imglib2.type.numeric.integer.LongType;

import org.scijava.Context;

public class My_Plugin implements PlugIn {
  public void run (String arg) {
    boolean createImageOnTheFly = true;  // set to false to convert existing open image
    int bitDepth = 24;  // set to 16 to create and convert 16-bit (short) image

    // some boiler plate to get Ops ...
    OpService ops = IJ1Helper.getLegacyContext().getService(OpService.class);

    ImagePlus imp;
    if (createImageOnTheFly) {
      imp = NewImage.createImage ("bit-depth = " + bitDepth, 512, 512, 1, bitDepth, NewImage.FILL_RAMP);
      imp.show();
    }
    else {  // get open image
      imp = IJ.getImage();
    }

    Img img = ImageJFunctions.wrap (imp);
    ImageJFunctions.show (img, "IJ2 Img");
    Img<LongType> longImg = ops.convert().int64(img) ;
    ImageJFunctions.show (longImg, "IJ2 Img<LongType>");
  }
}

When run as is, it throws:

java.lang.ClassCastException: net.imglib2.type.numeric.ARGBType cannot be cast to net.imglib2.type.numeric.ComplexType
	at net.imagej.ops.convert.ConvertImages$ConvertViaMap.createWorker(ConvertImages.java:265)
	at net.imagej.ops.convert.ConvertImages$Int64.createWorker(ConvertImages.java:177)
	at net.imagej.ops.convert.ConvertImages$ConvertViaMap.createWorker(ConvertImages.java:249)
	at net.imagej.ops.special.chain.UHCFViaUC.initialize(UHCFViaUC.java:60)
	at net.imagej.ops.DefaultOpMatchingService.singleMatch(DefaultOpMatchingService.java:425)
	at net.imagej.ops.DefaultOpMatchingService.findMatch(DefaultOpMatchingService.java:97)
	at net.imagej.ops.DefaultOpMatchingService.findMatch(DefaultOpMatchingService.java:83)
	at net.imagej.ops.OpEnvironment.module(OpEnvironment.java:268)
	at net.imagej.ops.OpEnvironment.run(OpEnvironment.java:156)
	at net.imagej.ops.convert.ConvertNamespace.int64(ConvertNamespace.java:647)
	at My_Plugin.run(My_Plugin.java:32)
	at ij.IJ.runUserPlugIn(IJ.java:222)
	at ij.IJ.runPlugIn(IJ.java:186)
	at ij.Executer.runCommand(Executer.java:137)
	at ij.Executer.run(Executer.java:66)
	at java.lang.Thread.run(Thread.java:745)

If you want to avoid this possibility, you either have to probe the
type of your Img<>, and not call disallowed conversions (but then
your code has to know the runtime type of your Img<>), or you
could wrap the call to convert() in a try block (and therefore,
kind-of, sort-of, probe the type of your Img<>).

(In the plugin code, you can set createImageOnTheFly = false,
in which case the plugin will process an existing open image. This
way you can use Fiji to open or create various types of images and
see what happens when you run convert() on them.)

Thanks, mm


#5

Hi Helmut -

The various bits of the convert call that Richard proposed do resolve
for me. If you look at the plugin code I posted in my reply to Richard,
you will see what I did (what imports, etc.).

The plugin is (for me) fully compilable and working.

I compile and run against stock Fiji (my current version reports
as ImageJ 2.0.0-rc-67/1.52c; Java 1.8.0_66 [64-bit];), running on
ubuntu 16.04 LTS).

Thanks, mm


#6

Hello mm,
Thanks a lot, your very last sentence helped me. You are using ImageJ 2.0.0-rc-67/1.52c and I was using version rc-43, although this comes with the bundled jars of the actual ImageJ zip-folder download. I downloaded the Fiji distribution and a got the new jar and now the code works.

Many thanks!
Helmut