Feature request: 32-bit int image in ImageJ1

At the moment, 32-bit int arrays are represented as RGB images by ImageJ1, which creates a problem if the ints are being used to quantify something discrete (in my case, connected components particle labels), because the quantification is scrambled by the RGB conversion.

It would be very helpful to be able to display int arrays as raw values from Integer.MIN_VALUE to Integer.MAX_VALUE with a look-up-table. The workaround is to use a 32-bit float, but this loses integer precision at 223 (about 8 million) and so the rest of the 32-bit int range up to 232 (about 2 billion) is not usable.

Having a look at the IJ1 code, it seems like it could be done by making a new IntProcessor class based on e.g. ShortProcessor, with the associated Blitter and Statistics classes.

@Wayne is this feasible?

2 Likes

Why not use ImageJ2? It supports numerous data types (I couldn’t find a list). ImageJ is intended to be small, sample and fast.

3 Likes

Thanks @wayne for the fast reply.

That’s unfortunately why not: the learning curve and time investment in the absence of good code examples and developer documentation is a barrier. As well, so far IJ2 seems a bit slow compared to IJ1, and my use case is for large images (> 150 GB 8-bit, so 600 GB 32-bit int) so performance issues are real.

But, I could be convinced with example code snippets and performance comparisons if they exist.

If one (I?) were to create an IntProcessor, would you be open to including it in IJ1? It would just be the ImageProcessor, ImageStack and ImagePlus wrapping a (potentially very large) int array.

2 Likes

Hey Michael @mdoube ,

search the source code of ImageJ for something like “ByteProcessor” … At all these places you would have to integrate your IntProcessor. And you basically need to test it. All. I’m afraid the effort is huge.

Another alternative: You could program a virtual stack that returns an ImageJ-compatible ImageProcessor but internally handles your int-image. I did something similar with GPU-backed images:

Cheers,
Robert

3 Likes

That’s what I feared as well: I see 103 references to ShortProcessor in the IJ1 code, although many of those are in ShortProcessor itself. So it’s not an infinite problem, but if there’s little will or need then it’s not worth the effort.

1 Like

Hi @mdoube,
I am willing to make minor changes to the ColorProcessor to make it more useful for processing and displaying 32-bit ints. The following constructors and methods already work with 32-bit ints:

  ColorProcessor(int width, int height)
  ColorProcessor(int width, int height, int[] pixels)
  Object getPixels()
  int getPixel(int x, int y)
  int get(int x, int y)
  int get(int index)
  void setPixels(Object pixels)
  void set(int x, int y, int value)
  void set(int index, int value)
3 Likes

4 posts were split to a new topic: Performance issues on large images with IJ2 compared to IJ1

Hi @mdoube,

The ImageJ 1.53g45 daily build adds an IntProcessor class that extends ColorProcessor. It is now easy to create and view 32-bit int images but there is currently no good way to save them. Here is a JavaScript example:

     var size = 800;
     var n = size*size;
     var ip = new IntProcessor(size,size);
     var range = Integer.MAX_VALUE - Integer.MIN_VALUE; 
     for (var i=0; i<n; i++) {
        value = Integer.MIN_VALUE + i*range/n;
        ip.set(i, value);
     }
     var img = new ImagePlus("32-bit int image",ip);
     IJ.run(img,"Viridis","");
     img.show();

5 Likes

That is very handy, thanks @Wayne.

I think this solves the immediate display problem.

As @haesleinhuepf mentioned above, it would be a lot of work (but IMO probably preferable in the long run) to create a fully capable IntProcessor, something like ShortProcessor but using int rather than unsigned short.

I’ll look into the IJ2 style way, and see if I can figure it out and also see if it is comparably performant as ImageProcessor's array access.

Hi @mdoube,

Upgrade to the latest daily build (1.53g49) and you will be able to use the IJ.createImage() method to create 32-bit int images and stacks. Histograms of 32-bit int images also now work.

  img = IJ.createImage("32-bit int stack", "32-bit int noise", 512, 512, 10);
  img.show();

2 Likes