TypeError: img should be PIL Image. Got <class ‘str’>

  • Any idea how to fix
    TypeError: img should be PIL Image. Got <class ‘str’>
  • Let me know what I did wrong.
# Predict 
def predict(image, model, topk=5):
    ''' Predict the class (or classes) of an image using a trained deep learning model.
    '''
    img = process_image(image)
    img = img.unsqueeze(0)
    
    output = model.forward(img)
    probs, labels = torch.topk(output, topk)        
    probs = probs.exp()
        
    # Reverse the dict
    idx_to_class = {val: key for key, val in model.class_to_idx.items()}
    # Get the correct indices
    top_classes = [idx_to_class[each] for each in classes]
    
    return labels, probs

#Passing 
probs, classes = predict(image, model)
print(probs)
print(classes)

---------------------------------------------------------------------------
TypeError                                 Traceback (most recent call last)
<ipython-input-92-b49fdcab5791> in <module>()
----> 1 probs, classes = predict(image, model)
     2 print(probs)
     3 print(classes)

<ipython-input-91-05809355bfe0> in predict(image, model, topk)
     2     ‘’' Predict the class (or classes) of an image using a trained deep learning model.
     3     ‘’'
----> 4     img = process_image(image)
     5     img = img.unsqueeze(0)
     6

<ipython-input-20-02663a696e34> in process_image(image)
    11                              std=[0.229, 0.224, 0.225])
    12     ])
---> 13     image = process(image)
    14     return image

/opt/conda/lib/python3.6/site-packages/torchvision-0.2.1-py3.6.egg/torchvision/transforms/transforms.py in __call__(self, img)
    47     def __call__(self, img):
    48         for t in self.transforms:
---> 49             img = t(img)
    50         return img
    51

/opt/conda/lib/python3.6/site-packages/torchvision-0.2.1-py3.6.egg/torchvision/transforms/transforms.py in __call__(self, img)
   173             PIL Image: Rescaled image.
   174         “”"
--> 175         return F.resize(img, self.size, self.interpolation)
   176
   177     def __repr__(self):

/opt/conda/lib/python3.6/site-packages/torchvision-0.2.1-py3.6.egg/torchvision/transforms/functional.py in resize(img, size, interpolation)
   187     “”"
   188     if not _is_pil_image(img):
--> 189         raise TypeError(‘img should be PIL Image. Got {}’.format(type(img)))
   190     if not (isinstance(size, int) or (isinstance(size, collections.Iterable) and len(size) == 2)):
   191         raise TypeError(‘Got inappropriate size arg: {}’.format(size))

TypeError: img should be PIL Image. Got <class ‘str’>

It seems you are passing image as a string (maybe the image path?).
If that’s the case, load the image before passing it to predict:

image = Image.open(image_path)
predict(image, model)

Yes the image is the image path.
I made on purpose not to use image_path because of the other error.

I have load it. Here are two different errors.

image = Image.open(image_path)
predict(image, model)


NameError Traceback (most recent call last)
in ()
----> 1 image = Image.open(image_path)
2 predict(image, model)

NameError: name ‘image_path’ is not defined

Secondly, I did load this one. I got this.

image = Image.open(image)
predict(image, model)

I got another different error.
AttributeError Traceback (most recent call last)
in ()
----> 1 image = Image.open(image)
2 predict(image, model)

/opt/conda/lib/python3.6/site-packages/PIL/Image.py in open(fp, mode)
2587 exclusive_fp = True
2588
-> 2589 prefix = fp.read(16)
2590
2591 preinit()

AttributeError: ‘JpegImageFile’ object has no attribute ‘read’

I finally managed to fix the problem:
Unfortunately, I got another error.

AttributeError: ‘JpegImageFile’ object has no attribute ‘read’

Code:

def predict(image, model, topk=5):
    ''' 
      Predict the class (or classes) of an image using a trained deep learning model.
      Here, image is the path to an image file, but input to process_image should be                                                         
      Image.open(image)
    '''
    img = process_image(Image.open(image))
    img = torch.from_numpy(img).type(torch.FloatTensor) 

    output = model.forward(img)
    probs, labels = torch.topk(output, topk)        
    probs = probs.exp()

    # Reverse the dict
    idx_to_class = {val: key for key, val in model.class_to_idx.items()}
    # Get the correct indices
    top_classes = [idx_to_class[each] for each in classes]

    return labels, probs
probs, classes = predict(image, model)
print(probs)
print(classes)

Error

---------------------------------------------------------------------------
AttributeError                            Traceback (most recent call last)
<ipython-input-32-b49fdcab5791> in <module>()
----> 1 probs, classes = predict(image, model)
      2 print(probs)
      3 print(classes)

