mwaskom
mwaskom

Reputation: 49022

Why does scipy.ndimage.io.imread return PngImageFile, not an array of values

I have two different machines with scipy 0.12 and PIL installed. On one machine, when I try to read a .png file, it returns an array of integers with size (w x h x 3):

In[2]:  from scipy.ndimage.io import imread
In[3]:  out = imread(png_file)
In[4]:  out.shape
Out[4]: (750, 1000, 4)

On the other machine, using the same image file, this returns a PIL.PngImagePlugin.PngImageFile object wrapped in an array

In[2]: from scipy.ndimage.io import imread
In[3]: out = imread(png_file)
In[4]: out.shape
Out[4]: ()
In[5]:  out
Out[5]: array(<PIL.PngImagePlugin.PngImageFile image mode=RGBA size=1000x750 at 0x1D40050>, dtype=object)

I can't see any way to access the data for the latter object.

I have the vague sense that something is wrong with the way PIL is using Png libraries to read the image, but is there something more specific that would be wrong and cause this behavior?

Upvotes: 8

Views: 8420

Answers (6)

Ken Chatfield
Ken Chatfield

Reputation: 3287

It's likely that you have an incomplete Python Imaging Library (PIL) install, which SciPy relies on to read the image. PIL relies on the libjpeg package to load JPEG images and the zlib package to load PNG images, but can be installed without either (in which case it is unable to load whatever images the libraries are missing for).

I had exactly the same issue as you describe above for JPEG images. No error messages are raised, but rather the SciPy call just returns a wrapped PIL object rather than loading the image into an array properly, which makes this particularly tricky to debug. However, when I tried loading in the image using PIL directly, I got:

> import Image
> im = Image.open('001988.jpg')
> im
   <JpegImagePlugin.JpegImageFile image mode=RGB size=333x500 at 0x20C8CB0>
> im.size
> (333, 500)
> pixels = im.load()
   IOError: decoder jpeg not available

So I uninstalled my copy of PIL, installed the missing libjpeg (in my case, probably zlib in yours), reinstalled PIL to register the presence of the library, and now loading images with SciPy works perfectly:

> from scipy import ndimage
> im = ndimage.imread('001988.jpg')
> im.shape
   (500, 333, 3)
> im
   array([[[112, 89, 48], ...
                     ..., dtype=uint8)

Upvotes: 9

Jacob Stern
Jacob Stern

Reputation: 4597

None of these solutions worked for me; even after installing zlib and libjpeg, the result of

from PIL import Image
image = Image.open('2007_000032.png')
print(type(image))

was

<class 'PIL.PngImagePlugin.PngImageFile'>

However, simply calling:

import numpy as np
image = np.asarray(Image.open('2007_000032.png'))

returns the desired data array.

Upvotes: 1

Anass Zurba
Anass Zurba

Reputation: 11

None of the above solved this issue for me.

What I had to do was to: downgrade Pillow from 5.4.0 to 5.3.0

Upvotes: 1

Jongwook Choi
Jongwook Choi

Reputation: 8920

For the most of use cases, I believe that libjpeg or libz dependencies are the most probable cause, as mentioned in Ken Chatfield's answer (the one accepted).

I would like to also mention that if someone is experiencing this with under tensorflow (especially 0.8.0) --- I mean without tensorflow, PIL did work --- then a similar situation might happen due to a bug of tensorflow.

Some related issues reported in github:

A workaround to this would be move import tensorflow as tf statement after importing numpy, scipy or PIL. Please refer to the aforementioned issues for detailed prescriptions.

Upvotes: 1

danodonovan
danodonovan

Reputation: 20373

This error (imread returning an PIL.PngImagePlugin.PngImageFile class rather than a data array) often happens when you have older versions of the python imaging library pillow or worse still PIL installed. pillow is an updated "friendly" fork of PIL and definitely worth installing!

Try updating these packages; (depending on your python distribution)

# to uninstall PIL (if it's there, harmless if not)
$ pip uninstall PIL
# to install (or -U update) pillow
$ pip install -U pillow

and then try restarting your python shell and running the commands again.

Upvotes: 5

Hardikgiri Goswami
Hardikgiri Goswami

Reputation: 514

Try this :

In[2]: from scipy.ndimage.io import imread
In[3]: imread("/hsgs/projects/awagner/test_image.png").shape

And tell me what is out ?

Upvotes: 0

Related Questions