OpService.math().multiply doesn't work "as expected" with an image with a palette [edit: Appears to be a problem with Img, rather than with multiply, per se.]

Tags: #<Tag:0x00007fa30232c4c0> #<Tag:0x00007fa30232c358> #<Tag:0x00007fa30232c178>


When I run OpService.math().multiply on an Img<T> that wraps an
image with a palette (look-up table?) it returns a less-than-useful
result. (This is by no means an important or urgent issue for me,
but I thought I would record it for posterity.)

Of course, multiplying an index into a look-up table by some fixed
number is not necessarily very sensible.


Open a .png image stored in a regular file in Fiji. The specific example
image reports itself as “339x333 pixels; 8-bit; 110K,” and when I move
Fiji’s cursor over the image the status bar displays things like:

x=10, y=10, index=4, value=255,255,255

Then run (from a plugin):

  private Img<T> input;

  T temp = input.firstElement().copy();
  temp.setReal (2.0);
  Img<T> input2 = (Img<T>) opService.math().multiply (input, temp);
  ImageJFunctions.show (input2, "input2");

This “works,” but the resulting image is garbled.

(By the way, why is the resulting image titled “input2 (V),” even though
I passed the title “input2” to show()?)

The multiplied image also reports itself as “339x333 pixels; 8-bit;
110K,” but its pixel values show up (in Fiji’s status bar) as things

x=10, y=10, value=8

That is, it appears that math().multiply() is multiplying the index into
the look-up table by two, but then treating the result as a pixel value.
This violated the principle of least surprise for me even though I
don’t really have any rational expectations for what multiplying a
palettized image by a scalar ought to do …

Perhaps this operation shouldn’t be permitted, or perhaps this
result should be left to stand as the “least surprising” of possibly
unanticipated results. I suppose math().multiply() could multiply
the entries in the look-up table, but I doubt I would have expected
that either.

Thanks, mm.

Can't open a .png image (with a palette) using IJ2

Hi @mountain_man

Did you have an open image, apply a colormap, then try to call a script that converts to Img and processes with ops?

And did the Img<T> have colormap indexes as the pixel values?? (Instead of the original pixel values).

Perhaps I misunderstood your issue, but if the above is the behavior that would effect every script and op.


Hi Brian -

Yes. I used a stock, auto-updated Fiji install to open a random
.png image that I downloaded from the internet.

No, I did not apply a colormap. My belief is that the colormap is
part of the original .png file. When I move Fiji’s cursor over the
open image, Fiji’s status bar displays (what I assume are) data
for the pixels as x-y coordinate, index value, and rgb value.

So I deduce that the image is stored as a colormap and (8-bit)
pixels that are indices into the colormap. I did not use Fiji to
create or modify the image.

Not exactly. I used the IJ2 “input harvester” to “discover” and
"access" the open image:

  private Img<T> input;

My assumption – but I don’t really know – is that the input
harvester wraps the open image in an Img<T> (but doesn’t
"convert" it in the sense of modifying the underlying

Note, the specific run-time type of my “Img<T> input” variable is:

input.getClass().getName() = net.imagej.DefaultDataset

Yes, solely by using OpService to multiply the image by 2:

  T temp = input.firstElement().copy();
  temp.setReal (2.0);
  Img<T> input2 = (Img<T>) opService.math().multiply (input, temp);
  ImageJFunctions.show (input2, "input2");

My understanding is that math().multiply() creates a new, multiplied
image (“input2”), but doesn’t modify the original image (“input”).

Yes. To be precise:

The resulting Img<T>, input2, (also of run-time type DefaultDataset)
appears not to have a colormap – just straight pixel values – who’s
values are two times the index values of the original image. This is
again from moving Fiji’s cursor over the image and looking at the
pixel data displayed in Fiji’s status bar.

So, for example, the (10, 10) pixel in the original image (input) shows
up in Fiji’s status bar as

x=10, y=10, index=4, value=255,255,255

while the corresponding (10, 10) pixel in the multiplied image (input2)
shows up as:

x=10, y=10, value=8

So: “index = 4” --> “value = 2*4 = 8”. (Other pixels show analogous

I’m not trying to do anything unusual with my script – but maybe I am.

(Write script in java, with @Plugin and @Parameter annotations.
Compile with javac with classpath pointed to my Fiji install’s jars
directory. Jar up the resulting .class file and copy the jar to my Fiji
install’s plugins directory.)

I could easily try running some other op on my image if that might
give you some helpful information.

By the way, just to confirm, math().multiply() seems be doing what
I expect when I run it on an image without a colormap. I have a
random-noise, 8-bit-gray-scale image that I created with Fiji stored
on disk as a .jpg file. When I open it in Fiji and run my script, the
original image shows just pixel values (no indices) and the multiplied
image also shows just pixel values (that are twice, modulo 256, the
corresponding pixel values in the original image).

Thanks, mm.


In that case the bug is less concerning, at least to me. My concern was that applying a colormap was effecting the pixel values of the converted Img.

When you open an image in the GUI it is an IJ1 ImagePlus, the input harvester will call the appropriate converter and/or wrapper under the hood so the ImagePlus is converted/wrapped to an Img.


A quick update: I now believe that the issue where indices into
the look-up table turn into values is not caused by math().multiply,
but rather by the Img itself.

Specifically, when I run:

  ImageJFunctions.show (input, "input");

(that is, I show() the unmultiplied @Parameter Img) I see the
same behavior – the original indices show up as values – as
I see with the multiplied input2.

See this newer post for some related detail:


Thanks, mm.