PIL.UnidentifiedImageError: cannot identify image file io.BytesIO object for deploying a PyTorch model in Flask

huangapple go评论81阅读模式
英文:

PIL.UnidentifiedImageError: cannot identify image file io.BytesIO object for deploying a PyTorch model in Flask

问题

这个错误通常是由于无法识别传入的图像文件格式引起的。您可以尝试以下方法来解决这个问题:

  1. 检查上传的图像文件格式:确保上传的图像文件是有效的图像格式(例如.jpg、.png)。如果文件不是有效的图像格式,那么PIL库将无法识别它。您可以使用文件扩展名或其他方法验证上传的文件是否是有效的图像文件。

  2. 确保图像文件在指定的路径上存在:您已经在代码中添加了一些打印语句来验证文件的存在性,但仍然遇到问题。确保文件位于指定的路径上,并且您的应用程序有权限访问该文件。还要确保文件路径的大小写与实际文件名相匹配,因为路径可能对大小写敏感。

  3. 检查图像数据是否完整:您可以在上传前,确保图像数据在传输过程中没有损坏。有时,图像数据可能因传输或存储问题而受损,导致PIL无法识别它。

  4. 使用不同的图像库:如果以上方法都没有解决问题,可以考虑使用不同的图像处理库,如OpenCV,来打开和处理图像。有时,不同的库可能对图像格式有不同的容忍度。

希望这些方法中的一种能够帮助您解决问题并成功运行您的应用程序。

英文:

I have a Python-Flask application where I upload an image onto a server and perform predictions on a selected uploaded image using a dense-net model following this tutorial, which results in the following error: PIL.UnidentifiedImageError: cannot identify image file <_io.BytesIO object at 0x7f4ceb257950>

Here is my prediction route:

@app.route('/predict', methods=['POST'])
@login_required
def predict():
    if request.method == 'POST':

        filename = ""
        if len(request.form) == 0:
            flash("Please select a file to perform a prediction on")
            return redirect(url_for('index'))
        else:

            filename = request.form['file']
            filepath = os.path.join(app.config['UPLOAD_PATH'], \
                                     current_user.username, filename)
            
            file = open(filepath, 'rb')
            img_bytes = file.read()
            class_id, class_name = models.get_prediction(image_bytes=img_bytes)
            print(class_id, class_name)


    return render_template('predict.html', filename=filename)

models.py:

import io
import json
import os

from torchvision import models
import torchvision.transforms as transforms
from PIL import Image

imagenet_class_index = json.load(open('imagenet_class_index.json'))
model = models.densenet121(pretrained=True)
model.eval()

def transform_image(image_bytes):
    my_transforms = transforms.Compose([transforms.Resize(255),
                                        transforms.CenterCrop(224),
                                        transforms.ToTensor(),
                                        transforms.Normalize(
                                            [0.485, 0.456, 0.406],
                                            [0.229, 0.224, 0.225])])
    
    image = Image.open(io.BytesIO(image_bytes))
    return my_transforms(image).unsqueeze(0)

def get_prediction(image_bytes):
    tensor = transform_image(image_bytes=image_bytes)
    outputs = model.forward(tensor)
    _, y_hat = outputs.max(1)
    predicted_idx = str(y_hat.item())
    return imagenet_class_index[predicted_idx]

stack trace:

