Why scipy.ndimage.io.imread returns a PngImageFile rather than an array of values

I have two different machines with scipy 0.12 and PIL. On one machine, when I try to read a .png file, it returns an array of integers with a size (wxhx 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 another computer, using the same image file, it 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 do not see any way to access data for the last object.

I have a vague feeling that something is wrong with the way PIL uses Png libraries to read images, but is there something more specific that would be wrong and cause this behavior?

+8
python scipy
source share
6 answers

You probably have an incomplete installation of the Python Imaging Library (PIL), which SciPy relies on when reading the image. PIL uses the libjpeg package to download JPEG images and the zlib package to download PNG images, but can be installed without them (in this case, it cannot download any images for which there are no libraries).

I had exactly the same problem as you described above for JPEG images. No error messages are issued, but rather, calling SciPy simply returns the wrapped PIL object, rather than loading the image into the array properly, which makes it especially difficult to debug. However, when I tried to load 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 deleted my copy of PIL, installed the missing libjpeg (in my case, probably zlib in yours), reinstalled PIL to register the library, and now loading images using SciPy works fine:

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

This error ( imread , returning the PIL.PngImagePlugin.PngImageFile class rather than a data array) often occurs when you have older versions of the python pillow image library installed or worse PIL . pillow is an updated β€œfriendly” PIL plug and is definitely worth installing!

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

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

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

+5
source share

In most use cases, I find libjpeg or libz dependencies to be the most likely cause, as stated in Ken Chatfield's answer (the one that was accepted).

I would also like to mention that if someone experiences this with a tensor stream (especially 0.8.0) --- I mean without a tensor stream, PIL really worked - then a similar situation could happen due to a shadoworflow error.

Some related issues reported on github:

A workaround to this would be to transfer the import tensorflow as tf statement after importing numpy , scipy or PIL . Please refer to the above questions for detailed instructions.

+1
source share

None of the above solved this problem for me.

What I needed to do to: downgrade Pillow from 5.4.0 to 5.3.0

+1
source share

Try the following:

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

And tell me what came of it?

0
source share

None of these solutions helped me; even after installing zlib and libjpeg result

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

was

 <class 'PIL.PngImagePlugin.PngImageFile'> 

However, just by calling:

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

returns the desired data array.

0
source share

All Articles