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
相关产品推荐
相关产品推荐

