Open ImageJ example zip images with scikit-image and friends

Hi python fans,

I’m trying to open ImageJ’s famous example images via the internet with python. Some of them come as zip, e.g.:

https://imagej.nih.gov/ij/images/t1-head-raw.zip
https://imagej.nih.gov/ij/images/t1-head.zip
http://imagej.nih.gov/ij/images/Spindly-GFP.zip

I’m trying to open them using scikit-image, pillow or any other python library. I googled around and found this code snippet using pillow:

# Load image
from PIL import Image
import requests
from io import BytesIO

response = requests.get('http://imagej.nih.gov/ij/images/Spindly-GFP.zip')
image = Image.open(BytesIO(response.content))

which doesn’t understand the image format:

UnidentifiedImageError                    Traceback (most recent call last)
<ipython-input-8-2a328a56061f> in <module>
      5 
      6 response = requests.get('http://imagej.nih.gov/ij/images/Spindly-GFP.zip')
----> 7 image = Image.open(BytesIO(response.content))
      8 
      9 #image = imread('https://imagej.nih.gov/ij/images/t1-head.zip')

c:\users\rober\miniconda3\lib\site-packages\PIL\Image.py in open(fp, mode, formats)
   2941     for message in accept_warnings:
   2942         warnings.warn(message)
-> 2943     raise UnidentifiedImageError(
   2944         "cannot identify image file %r" % (filename if filename else fp)
   2945     )

Furthermore, I used zipfile:

import zipfile
unzipped_file = zipfile.ZipFile("http://imagej.nih.gov/ij/images/Spindly-GFP.zip", "r")

Which can’t read from the internet apparently:

OSError                                   Traceback (most recent call last)
<ipython-input-10-027b86a5be82> in <module>
      1 import zipfile
----> 2 unzipped_file = zipfile.ZipFile("http://imagej.nih.gov/ij/images/Spindly-GFP.zip", "r")
      3 
      4 from skimage.io import imread
      5 

c:\users\rober\miniconda3\lib\zipfile.py in __init__(self, file, mode, compression, allowZip64, compresslevel, strict_timestamps)
   1248             while True:
   1249                 try:
-> 1250                     self.fp = io.open(file, filemode)
   1251                 except OSError:
   1252                     if filemode in modeDict:

OSError: [Errno 22] Invalid argument: 'http://imagej.nih.gov/ij/images/Spindly-GFP.zip'

I’m now womdering: Did anyone manage to open these images in python? If so, is the a simple library/method which does that? You know, I’m indulged by ImageJ, where we just call

open("http://imagej.nih.gov/ij/images/Spindly-GFP.zip");

Is there a similarily simple method in python? If not, I’m sure with PIL, zipfile and/or skimage I can make one. And maybe skimage would be happy about a PR with such a helper function. But before I reinvent the wheel, I wanted to check with experts :wink:

Thanks!

Cheers,
Robert

no there’s no one function that does all that… (well, I can’t speak for all libraries… i’m sure there are a lot of use-case specific functions like that out there), but it’s pretty straightforward:

import requests
import zipfile
from io import BytesIO
from tifffile import imread


def remote_reader(url):
    """generator that yields numpy arrays for each tif in a remote zip."""
    response = requests.get(url)
    response.raise_for_status()
    with zipfile.ZipFile(BytesIO(response.content)) as zf:
        for path in zf.filelist:
            with zf.open(path, "r") as f:
                # f is a file-like object of type zipfile.ZipExtFile
                # replace imread with any file-reader of your choice
                # that accepts a file-like object as input 
                yield imread(f)


# example:
for arr in remote_reader('http://imagej.nih.gov/ij/images/Spindly-GFP.zip'):
    print(arr.shape, arr.dtype)  

#(51, 5, 2, 196, 171) uint16

edit: I’ll add that skimage.io.imread seems to hang, whereas tifffile.imread works fine. I haven’t looked into the source to see what skimage.io.imread is doing with file-like objects to figure out what’s going on there, but a slight modification would be needed to make it work with their imread function

2 Likes

Awesome! Thanks @talley for the light speed response. It works!

1 Like

Looks like the imageio library we use underneath the hood does not like that object. It works fine if you do, e.g., skimage.io.imread(f, plugin='matplotlib') or skimage.io.imread(f, plugin='tifffile').

2 Likes