imagej / imagej-legacy

ImageJ+ImageJ2 compatibility layer
https://imagej.net/libs/imagej-legacy
BSD 2-Clause "Simplified" License
17 stars 25 forks source link

Showing int32 image mangles values #211

Open ctrueden opened 5 years ago

ctrueden commented 5 years ago
#@ ImageJ ij
v = Integer.MAX_VALUE
int[] values = [
    v, v - 1, v - 2, v / 4,
    v / 4 - 3, v / 8 - 5, v / 3, v / 2 + 5,
    v / 2 + 3, v / 2 + 7, v / 2 + 11, v / 2 + 13
]
img = net.imglib2.img.array.ArrayImgs.ints(values, 4, 3)

def printValues(img, values) {
    access = img.randomAccess()
    for (y=0; y<3; y++) {
        for (x=0; x<4; x++) {
            access.setPosition(x, 0)
            access.setPosition(y, 1)
            println("($x, $y) = ${access.get()} (array value=${values[4*y+x]})")        
        }
    }
}

println("Sample values before displaying:")
printValues(img, values)
ij.ui().show(img)
//net.imglib2.img.display.imagej.ImageJFunctions.show(img)
//bdv.util.BdvFunctions.show(img, "image")
println()
println("Sample values after displaying:")
printValues(img, values)

Run the above script, and observe how the original array's values get mangled.

Using net.imglib2.img.display.imagej.ImageJFunctions.show(img) does not mangle the array, but does create an int16 image(!) which I guess is a separate bug (CC @maarzt).

Using bdv.util.BdvFunctions.show is, I think, OK, although I didn't thoroughly check.

maarzt commented 5 years ago

Yes, I noticed that bug before, it's fixed in the first commit of this PR: https://github.com/imglib/imglib2-ij/pull/28

maarzt commented 5 years ago

Yes, the bug is fixed by the PR mentioned before, but for a different reason. Overall this occurs as consequence of several strange behaviors:

  1. Calling new ImagePlus("title", stack) effectively performs: stack.setPixels(stack.getProcessor(1).getPixels(), 1). Which make no sense, but it's causes problems for performance and numerical precision of imglib2 images when wrapped as virtual stacks.
  2. And the numerical precision problem actually caused the bug. Converting Integer.MAX_VALUE -> float -> double ->long -> int, results for reasons of rounding and numerical precision in Integer.MIN_VALUE.

https://github.com/imglib/imglib2-ij/pull/28 fixes the problem because it reduces the conversion to Integer.MAX_VALUE -> float -> int.