YOLOv8+PySide6条形码保质期识别检测系统

YOLOv8+PySide6条形码保质期识别检测系统 这次我们来看一个落地性很强的本地部署项目基于 YOLOv8 / YOLOv5 PySide6 的条形码保质期识别检测系统。它要解决的需求很明确——从一张包含商品包装的图片里定位条形码区域识别保质期相关文字最终在桌面界面里输出结果。整个系统的核心组合是YOLO 系列目标检测模型负责“找到目标”OCR 负责“读出文字”PySide6 负责“做成能用的桌面工具”。先说结论这个项目适合谁。如果你是做食品、药品、日化品质检相关系统的开发者或者想把 YOLOv8 目标检测和 PySide6 桌面 GUI 串成一个完整小系统的人那这篇文章可以直接收藏。文章会依次讲清楚核心能力、环境准备、YOLOv8 模型训练、保质期 OCR 识别、PySide6 界面实现以及批量任务和接口扩展。从硬件门槛看这个项目并不高。条形码检测用 YOLOv8n 这种轻量模型普通 CPU 就能推理只是速度会慢一些用 GPU 会更顺。像 GTX 1660 Ti 这种 6GB 显存的显卡也能完成训练和推理关键是把 batch size 和图片分辨率调低。更稳妥的判断是实际显存占用需要以你本机环境为准但这不是一个必须 24GB 大显存才能跑的项目。1. 核心能力速览先给一张规格速览表后面再展开细节。能力项说明项目类型本地部署的目标检测 OCR 识别桌面系统目标检测框架YOLOv8 / YOLOv5推荐 YOLOv8界面框架PySide6Qt for Python主要功能条形码定位、保质期区域定位、OCR 日期解析、图片检测、批量扫描扩展能力可接 API 服务可批量处理文件夹图片可导出 CSV硬件要求CPU 可运行GPU 加速效果更好显存需求与模型规格、输入分辨率有关需实际测试支持平台Windows / Linux满足 PySide6 和 PyTorch 安装条件的系统均可启动方式命令行启动 Python 脚本或打包成 exe 后双击运行是否支持 API可通过 FastAPI 等框架自行封装是否支持批量任务支持批量遍历目录图片并输出结构化结果适合场景商超入库、仓储盘点、食品保质期抽检、自动化测试从功能上看这个系统最大的特点是把“目标检测”和“文字识别”放到了一条流水线里。YOLOv8 负责定位OCR 负责解读最后用 PySide6 把整个流程包装成普通用户能直接操作的工具。2. 系统架构与核心工作流程这套系统的完整工作流程可以拆成三层。第一层是图像输入层。支持单张图片、文件夹批量图片也可以扩展摄像头实时读取。图片进入系统后先做必要的预处理包括缩放、色彩空间转换、对比度增强等。第二层是检测识别层。这里有两件事用 YOLOv8 或 YOLOv5 模型定位条形码区域和保质期区域把定位到的区域裁剪出来交给 OCR 引擎读取文本再用正则表达式解析出日期信息。第三层是应用层。PySide6 负责展示检测结果包括原图标注框、识别出的条形码编号、保质期文本、是否过期等。同时可以导出结果也可以把识别逻辑封装成 API 或批量任务。整体数据流如下输入图片 - YOLO 模型检测 - 生成检测框与类别 | v 按类别裁剪区域 | v OCR 文本识别 | v 日期解析与过期判断 | v PySide6 界面展示 / 批量导出 / API 返回之所以把“条形码定位”和“保质期识别”分开是因为这两个目标在图像中的特征完全不同。条形码是一组黑白条纹纹理特征明显保质期文字则是数字和汉字混合的印刷文本。用同一个模型直接端到端识别文字并不现实更稳的做法是检测模型负责定位OCR 负责识别。3. 适用场景与合理使用边界这个系统适合处理以下几种场景商品外包装检测在入库环节批量识别条形码和保质期判断商品是否临期或过期。质检抽样对生产线或仓库中的商品图片进行抽检减少人工翻看包装的时间。自动化测试把图片批量灌入系统验证 OCR 识别效果和检测模型精度。教学演示学习 YOLOv8 自定义数据集训练以及 PySide6 桌面应用的完整开发流程。但它也不是万能的。需要注意几个边界保质期印刷质量差、遮挡严重或倾斜角度过大时OCR 识别率会明显下降。如果商品包装上同时出现多个条形码检测模型需要专门训练才能区分。这个系统做的是“识别”不是“数据库核验”。它只能读出图片上的文字不能判断这个商品在数据库里是否临期。涉及真实商品的条形码、保质期、库存数据时必须遵守企业数据使用规定不能把收集到的数据用于未经授权的用途。在实际部署中合规意识要放在前面。系统可以定位到条形码并识别保质期但你不能用它去绕过任何商业系统也不能用它处理来源不明或版权受限的数据。用于生产环境前需要和业务方确认数据授权范围。4. 环境准备与前置条件这个项目的核心依赖是 PyTorch、YOLOv8 和 PySide6。先做环境检查再开始安装。4.1 操作系统与 Python 版本建议使用 Windows 10/11 或 Ubuntu 20.04 以上系统。Python 版本推荐 3.9 或 3.10兼容性比较稳妥。PySide6 对 Python 版本有要求3.10 是当前比较通用的选择。如果使用 Python 3.12 以上需要确认 PySide6 和 PyTorch 都有对应版本。4.2 GPU 与 CPU 要求CPU 推理可以使用但检测速度会明显变慢。建议用于测试和小批量场景。GPU 推理NVIDIA 显卡需要安装对应版本的 CUDA 驱动。GTX 1660 Ti、RTX 3060 这类 6GB 显存的显卡可以跑batch size 和图片分辨率需要控制。纯 CPU 环境也能运行 YOLOv8n只是对高分辨率图片的推理时间会偏长。4.3 必要依赖在项目目录下创建虚拟环境然后安装以下核心依赖# 创建虚拟环境 conda create -n barcode_ocr python3.10 -y conda activate barcode_ocr # 安装 PyTorch先确认自己的 CUDA 版本 pip install torch torchvision torchaudio --index-url https://download.pytorch.org/whl/cu118 # 安装 YOLOv8 依赖库 pip install ultralytics # 安装 PySide6 桌面界面库 pip install PySide6 # 图像处理工具 pip install opencv-python numpy pandas # OCR 引擎推荐 PaddleOCR pip install paddlepaddle paddleocr如果机器没有 NVIDIA GPU可以不安装 CUDA 版 PyTorch直接安装 CPU 版。安装前在终端里执行nvidia-smi查看驱动支持的 CUDA 版本再选择对应的 PyTorch 安装命令。4.4 模型文件YOLOv8 的预训练模型可以通过 ultralytics 库自动下载。执行训练或推理时代码会自动从官方地址拉取yolov8n.pt等权重文件。如果你的网络下载速度不稳定也可以手动下载后放到项目目录里。需要注意预训练模型只能检测 COCO 80 类不会直接识别条形码必须用自己的数据集微调。4.5 磁盘空间一个 YOLOv8n 权重文件约 6MB一个 YOLOv8s 约 22MB训练时产生的日志、预测图和权重文件会占用几百 MB 到几 GB。OCR 模型文件通常也会占用几百 MB。建议预留至少 10GB 空间。5. 安装部署与启动方式这里给出一套可复用的项目结构。你不需要完全照抄但按这个结构组织代码后续扩展会轻松很多。barcode_expiry_system/ ├── main.py # PySide6 界面入口 ├── detect.py # YOLO 检测与识别逻辑 ├── ocr_parser.py # OCR 与日期解析 ├── batch_scan.py # 批量任务脚本 ├── api_server.py # FastAPI 接口服务 ├── models/ │ └── best.pt # 训练好的检测模型 ├── datasets/ │ ├── images/ │ └── labels/ ├── inputs/ # 待检测图片 ├── outputs/ # 结果输出 └── requirements.txt5.1 安装依赖将上面的 pip 安装命令整理成requirements.txt文件torch torchvision ultralytics PySide6 opencv-python numpy pandas paddlepaddle paddleocr fastapi uvicorn然后执行pip install -r requirements.txt5.2 启动桌面界面最简单的启动方式是直接运行主程序python main.py启动成功后会弹出 PySide6 窗口。界面内可以点击按钮选择图片然后触发检测。5.3 启动 API 服务如果不想打开桌面窗口只是想给其他系统提供识别能力可以启动 API 服务uvicorn api_server:app --host 0.0.0.0 --port 8000启动后可以用接口请求方式传入图片路径或图片文件。5.4 打包成 exe如果要把系统给非技术用户使用可以用 PyInstaller 打包pip install pyinstaller pyinstaller -w -F main.py --name BarcodeExpirySystem打包时需要把best.pt模型文件放到对应目录并确保 PyInstaller 能收集到 ultralytics 和 PySide6 的依赖。首次打包容易出现缺文件的问题需要根据报错逐个补齐。6. 条形码检测YOLOv8 模型准备与训练这是整个系统的核心。YOLOv8 预训练模型本身不认识条形码所以你需要准备自己的数据集重新训练一个检测模型。下面按数据准备、模型训练、效果验证三步展开。6.1 数据集准备数据集的标注格式和 YOLO 系列通用格式一致。每一张图片对应一个.txt标签文件里面的每一行代表一个目标class_id x_center y_center width height坐标值需要归一化到 0-1 之间。例如一张 1920x1080 的图片里条形码框的左上角是 (100, 200)右下角是 (500, 400)那么中心点坐标是 (300, 300)宽度是 400高度是 200归一化后就是0 0.15625 0.27778 0.20833 0.18519标注工具可以使用 LabelImg 或 Label Studio。如果希望省事也可以用 Roboflow 在线标注并导出 YOLO 格式。条形码数据集的收集建议尽量覆盖不同光照条件包括室内灯、自然光、昏暗环境。覆盖不同拍摄角度包括正面、略微倾斜、俯拍。覆盖不同包装材质包括塑料、纸盒、玻璃瓶。样本数量根据实际场景决定常规试验可以先从几百到上千张开始。如果只是验证流程先准备 100 张左右也能跑通全流程。如果不仅识别条形码还要识别保质期位置可以把标签类别设计成两类names: 0: barcode 1: expiry_dateYOLOv5 的数据集格式和 YOLOv8 几乎相同因此这份数据也可以在两个框架之间复用。这也是项目标题里写“YOLOv8 / YOLOv5”的原因你的整体流程不绑定具体某个 YOLO 版本。6.2 训练 YOLOv8 模型数据目录结构如下datasets/ ├── barcode/ │ ├── images/ │ │ ├── train/ │ │ └── val/ │ ├── labels/ │ │ ├── train/ │ │ └── val/ │ └── barcode.yamlbarcode.yaml内容示例path: ./datasets/barcode train: images/train val: images/val names: 0: barcode 1: expiry_date训练脚本from ultralytics import YOLO model YOLO(yolov8n.pt) model.train( datadatasets/barcode/barcode.yaml, epochs100, imgsz640, batch8, device0, # CPU 环境改成 devicecpu workers2, projectruns/train, namebarcode_exp, )在 GTX 1660 Ti 这类 6GB 显存显卡上建议把 imgsz 设为 640batch 设为 8。如果显存不足先降 batch 到 4 或 2。不要一开始就用 100 轮去跑完整训练先用 10 轮验证流程是否通顺。训练完成后在runs/train/barcode_exp/weights/目录下会生成best.pt和last.pt。best.pt是验证集上效果最好的权重后续推理要用它。ultralytics 还会自动生成results.png里面包含训练损失和验证指标的曲线图这就是很多人常说的 YOLOv8 损失函数曲线。观察损失曲线时重点看是否收敛、有没有剧烈震荡。6.3 推理验证训练完成后用一张测试图片验证from ultralytics import YOLO model YOLO(runs/train/barcode_exp/weights/best.pt) results model.predict( sourceinputs/test_01.jpg, conf0.45, imgsz640, saveTrue, projectoutputs, namedetect_result, ) for result in results: boxes result.boxes for box in boxes: cls_id int(box.cls[0]) conf float(box.conf[0]) xyxy [int(v) for v in box.xyxy[0].tolist()] print(model.names[cls_id], conf, xyxy)预测结果里会保存带有标注框的图片终端同时输出每个框的类别、置信度和坐标。7. 保质期识别OCR 与日期解析实现YOLO 模型定位到expiry_date区域后下一步是把这个区域裁剪出来交给 OCR 识别。7.1 OCR 识别代码这里以 PaddleOCR 为例它在中文包装印刷体上的识别效果比较稳定from paddleocr import PaddleOCR import cv2 ocr PaddleOCR(use_angle_clsTrue, langch, show_logFalse) def extract_text_from_region(img, region): x1, y1, x2, y2 [int(v) for v in region] crop img[y1:y2, x1:x2] result ocr.ocr(crop, clsTrue) if not result or not result[0]: return lines [] for line in result[0]: text line[1][0] confidence line[1][1] if confidence 0.5: lines.append(text) return \n.join(lines)7.2 日期正则解析OCR 返回的文本不是标准结构里面可能混着汉字、数字和其他字符。需要用正则表达式把日期提取出来。常见格式有2025-08-302025/08/302025.08.302025年08月30日保质期至2025-08-30示例代码import re from datetime import datetime def parse_expiry_date(text): if not text: return None patterns [ r(20\d{2})[年./-](\d{1,2})[月./-](\d{1,2})日? ] for pattern in patterns: match re.search(pattern, text) if match: year int(match.group(1)) month int(match.group(2)) day int(match.group(3)) try: return datetime(year, month, day) except ValueError: return None return None def check_expired(expiry_date: datetime): if expiry_date is None: return 未识别到日期 if expiry_date datetime.now(): return 已过期 return 未过期这里需要注意OCR 可能会把数字 0 识别成 O把 8 识别成 B这类问题需要在实际样本里慢慢补充规则。更复杂的做法是训练一个专用的文本识别模型或者对 OCR 文本做字符串校准。7.3 完整识别流程串联把检测和 OCR 串起来import cv2 from ultralytics import YOLO class BarcodeExpiryDetector: def __init__(self, model_path): self.model YOLO(model_path) def detect(self, image_path): img cv2.imread(image_path) results self.model.predict(img, conf0.45, imgsz640) barcode_boxes [] expiry_boxes [] for result in results: boxes result.boxes for box in boxes: cls_id int(box.cls[0]) xyxy [int(v) for v in box.xyxy[0].tolist()] if cls_id 0: barcode_boxes.append(xyxy) elif cls_id 1: expiry_boxes.append(xyxy) return img, barcode_boxes, expiry_boxes这个BarcodeExpiryDetector类可以同时被 PySide6 界面和 API 服务复用避免重复写模型加载逻辑。8. PySide6 桌面界面实现PySide6 是整个系统的“门面”。它负责让用户能上传图片、点击检测、看到结果。8.1 界面布局一个最简版本包含以下控件图片显示区域QLabel用来展示原图和检测后的标注图。选择图片按钮QPushButton。开始检测按钮QPushButton。结果文本区域QTextEdit展示检测到的条形码信息、保质期和过期状态。界面布局采用垂直布局加水平布局组合import sys import cv2 from PySide6.QtWidgets import ( QApplication, QMainWindow, QPushButton, QLabel, QFileDialog, QVBoxLayout, QHBoxLayout, QWidget, QTextEdit ) from PySide6.QtGui import QPixmap, QImage from PySide6.QtCore import Qt class MainWindow(QMainWindow): def __init__(self, detector): super().__init__() self.detector detector self.setWindowTitle(条形码保质期识别检测系统) self.resize(1024, 720) self.image_label QLabel(请选择图片) self.image_label.setAlignment(Qt.AlignCenter) self.image_label.setMinimumWidth(640) self.select_btn QPushButton(选择图片) self.detect_btn QPushButton(开始检测) self.result_text QTextEdit() self.result_text.setReadOnly(True) btn_layout QHBoxLayout() btn_layout.addWidget(self.select_btn) btn_layout.addWidget(self.detect_btn) main_layout QVBoxLayout() main_layout.addWidget(self.image_label) main_layout.addLayout(btn_layout) main_layout.addWidget(self.result_text) container QWidget() container.setLayout(main_layout) self.setCentralWidget(container) self.current_path None self.select_btn.clicked.connect(self.select_image) self.detect_btn.clicked.connect(self.run_detect) def select_image(self): path, _ QFileDialog.getOpenFileName( self, 选择图片, ./inputs, Images (*.png *.jpg *.jpeg *.bmp) ) if path: self.current_path path pixmap QPixmap(path) self.image_label.setPixmap(pixmap.scaled( self.image_label.width(), self.image_label.height(), Qt.KeepAspectRatio )) def run_detect(self): if not self.current_path: self.result_text.setText(请先选择图片) return img, barcode_boxes, expiry_boxes self.detector.detect(self.current_path) for box in barcode_boxes: x1, y1, x2, y2 box cv2.rectangle(img, (x1, y1), (x2, y2), (0, 255, 0), 2) for box in expiry_boxes: x1, y1, x2, y2 box cv2.rectangle(img, (x1, y1), (x2, y2), (0, 0, 255), 2) img_rgb cv2.cvtColor(img, cv2.COLOR_BGR2RGB) height, width, channel img_rgb.shape bytes_per_line channel * width q_img QImage(img_rgb.data, width, height, bytes_per_line, QImage.Format_RGB888) self.image_label.setPixmap(QPixmap.fromImage(q_img).scaled( self.image_label.width(), self.image_label.height(), Qt.KeepAspectRatio )) self.result_text.append(f检测到条形码: {len(barcode_boxes)} 个) self.result_text.append(f检测到保质期区域: {len(expiry_boxes)} 个) if __name__ __main__: app QApplication(sys.argv) detector None # 实际需要传入训练好的检测器 window MainWindow(detector) window.show() sys.exit(app.exec())这里需要注意一个常见坑OpenCV 读图是 BGR 通道顺序PySide6 的 QImage 通常需要 RGB 格式展示前必须用cv2.cvtColor转换否则颜色会偏蓝偏红。8.2 长耗时任务的线程问题run_detect里直接调用 YOLO 推理如果处理高分辨率图片或大量图片界面会卡住。解决方式是使用 QThread 将推理放到子线程主线程只负责更新界面。项目初期可以先用简单的同步调用但要意识到这个瓶颈。9. 接口扩展与批量任务处理9.1 批量任务脚本批量扫描文件夹内的所有图片import glob import csv import os from detect import BarcodeExpiryDetector detector BarcodeExpiryDetector(models/best.pt) input_dir inputs output_csv outputs/result.csv results [] for img_path in glob.glob(os.path.join(input_dir, *.jpg)) glob.glob(os.path.join(input_dir, *.png)): print(processing:, img_path) img, barcode_boxes, expiry_boxes detector.detect(img_path) results.append({ image: img_path, barcode_count: len(barcode_boxes), expiry_region_count: len(expiry_boxes), }) with open(output_csv, w, newline, encodingutf-8-sig) as f: writer csv.DictWriter(f, fieldnames[image, barcode_count, expiry_region_count]) writer.writeheader() writer.writerows(results) print(done, total:, len(results))CSV 导出时使用utf-8-sig编码Excel 打开中文不会乱码。9.2 FastAPI 接口如果需要给其他系统调用可以封装成 API。参考代码如下from fastapi import FastAPI, UploadFile, File import cv2 import numpy as np from detect import BarcodeExpiryDetector app FastAPI() detector BarcodeExpiryDetector(models/best.pt) app.post(/scan) async def scan_image(file: UploadFile File(...)): contents await file.read() nparr np.frombuffer(contents, np.uint8) img cv2.imdecode(nparr, cv2.IMREAD_COLOR) barcode_boxes [] expiry_boxes [] results detector.model.predict(img, conf0.45, imgsz640) for result in results: boxes result.boxes for box in boxes: cls_id int(box.cls[0]) xyxy [int(v) for v in box.xyxy[0].tolist()] if cls_id 0: barcode_boxes.append(xyxy) else: expiry_boxes.append(xyxy) return { barcode_count: len(barcode_boxes), expiry_region_count: len(expiry_boxes), barcode_boxes: barcode_boxes, expiry_boxes: expiry_boxes, }启动接口后用 curl 做一次最简单的验证curl -X POST -F fileinputs/test_01.jpg http://127.0.0.1:8000/scan9.3 调用接口的 Python 客户端import requests url http://127.0.0.1:8000/scan files {file: open(inputs/test_01.jpg, rb)} response requests.post(url, filesfiles, timeout60) print(response.json())接口能力让这个系统从“单人本地工具”升级成“可被其他系统调用的识别服务”。在部署API服务时要注意两点一是本地局域网调试时建议监听127.0.0.1不要直接暴露到公网二是如果要在生产环境提供服务需要加上认证和请求频率限制。10. 资源占用与性能观察这个项目涉及两个主要资源消耗点PySide6 界面自身的内存占用以及 YOLO 模型推理时产生的显存和 CPU 占用。需要明确的是本文没有跑基准测试以下给出的是通用观察方法而不是固定数据。10.1 显存观察方法在训练或推理过程中可以用 NVIDIA 的命令行工具查看显存占用nvidia-smi -l 2-l 2表示每 2 秒刷新一次。重点看GPU Memory Usage一栏。10.2 影响性能的关键参数参数影响imgsz输入分辨率越大检测越慢显存占用越高batch训练时 batch 越大显存占用越高conf置信度阈值越低框越多后处理时间越长图片尺寸输入的原始图片越大预处理时间越长OCR 引擎类型CPU 推理时OCR 是主要耗时点10.3 降低资源占用的方法使用 YOLOv8n 而不是 YOLOv8x。推理时把 imgsz 设为 640不要直接对 4000 像素大图推理。在检测前对大图先做缩放。OCR 只对裁剪出来的小区域执行不要整张图跑 OCR。训练时梯度积累或降低 batch避免显存溢出。关闭其他占用显存的程序。11. 常见问题与排查方法以下是根据常见本地部署经验整理的排查清单问题现象可能原因排查方式解决方案PySide6 启动后白屏或闪退PySide6 版本不兼容终端运行python main.py查看报错升级或重装 PySide6检查 Python 版本YOLO 推理一直在 CPU 上执行torch 是 CPU 版本或 CUDA 不匹配执行python -c import torch; print(torch.cuda.is_available())安装对应 CUDA 版 PyTorch模型无法检测到条形码训练数据中条形码样本太少查看预测结果检查训练集数量增加样本加大训练轮数保质期 OCR 乱码印刷模糊、倾斜、明暗不均检查裁剪区域图片质量先对裁剪区域做二值化、对比度增强显存不足batch 或 imgsz 过大观察nvidia-smi降低 batch降低 imgszGPU 显存充足但训练很慢workers 太小或 GPU 利用率低查看 GPU 利用率调大 workers检查数据加载瓶颈API 请求超时推理时间过长或图片过大查看服务日志限制上传图片大小压缩图片后再推理批量任务卡住单张图片 OCR 卡死或异常在循环里打印当前图片路径增加异常捕获和失败重试打包 exe 后模型文件丢失PyInstaller 未包含best.pt查看打包日志使用--add-data指定模型路径识别出多个重复框NMS 阈值设置不合理检查预测框的置信度调高 conf或调整 NMS 参数排查时最有效的方法是看终端日志。开发阶段不要隐藏异常直接让程序把 traceback 打出来再针对报错信息搜索解决办法。12. 最佳实践与合规注意事项12.1 工程化建议先跑通最小流程再迭代优化。第一次做这个系统不要追求 100 类目标、复杂模型和多线程界面。先用一类barcode、一类expiry_date在几十张图片上训练 10 轮确认能检测到目标再考虑数据量扩充。模型文件和输入输出目录要分清楚。推荐这样组织models/ # 存放权重文件不直接放在项目根目录 inputs/ # 待检测图片不放入模型目录 outputs/ # 检测结果和导出文件自动生成子目录 logs/ # 运行日志批量任务必须加日志和失败重试机制。因为 OCR 对模糊图片的识别结果不稳定遇到识别失败应该记录原始图片路径和失败原因不要静默跳过。API 服务要限制访问范围。本地开发时监听127.0.0.1跨机器访问时不要裸奔在公网需要加 Token 或 Basic Auth。上传接口要限制文件大小和文件类型避免恶意图片导致内存溢出。12.2 数据与授权提醒这个系统识别的是真实商品包装上的条形码和保质期文字。使用它处理数据时需要注意如果数据来自企业内部的商品库或供应商系统需要确认你有处理这些图片的授权。不要在未授权的情况下把批量识别的条形码数据用于第三方分析或公开分享。如果系统后续接入人脸识别、身份信息或敏感数据必须单独做合规评估。本文讨论的场景仅限普通商品包装识别。13. 总结与下一步这个项目最值得尝试的地方不是单个 YOLOv8 模型有多强而是它把“目标检测 OCR 桌面界面”三个环节完整串了起来。学完这套流程你不仅能做一个条形码保质期识别工具也能把这套模式迁移到其他检测识别场景比如车牌识别、单据识别、货物标签识别。拿到项目后建议按这个顺序验证先确认 PySide6 能正常启动一个空窗口。再用预训练 YOLOv8 模型跑通推理流程确认 CUDA 环境正常。准备一个几十张图片的小数据集训练一个最简模型。把 OCR 和日期解析接上用 10 张真实图片验证识别效果。最后再封装 API 和批量任务。最容易踩的坑是环境问题。PyTorch 的 CUDA 版本和 PySide6 的 Python 版本不匹配时报错会很莫名其妙。建议所有依赖都装进虚拟环境不要用系统 Python 直接装。后续扩展方向也很明确可以用 YOLOv8-seg 做实例分割处理条形码区域更精细可以把 OCR 换成专门的中文文本识别模型提高保质期文字识别率可以在界面里加入摄像头实时检测可以把模型训练和推理服务拆开做成一个独立的模型服务平台。先把基础流程跑通后面每一步都顺。