volread on tifffile produces the wrong shape
See original GitHub issueThis is a regression from 2.9.0 first shared by @mkcor in https://github.com/scikit-image/scikit-image/pull/5262.
Reproducing example:
img = iio.volread('http://cmci.embl.de/sampleimages/NPCsingleNucleus.tif')
img.shape
# in v2.10.3 (30, 180, 183)
# in v2.9.0 (15, 2, 180, 183)
It traces back to something that, at least to me, is unexpected behavior in v2.9.0. Calling imageio.imread
on the above tiff (in either version of ImageIO) returns a single page of the file, not a single image. I.e.,
import imageio as iio
img = iio.imread('http://cmci.embl.de/sampleimages/NPCsingleNucleus.tif')
img.shape # (180, 183) not the expected (2, 180, 183)
Consequentially, iterating over single images and stacking them, doesn’t yield a stack of channel-first images, but a stack of pages:
reader = iio.get_reader('http://cmci.embl.de/sampleimages/NPCsingleNucleus.tif', mode="i")
img = np.stack([reader.get_data(index=x) for x in range(reader.get_length())])
img.shape # (30, 180, 183)
Reading a volume, on the other hand, does the expected thing and produces a stack of channel-first images (in v2.9.0)
img = iio.volread('http://cmci.embl.de/sampleimages/NPCsingleNucleus.tif')
img.shape # (15, 2, 180, 183)
however, does the page-stacking thing in v2.10.3:
img = iio.volread('http://cmci.embl.de/sampleimages/NPCsingleNucleus.tif')
img.shape # (30, 180, 183)
@cgohlke @almarklein @mkcor (and others who use TIFF more than me) What is expected behavior here? Would you expect imread
to return a single image (shape: (2, 180, 183)) or a single page (shape: (180, 183))? I am leaning towards a single image, but I am open for comments here.
Depending on this answer, I would either look into a bugfix fir get_data(index=...)
(any version) or volread(...)
(v2.10.3).
Issue Analytics
- State:
- Created 2 years ago
- Comments:21 (14 by maintainers)
Top GitHub Comments
@GenevieveBuckley The fix should roll out to PyPI tonight.
Indeed. I also just found the relevant section of code in our vendored tiffile: It literally just parses the metadata string and sets the shape according to the
channel
andframe
entries . . .https://github.com/imageio/imageio/blob/master/imageio/plugins/_tifffile.py#L2172-L2252
On the bright side though, it makes the fix efficient, because we don’t have to parse the full file to figure out the image’s shape. All that is needed is to read the first page and we can learn how many pages to read for a
imread(index=N)
call.🤣 lol.
Makes you wonder how @cgohlke figured out how to correctly read ImageJ hyperstacks in the first place. Big props.