[2023-03-03 13:49:32,564] ERROR in app: Exception on /predict [POST]
Traceback (most recent call last):
  File "/mnt/c/Users/sahan/Desktop/Senior Year/CS 81a/Sahana-cs81a/venv/lib/python3.8/site-packages/flask/app.py", line 2525, in wsgi_app
    response = self.full_dispatch_request()
  File "/mnt/c/Users/sahan/Desktop/Senior Year/CS 81a/Sahana-cs81a/venv/lib/python3.8/site-packages/flask/app.py", line 1822, in full_dispatch_request        
    rv = self.handle_user_exception(e)
  File "/mnt/c/Users/sahan/Desktop/Senior Year/CS 81a/Sahana-cs81a/venv/lib/python3.8/site-packages/flask/app.py", line 1820, in full_dispatch_request        
    rv = self.dispatch_request()
  File "/mnt/c/Users/sahan/Desktop/Senior Year/CS 81a/Sahana-cs81a/venv/lib/python3.8/site-packages/flask/app.py", line 1796, in dispatch_request
    return self.ensure_sync(self.view_functions[rule.endpoint])(**view_args)
  File "/mnt/c/Users/sahan/Desktop/Senior Year/CS 81a/Sahana-cs81a/venv/lib/python3.8/site-packages/flask_login/utils.py", line 290, in decorated_view        
    return current_app.ensure_sync(func)(*args, **kwargs)
  File "/mnt/c/Users/sahan/Desktop/Senior Year/CS 81a/Sahana-cs81a/cloudsystem/app.py", line 311, in predict
    class_id, class_name = models.get_prediction(image_bytes=img_bytes)
  File "/mnt/c/Users/sahan/Desktop/Senior Year/CS 81a/Sahana-cs81a/cloudsystem/models.py", line 25, in get_prediction
    tensor = transform_image(image_bytes=image_bytes)
  File "/mnt/c/Users/sahan/Desktop/Senior Year/CS 81a/Sahana-cs81a/cloudsystem/models.py", line 21, in transform_image
    image = Image.open(io.BytesIO(image_bytes))
  File "/mnt/c/Users/sahan/Desktop/Senior Year/CS 81a/Sahana-cs81a/venv/lib/python3.8/site-packages/PIL/Image.py", line 3283, in open
    raise UnidentifiedImageError(msg)
PIL.UnidentifiedImageError: cannot identify image file <_io.BytesIO object at 0x7f4c48b2ea40>

I have tried this with no success as well as ensuring that only valid file types (i.e. .png, .jpg) can be uploaded. I've also tried passing in the path name instead of file bytes, which results in a FileNotFoundError. I've double checked to make sure that the path is correct and the file does indeed exist in my local directory. Using OpenCV instead results in the same error as above. For now, I just want the prediction results to be printed in the terminal. Thank you!

Edit (1): Here are the first 20 bytes of image_bytes getting passed into PIL: b'\xde\xcf\x13J5.p\xf5\xe5Qt9\xd7\xb5 \xda\x1d\xab4\xa0'

Edit (2): Since the bytes of the file don't correspond to any image format, I tried to pass in the image path into Image.open() instead:

if os.path.isfile(filepath):
        print(filepath + " is a valid file from app.py")
class_id, class_name = models.get_prediction(filepath)

The print statement is printing the path, so I assume that the path being passed into models.get_prediction() is valid.

The transform_image() function now looks like this:

def transform_image(path):
    my_transforms = transforms.Compose([transforms.Resize(255),
                                        transforms.CenterCrop(224),
                                        transforms.ToTensor(),
                                        transforms.Normalize(
                                            [0.485, 0.456, 0.406],
                                            [0.229, 0.224, 0.225])])
    
    if os.path.isfile(path):
        print(path + " is a valid file from models.py")    
    image = Image.open(path)
    return my_transforms(image).unsqueeze(0)

Once again, the path of the inputted file is printing, so the file must exist within the path. However, I'm still getting the following error from Image.open(path): PIL.UnidentifiedImageError: cannot identify image file 'uploads/test/Cat03.jpg.

答案1

得分: 0

问题是在先前调用的图像验证函数中读取了图像缓冲区的一部分,导致图像未正确存储。移除读取图像缓冲区的代码行解决了问题。

英文:

The issue was that a part of the image buffer was being read in a previously called function for image validation and as a result the image wasn't being stored correctly. Removing the line of code reading the image buffer fixed the problem.

huangapple
  • 本文由 发表于 2023年3月4日 06:11:41
  • 转载请务必保留本文链接:https://go.coder-hub.com/75632283.html
匿名

发表评论

匿名网友

:?: :razz: :sad: :evil: :!: :smile: :oops: :grin: :eek: :shock: :???: :cool: :lol: :mad: :twisted: :roll: :wink: :idea: :arrow: :neutral: :cry: :mrgreen:

确定