pyimagej icon indicating copy to clipboard operation
pyimagej copied to clipboard

Make ImagePlus subscriptable

Open ctrueden opened this issue 3 years ago • 4 comments

PyImageJ lets you subscript RandomAccessibleInterval objects, but not ImagePlus objects.

For single-element access:

  • GRAY8 (ByteProcessor) is the equivalent of numpy.uint8.
  • GRAY16 (ShortProcessor) is the equivalent of numpy.uint16.
  • GRAY32 (FloatProcessor) is the equivalent of numpy.float32.
  • COLOR_RGB (IntProcessor) has no numpy dtype equivalent to my knowledge.
  • COLOR_256 is apparently also done in numpy with numpy.uint8...
  • Does ImageJ support for uint32 now? I vaguely remember reading on a thread during 2021-2022 about it, but I can't find it now.

Note also that to be consistent with numpy and ImgLib2's behavior, the dtype function should also be implemented, and it should return a class object corresponding to the returned type of single elements.

For slicing: maybe we can use the Duplicator's crop and/or run to limit dimensional min/maxes. But step values other than 1 require more effort. Better to wrap the ImagePlus into some kind of Python-side view object?

ctrueden avatar Apr 28 '22 03:04 ctrueden

See also this Gitter chatlog.

ctrueden avatar Apr 28 '22 03:04 ctrueden

I think our four choices are:

  1. Invent some ImageJ-specific dtypes; or
  2. Reuse the numpy dtypes; or
  3. Use plain Python types but that is ambiguous (GRAY8 vs GRAY16); or
  4. Break the convention of dtypes returning the class of elements you get from single-element slicing.

The advantage of (2) is that those types are already in place. But the disadvantage is that it's inconsistent with how PyImageJ handles RandomAccessibleInterval—why not report the numpy-equivalent dtypes for RAIs too then?

So I think (1) is probably the cleanest solution.

ctrueden avatar Apr 28 '22 13:04 ctrueden

I think our four choices are:

1. Invent some ImageJ-specific dtypes; or

2. Reuse the numpy dtypes; or

3. Use plain Python types but that is ambiguous (GRAY8 vs GRAY16); or

4. Break the convention of `dtypes` returning the class of elements you get from single-element slicing.

The advantage of (2) is that those types are already in place. But the disadvantage is that it's inconsistent with how PyImageJ handles RandomAccessibleInterval—why not report the numpy-equivalent dtypes for RAIs too then?

So I think (1) is probably the cleanest solution.

I'd propose not actually making a decision on this. I'd rather focus on making pixel access (i.e. slicing) work the way we want it. Then I think this question of the dtype will follow naturally from the return.

gselzer avatar Apr 28 '22 13:04 gselzer

My current thinking is: let's not ever implement this. What we could do instead is, if someone tries to slice or subscript an ImagePlus, raise an exception explaining that the original ImageJ data structures do not support this, and to recommend using ImgLib2 structures instead. :+1: No need to make it any easier than we already have for people to keep using ImagePlus forever.

ctrueden avatar Jun 23 '23 16:06 ctrueden