PIL.UnidentifiedImageError:无法标识用于在Flask中部署PyTorch模型的映像文件io.BytesIO对象

0sgqnhkj  于 2023-03-18  发布在  其他
关注(0)|答案(1)|浏览(378)

我有一个Python-Flask应用程序,在该应用程序中,我将图像上传到服务器,并使用this tutorial之后的密集网模型对选定的上传图像执行预测,这会导致以下错误:PIL.UnidentifiedImageError: cannot identify image file <_io.BytesIO object at 0x7f4ceb257950>
以下是我的预测路线:

@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]

堆栈跟踪:

[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>

我已经尝试了this没有成功,以及确保只有有效的文件类型(即.png,.jpg)可以上传。我也尝试过传入路径名而不是文件字节,这将导致FileNotFoundError。我已经仔细检查了路径是否正确,并且该文件确实存在于我的本地目录中。使用OpenCV将导致与上面相同的错误。目前,我只希望预测结果能在终端打印出来,谢谢!
Edit(1):以下是传入PIL的image_bytes的前20个字节:“五...四...”
Edit(2):由于文件的字节数与任何图像格式都不对应,我尝试将图像路径传入Image.open()

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

print语句打印路径,所以我假设传入models.get_prediction()的路径是有效的。
transform_image()函数现在如下所示:

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)

同样,输入文件的路径正在打印,所以文件必须存在于路径中。但是,我仍然从Image.open(path)得到以下错误:PIL.UnidentifiedImageError: cannot identify image file 'uploads/test/Cat03.jpg .

hgc7kmma

hgc7kmma1#

问题是在先前调用的函数中读取了图像缓冲区的一部分以进行图像验证,因此图像未正确存储。删除阅读图像缓冲区的代码行修复了该问题。

相关问题