pythonscipyimreadndimagecstringio

Reading image from URL with misc.imread returning a flattened array instead of a colour image


I'm trying to read an image from a URL (provided by Google's Static Maps API).

The image displays okay in browser.

enter image description here

https://maps.googleapis.com/maps/api/staticmap?maptype=satellite&center=37.530101,38.600062&zoom=14&size=256x278&key=...

But when I try to load it into an array using misc.imread it seems to end up as a 2-dimensional array (i.e. flattened, no RGB colours).

Here is the code I am using (I hid my API key):

from scipy import ndimage
from scipy import misc
import urllib2
import cStringIO

url = \
    "https://maps.googleapis.com/maps/api/staticmap?maptype=satellite&" \
    "center=37.530101,38.600062&" \
    "zoom=14&" \
    "size=256x278&" \
    "key=...."

file = cStringIO.StringIO(urllib2.urlopen(url).read())
image = misc.imread(file)
print image.shape

(278, 256)

What I expected was a 3-d array of shape (278, 256, 3).

Maybe it's not reading the file properly?

In [29]:
file.read()[:30]
Out[29]:
'\x89PNG\r\n\x1a\n\x00\x00\x00\rIHDR\x00\x00\x01\x00\x00\x00\x01\x16\x08\x03\x00\x00\x00\xbe'

Solution

  • The byte \x03 after \x08 indicates that your file is indexed RGB (i.e. it has a palette). There is a bug in scipy.misc.imread that occurs when you read an indexed PNG file. The array returned is the array of index values, not the actual RGB colors. The bug has been fixed for scipy 0.17.0, but that has not been released yet.

    A work-around is to use scipy.ndimage.imread with the option mode='RGB'.

    (Two slightly different imread functions exist for, um, historical reasons. In this case, the fact that one had the mode option turns out to be helpful. The implementations are unified in scipy 0.17.0.)