Unexpected behavior of Views.interval()

In encountered strange results when using net.imglib2.view.Views in a script:

from net.imglib2.img.display.imagej import ImageJFunctions
from net.imglib2.view import Views
from ij import IJ

imp = IJ.createImage("Untitled", "8-bit black", 10, 10, 10);
img = ImageJFunctions.wrap(imp)

interval = Views.interval(img, [0, 0, 0], [9, 9, 9])

ImageJFunctions.show(interval)

While this seems to work as expected when the min and max parameters are in the range of the original image, the behavior is inconsistent when using values outside the range:

interval = Views.interval(img, [0, 0, 0], [10, 9, 9])
interval = Views.interval(img, [0, 0, 0], [9, 10, 9])
  • throw java.lang.ArrayIndexOutOfBoundsException

But

interval = Views.interval(img, [0, 0, 0], [9, 9, 10])
  • displays a 10x10x11 image

Similarly,

interval = Views.interval(img, [-1, 0, 0], [9, 9, 9])
interval = Views.interval(img, [0, -1, 0], [9, 9, 9])
  • throw java.lang.ArrayIndexOutOfBoundsException

but

interval = Views.interval(img, [0, 0, -1], [9, 9, 9])
  • displays a 10x10x11 image

More confusing, and inconsistent between x and y dimensions:

interval = Views.interval(img, [-20, 2, 0], [29, 7, 9])
  • displays a 50x6x10 image (!)
interval = Views.interval(img, [2, -20, 0], [7, 29, 9])
  • throws exception
interval = Views.interval(img, [0, 2, -20], [9, 7, 29])
  • displays a 10x6x50 image

The behavior is different again when directly using an Img instead of an ImagePlus:

# @OpService ops

from net.imglib2.img.display.imagej import ImageJFunctions
from net.imglib2.view import Views

from ij import IJ

img = ops.create().img([10,10,10])
interval = Views.interval(img, [0, 0, 0], [90, 90, 90]) # displays
# interval = Views.interval(img, [0, 0, 0], [91, 91, 91]) # throws exception when trying to show

ImageJFunctions.show(interval)

Hi Jan,
yes, Views.interval behaviour is undefined if the specified interval falls outside of defined data. We should just make that clear in the javadoc.
Note, that it would not be sufficient to check the bounds of the img argument to Views.interval( img, ...). Img might not be bounded, and if it is, then the bounds might not reflect the range data is defined. It may or may not be possible to look through transform chains etc to make the behaviour consistent. I would go with just stating “undefined behaviour” for now.
best regards,
Tobias

1 Like

…if you need to access outside of the image range, then Views.extend(...) the img first.

2 Likes

Alright, thanks for the clarification.