Matteo
Matteo

Reputation: 8142

Matplotlib does not detect correct file type runtime error

I'm running a python demo that is meant to open an image and visualize segmentations of objects on top of it. This script has a routine called loadImage() which is used to load an image:

def loadImage(self, im_id):
    """
    Load images with image objects.
    :param im: a image object in input json file
    :return:
    """
    im = self.images[im_id]
    return mpimg.imread(open('%s/%s/%s'%(self.image_folder, im['file_path'], im['file_name']), 'r'))

Note that mpimg stands for matplotlib (because of the line import matplotlib.image as mpimg at the beginning of script). However once the script executes this function I am returned the following error:

  File "script.py", line 148, in callerFunction
    im = self.loadImage(im_id)

  File "script.py", line 176, in loadImage
    return mpimg.imread(open('%s/%s/%s'%(self.image_folder, im['file_path'], im['file_name']), 'r'))

  File "/usr/lib/pymodules/python2.7/matplotlib/image.py", line 1192, in imread
    return handler(fname)

RuntimeError: _image_module::readpng: file not recognized as a PNG file

I've done some research and for some reason it seems like imread does not properly detect file type when a open file handle is used. And so, since the images I'm trying to load are jpg the readpng module has a runtime error.

Can anybody please help me figure out:

  1. What is this behavior due to?
  2. What is the fix?

Thanks for your help.


Some clarifications after answer by @Paul and further investigation.

As the matplotlib.image documentation says, the funtion imread() can accept as input

a string path or a Python file-like object. If format is provided, will try to read file of that type, otherwise the format is deduced from the filename. If nothing can be deduced, PNG is tried.

so I guess my question should be extended to why in this specific case using a file handle as input causes that runtime error?

Upvotes: 1

Views: 1732

Answers (1)

Paul H
Paul H

Reputation: 68256

Just feed it the file name:

import os
import matplotlib.image as mpimg

class imageThingy(object):
    def loadImage(self, im_id):
        """
        Load images with image objects.
        :param im: a image object in input json file
        :return:
        """
        im = self.images[im_id]
        imgpath = os.path.join(self.image_folder, im['file_path'], im['file_name'])
        return mpimg.imread(imgpath)

    def plotImage(self, im_id):
        fig, ax = plt.subplots()
        ax.imshow(img, origin='lower')
        return fig

Depending on the filetype, you may need to plot your image with origin="lower". This is because the image parser reads in all filetypes as a numpy array. The first element of numpy is always always always the upper right corner. However, some filetypes have their forigin in the lower left corner. Therefore, they are flipped as arrays. This info is in the link you posted.

Upvotes: 1

Related Questions