1

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?

1 Answer 1

1

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.

Sign up to request clarification or add additional context in comments.

7 Comments

Paul this solved my problem! Thanks a lot. Could you please tell me what was going on before and what is now changed?
However there is still a thing not working (which is mentioned in the link I put in my question), which is that the image results printed upside-down. Do you know how to fix that problem as well?
@Matteo first comment: you were passing a file object, but imread only wants the path to the file. second comment I'll address in my response.
Paul thanks again for extending your answer, it is very clear now how to fix this problem. Still I am not completely sure of what is causing it (read added part in question), do you have any idea?
@Matteo The cause of the problem is that you were passing an open file object to a function that expects a filepath in the form of a string. It's like asking for a plane ticket but receiving the plane instead. It may be an error in the documentation that says it can take a file-like object, or your file might be corrupt, or that file type doesn't work with file-like objects. There's no way to know without a full example and the image. If the file path works, just use it.
|

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.