<ipython-input-31-6f996290ea63> in predict(image, model, topk)
      5       Image.open(image)
      6     '''
----> 7     img = process_image(Image.open(image))
      8     img = torch.from_numpy(img).type(torch.FloatTensor)
      9 

/opt/conda/lib/python3.6/site-packages/PIL/Image.py in open(fp, mode)
   2587         exclusive_fp = True
   2588 
-> 2589     prefix = fp.read(16)
   2590 
   2591     preinit()

AttributeError: 'JpegImageFile' object has no attribute 'read'

Could you post the following outputs:

print(image)
print(type(image))
image = Image.open(image)

I have used your code. This is what I got:

<PIL.JpegImagePlugin.JpegImageFile image mode=RGB size=695x500 at 0x7F3D941C15F8>
<class 'PIL.JpegImagePlugin.JpegImageFile'>

---------------------------------------------------------------------------
AttributeError                            Traceback (most recent call last)
<ipython-input-27-3d8674b159a4> in <module>()
      1 print(image)
      2 print(type(image))
----> 3 image = Image.open(image)

/opt/conda/lib/python3.6/site-packages/PIL/Image.py in open(fp, mode)
   2587         exclusive_fp = True
   2588 
-> 2589     prefix = fp.read(16)
   2590 
   2591     preinit()

AttributeError: 'JpegImageFile' object has no attribute 'read'

Thanks for the information.
How did you create image then?
You should pass the path to the image file to Image.open().

I created this code ( before predict function).

#Showing my image 
with Image.open('flowers/test/32/image_05591.jpg') as image:
    plt.imshow(image)

Do you think I should do this?

Image.open(image_path).

Yes, load the image and pass it to process_image:

image = Image.open('flowers/test/32/image_05591.jpg')
img = process_image(image)

After I have used your code.

image = Image.open('flowers/test/32/image_05591.jpg')
img = process_image(image)

This happens.

tensor([[[ 1.1015,  1.0331,  0.9474,  ..., -0.4739, -0.5253, -0.4397],
         [ 1.1015,  1.0502,  1.0159,  ..., -0.3541, -0.4911, -0.5253],
         [ 1.1187,  1.0673,  1.0331,  ..., -0.0287, -0.2513, -0.4739],
         ...,
         [-1.3644, -1.3644, -1.3815,  ..., -1.5357, -1.5870, -1.6384],
         [-1.3130, -1.3302, -1.3815,  ..., -1.5528, -1.5870, -1.6213],
         [-1.2959, -1.3644, -1.4500,  ..., -1.6213, -1.6213, -1.6213]],

        [[-1.5280, -1.5455, -1.5455,  ..., -0.1099, -0.0749,  0.0476],
         [-1.5105, -1.5455, -1.5455,  ..., -0.2150, -0.1099, -0.0574],
         [-1.5105, -1.5280, -1.5280,  ..., -0.0749,  0.0826,  0.0826],
         ...,
         [-1.1604, -1.1604, -1.1429,  ..., -1.3179, -1.3704, -1.4580],
         [-1.1078, -1.1078, -1.1604,  ..., -1.3704, -1.4055, -1.4405],
         [-1.0553, -1.1078, -1.1779,  ..., -1.3880, -1.3880, -1.3880]],

        [[-1.3687, -1.3861, -1.3861,  ..., -0.7413, -0.8110, -0.7413],
         [-1.3339, -1.3687, -1.3861,  ..., -0.7413, -0.8110, -0.8633],
         [-1.3339, -1.3513, -1.3687,  ..., -0.5670, -0.6193, -0.7761],
         ...,
         [-1.4733, -1.4907, -1.4907,  ..., -1.5430, -1.5953, -1.6650],
         [-1.4384, -1.4907, -1.5430,  ..., -1.5256, -1.5604, -1.5953],
         [-1.3513, -1.4559, -1.5430,  ..., -1.5430, -1.5256, -1.5256]]])

Great!
Looks like the image was successfully processed, so that you can now execute the remaining code. :slight_smile:

I understand… I am assuming I should change the name of the pathways …

I see. I guess I am going to change the name of the pathway…

I have changed the name:

image = Image.open('flowers/test/32/image_05591.jpg')
img = process_image(image)
def predict(image, model, topk=5):
    ''' 
      Predict the class (or classes) of an image using a trained deep learning model.
      Here, image is the path to an image file, but input to process_image should be                                                         
      Image.open(image)
    '''
    img = process_image(Image.open(img))
    img = torch.from_numpy(img).type(torch.FloatTensor) 

    output = model.forward(img)
    probs, labels = torch.topk(output, topk)        
    probs = probs.exp()

    # Reverse the dict
    idx_to_class = {val: key for key, val in model.class_to_idx.items()}
    # Get the correct indices
    top_classes = [idx_to_class[each] for each in classes]

    return labels, probs

The test it:

probs, classes = predict(image, model)
print(probs)
print(classes)

New errors:

---------------------------------------------------------------------------
UnboundLocalError                         Traceback (most recent call last)
<ipython-input-29-b49fdcab5791> in <module>()
----> 1 probs, classes = predict(image, model)
      2 print(probs)
      3 print(classes)

<ipython-input-28-2ef4f9abd430> in predict(image, model, topk)
      5       Image.open(image)
      6     '''
----> 7     img = torch.from_numpy(img).type(torch.FloatTensor)
      8 
      9     output = model.forward(img)

UnboundLocalError: local variable 'img' referenced before assignment

instead of ‘img’, you had to put ‘image’.

did it work anyway? i mean, did you fix the entire problem?