You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

Django接收表单文件做OCR时出现io.UnsupportedOperation: fileno错误求助

问题解决:Django上传文件OCR时触发io.UnsupportedOperation: fileno错误

错误原因

你传给recognize_plate的是Django的InMemoryUploadedFile/TemporaryUploadedFile对象,而cv2.imread()(被ultralytics补丁重写后)需要的是本地文件路径字符串,不是文件流对象。当底层调用np.fromfile尝试获取文件描述符时,内存中的文件对象没有fileno属性,因此抛出错误。

解决方法

方法1:直接读取文件字节(推荐,无需创建临时文件)

修改recognize_plate函数,通过文件字节直接解析为OpenCV格式:

import numpy as np
import cv2
from hezar import Model
from ultralytics import YOLO

def recognize_plate(plate_file):
    results = {}
    # 加载模型
    model = Model.load("hezarai/crnn-fa-64x256-license-plate-recognition")
    license_plate_detector = YOLO('repairman/plate_recognition/best.pt')

    # 读取上传文件的字节数据,转换为OpenCV可处理的格式
    file_bytes = np.asarray(bytearray(plate_file.read()), dtype=np.uint8)
    frame = cv2.imdecode(file_bytes, cv2.IMREAD_COLOR)

    # 后续车牌检测、字符识别逻辑写在这里
    # 示例:检测车牌
    detections = license_plate_detector(frame)
    # 处理检测结果并识别字符...

    return results  # 返回最终识别结果

方法2:保存为临时文件后读取(适合需要文件路径的场景)

如果你的模型必须依赖文件路径,可以先将上传的文件保存到临时路径:

import tempfile
import cv2
import os
from hezar import Model
from ultralytics import YOLO

def recognize_plate(plate_file):
    results = {}
    # 加载模型
    model = Model.load("hezarai/crnn-fa-64x256-license-plate-recognition")
    license_plate_detector = YOLO('repairman/plate_recognition/best.pt')

    # 创建临时文件保存上传图片
    with tempfile.NamedTemporaryFile(delete=False, suffix='.jpg') as temp_file:
        temp_file.write(plate_file.read())
        temp_path = temp_file.name
    
    # 通过临时路径读取图片
    frame = cv2.imread(temp_path)

    # 后续检测、识别逻辑...

    # 处理完成后删除临时文件(可选)
    os.unlink(temp_path)

    return results

优化views.py代码(可选)

使用表单验证后的cleaned_data获取文件对象,比直接读取request.FILES更可靠:

@login_required(login_url='/profile/login/')
def repairman_profile(request):
    user = request.user
    repairman = RepairmanUser.objects.get(user=user)

    if request.method == 'POST':
        plate_form = PlateForm(request.POST, request.FILES)

        if plate_form.is_valid():
            # 从cleaned_data获取验证后的文件对象
            plate_image = plate_form.cleaned_data.get("plate_image")
            plate = recognize_plate(plate_image)
            return HttpResponse(plate)
    else:
        plate_form = PlateForm()

    context = {
        "repairman": repairman,
        'plate_form': plate_form,
    }
    return render(request, 'repairman/profile.html', context=context)

内容的提问来源于stack exchange,提问作者parham mazahery

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.06.21 22:04:53