资讯动态

YOLOv10可回收塑料识别分类检测系统:数据集训练到界面部署全流程

发布时间:2026/10/19 12:25:02 来源:尧图企业网站定制
做过识别项目的人应该都有同感模型选型只是第一步真正磨人的是数据、训练和产品化那一段路。这个项目标题里写的“YOLOv10可回收塑料识别分类检测系统”本质上就是一个完整的目标检测小产品——从塑料瓶到塑料袋能在画面里标出来类别、画上框再通过界面直接操作。YOLOv10负责模型侧数据集负责教会模型认瓶子UI界面负责把能力交到用户手里。这篇文章就把整个系统从数据集到界面部署完整拆开讲一遍内容包括七个典型可回收塑料类别的标注与训练、v10的端到端推理优势、基于PySide6的界面实现、摄像头与图片检测的接入方式以及我在实际搭建中踩过的一些坑。无论你是课程设计、毕业项目还是想做环保方向的Demo这套思路可以直接复用。1. 项目整体拆解与选型思路1.1 系统解决的核心问题可回收塑料的分拣在现实里并不像想象中那么简单。一只压扁的矿泉水瓶、一个酱料罐、一张保鲜膜从视觉上看都是“塑料”但材质完全不同——PET、HDPE、PP这些名称背后对应的是不同的回收再生流程。人工目检分拣效率低、容易疲劳传统图像处理又很难适应复杂背景和光照变化所以一套能自动识别并分类塑料材质的视觉系统在环保回收、智慧垃圾分拣、循环经济园区这些场景下都有实际价值。这个项目把任务明确为输入一张图片、一段视频或者摄像头实时画面输出画面中每个塑料目标的类别标签和边界框坐标同时用可视化界面展示结果。用一个统一的系统来完成检测和展示闭环而不是只停留在跑通一个训练脚本的程度。从这个角度看系统的核心能力落在三个层面模型要认得准、推理要快、界面要能直接用。三个层面里任何一层瘸腿整体体验都会打折扣。1.2 为什么选YOLOv10而不是其他检测方案目标检测领域可选的方案不少老牌的两阶段代表Faster R-CNN精度高但速度是短板单阶段的SSD轻快但小目标和遮挡场景表现一般YOLO系列则一直走速度与精度平衡的路线。到了YOLOv10几个关键变化值得注意它设计了一个无NMS非极大值抑制的训练推理框架统一了标签分配策略双标签分配推理时不再需要额外的后处理步骤延迟更低、端到端特性更强。对塑料识别这个场景来说实时性非常关键。在传送带分拣或者摄像头扫视的场景里单帧处理时间往往决定了系统能不能落地。实测在同一张测试图上YOLOv10的推理延迟相比同尺寸的YOLOv8有一定幅度的下降同时mAP并没有明显牺牲。选择v10不是因为它是最新的所以无脑用而是因为这个场景确实需要低延迟、高吞吐端到端推理也能让部署代码更简洁。1.3 整体技术架构与目录结构系统的技术栈比较典型Python做主体PyTorch ultralytics做训练和推理PySide6做桌面界面OpenCV处理图像流。模型选用YOLOv10ssmall版本作为默认档位平衡了显存占用、速度和精度。项目目录一般按以下方式划分建议从一开始就规范好后面迭代会省很多事plastic_recognition/ ├── dataset/ # 标注后的数据集images/ labels/ ├── weights/ # 预训练权重和训练产出的最佳模型 ├── scripts/ # 训练、验证、转换脚本 ├── ui/ # 界面代码主窗口和各个检测子模块 ├── models/ # 网络配置或推理封装类 └── requirements.txt界面层和数据层分开模型推理封装成独立类这样后面换模型版本或者从图片检测扩展到视频流检测时不需要把界面代码重写一遍。2. 可回收塑料数据集构建全流程2.1 类别体系怎么定可回收塑料的材质分类行业里通常参考塑料制品底部的三角形回收标识编号也就是树脂编码体系。项目把数据集定位成七个类别PET聚酯常见矿泉水瓶、饮料瓶、HDPE高密度聚乙烯常见洗护用品瓶、药瓶、PVC聚氯乙烯常见管道、保鲜膜、LDPE低密度聚乙烯常见塑料袋、保鲜膜、PP聚丙烯常见食品容器、瓶盖、PS聚苯乙烯常见一次性餐盒、泡沫再加上一个Other用于兜底不确定的塑料制品。这里有一个经验不要一开始就追求十二三个细分类类别越多标注成本和训练难度越高而且材质相近的类别容易互相干扰。比如LDPE薄膜和PP薄片在图片里长得很像如果标注不仔细模型会学到错误特征。先用七个大类把流程跑通需要细分再逐步加类别项目节奏更可控。2.2 图片采集的实操建议训练数据质量直接决定模型的动手能力。采集阶段不需要昂贵设备手机拍摄即可但有几点直接影响效果的细节值得注意。多场景原则是第一位的。同一只矿泉水瓶要拍它在桌面、草地、传送带、纸箱、反光面等不同背景下的样子同时覆盖室内灯、晴天窗边光、逆光、阴天等光照变化。这样模型学到的才是“瓶子本身的特征”而不是“某个桌面的纹理”。其次要拍压扁、揉皱、堆叠、半遮挡、倾斜等不同状态因为回收场景里干净的完整瓶子反而是少数。再就是同一物品的不同品牌和颜色比如不同色号的洗护瓶——它们材质可能都是HDPE但外形设计差异很大样本多样性要够。拍摄后建议统一做人工筛图剔除模糊、无目标、过度重复的帧。宁可要质量高的一千张不要勉强凑数的一万张。2.3 标注格式与工具操作目标检测的数据标注格式里YOLO格式应该说是坑最少的一种。每张图片对应一个同名txt文件每行表示一个目标class_id x_center y_center width height和VOC的XML或者COCO的JSON不同YOLO格式的坐标是相对于图片宽高的归一化数值。举个例子一张640x640的图里一只瓶子的中心点在像素坐标(400, 300)宽200高400对应的归一化标注就是0 0.625 0.46875 0.3125 0.625计算公式很简单中心点x除以宽度、中心点y除以高度、目标宽除以图片宽、目标高除以图片高。为什么要归一化因为模型训练时输入图片会被resize到固定尺寸归一化坐标在resize过程中保持不变省去了大量坐标变换的麻烦。标注工具推荐LabelImg或者Label Studio。LabelImg老牌稳定单机标注足够Label Studio功能更多支持多人协作适合数据集比较大的情况。标注时有一条重要经验可回收塑料的外形边界常常不规则尤其塑料袋和薄膜标注框要尽量贴合最主要的目标物体不要把背景大面积框进框里否则模型训练时会学到多余背景信息。2.4 数据增强与划分策略数据集规模方面按我的经验七类塑料、每类300-500张干净标注图是一个出效果的最低门槛。总计2500-3500张左右配合增强手段足以支撑YOLOv10s训出一个应用级模型。如果部分类别比如PVC样本数少可以采用同类别过采样或者用增强手段额外生成样本。数据增强在ultralytics框架里开箱即用训练时默认会做随机翻转、缩放、色域变换等。针对塑料识别这个场景我觉得有两个增强特别值得加一是亮度对比度扰动因为塑料表面反光强烈光照变化对视觉特征影响大二是随机遮挡cutout模拟瓶瓶罐罐堆叠遮挡的场景。增强不是越多越好过强的增强会让模型学不到真实分布建议用预置增强配置训练一个baseline再逐步增强观察验证集指标变化。划分策略上train/val/test按8:1:1比较常见。test集务必保证来自不同的拍摄批次或场景不要和train集高度相似否则验证结果会虚高部署到真实场景会瞬间现原形。3. YOLOv10模型训练与核心参数解析3.1 环境准备与预训练模型选择训练环境的版本组合直接影响到能否顺利复现这里给出一套实测兼容性较好的组合组件推荐版本说明Python3.8 - 3.113.10和3.11都稳避免过新的3.12踩第三方包兼容坑PyTorch2.xCUDA版本根据显卡驱动对应的版本安装ultralytics8.x已内置YOLOv10模型定义OpenCV4.x负责图像读取和处理PySide66.x搭建界面权重选择上YOLOv10官方提供n/s/m/l/x五个尺寸档位。塑料识别不是超大规模类别任务ssmall是性价比最高的起点显存要求低、速度快。如果你的标注数据质量很高、样本量很大后续可以换m档进一步提高精度如果是部署到嵌入式设备n档也是可以接受的选择。使用预训练权重做迁移学习非常关键。完全随机初始化训练一个检测头在几千张图的小数据集上很难收敛好而从COCO预训练的权重出发模型已经具备通用的物体边缘、纹理、形状特征提取能力我们只需要微调它认识塑料材质类别收敛速度和最终精度都会明显更好。3.2 训练脚本与参数配置ultralytics框架把训练入口封装得很简洁核心训练脚本如下from ultralytics import YOLO model YOLO(yolov10s.pt) # 加载COCO预训练权重 model.train( data./dataset/data.yaml, epochs200, imgsz640, batch16, lr00.01, patience30, device0, # GPU索引CPU训练则设为cpu workers4, project./runs, nameplastic_exp )每个参数都有讲究。imgsz640是精度和速度的经典平衡点如果主要检测小目标可以提高到768或896代价是显存占用上升batch16在8G显存的卡上跑YOLOv10s是安全的如果显存不足可以降为8并适当提高训练轮数lr00.01是默认值通常不用动如果发现loss震荡明显可以降到0.005试试。data.yaml是训练入口内容和格式很重要# dataset/data.yaml path: ./dataset train: images/train val: images/val test: images/test nc: 7 names: [PET, HDPE, PVC, LDPE, PP, PS, Other]这里的path路径必须是真实的nc类别数和names列表顺序必须和标注时保持一致。特别提醒如果标注时把类别顺序搞乱了比如训练脚本里names顺序和生成txt时用的class_id顺序不一致模型会学一个错位的映射表面看loss在降实际推理结果全是乱的。3.3 训练过程监控与指标解读训练过程中ultralytics会输出每个epoch的loss、mAP、precision、recall等指标。对新手来说不要只看loss降没降重点盯三个东西第一个是mAP50代表IoU阈值为0.5时的平均精度反映了模型“大概框对、类别对”的能力这个指标在八九十以上才算可用。第二个是mAP50-95它跨多个IoU阈值计算更加严格能反映框的贴合度和定位精度塑料识别场景里如果这个指标太低框会明显偏大偏小影响分拣判断。第三个是precision和recall的平衡前者是查准率指检出的目标里真正正确的比例后者是查全率指真实目标被成功找出的比例。训练全过程里一个常见趋势是epoch前中期loss下降明显mAP快速上升到了后期mAP可能出现震荡这通常是学习率过大或者数据噪声导致的。这时候patience30的早停机制会发挥作用——连续30轮验证集指标没有提升就自动停止保存最优权重。建议训练完看runs/plastic_exp/weights/best.pt和last.ptbest是验证集表现最好的权重也是后面推理、部署要用的。3.4 训练踩坑与优化方向我实际训练这个项目时碰到过两个典型的坑。第一个是类别不平衡PET和HDPE瓶子样本充足PVC和PS样本偏少导致模型整体mAP不错但单独看PVC这一类的recall只有五十多。解决办法有二一是增加PVC样本的采集和标注二是在训练时给少数类提高损失权重。ultralytics中可以在data.yaml里为各类配置不同权重或者在数据加载层面过采样。第二个坑是薄膜类目标标注框太大、目标占比太小导致模型在遮挡情况下经常只检出半个目标。后来提高imgsz到768并增加了更多小目标的整图样本提升了这部分表现。还有一个方向值得尝试如果场景光照条件比较固定比如室内传送带可以采集一部分高质量的同场景图片微调模型这种迁移在真实部署中往往效果立竿见影。4. UI界面与检测推理的工程实现4.1 界面功能需求与模块设计模型训好之后系统的价值需要通过界面真正释放出来。界面功能我按实际使用流程来设计打开程序后可以选择图片检测、视频文件检测或摄像头实时检测三种模式。检测结果区域实时显示标注框和类别右侧信息栏显示当前目标数量、各类别置信度、单帧推理耗时底部提供“导出结果”按钮可以把标注后的图片或视频保存到本地。界面和推理逻辑务必分层否则后续扩展会非常痛苦。Detector类负责加载权重、执行前向推理、解析结果、提供检测数据MainWindow负责接收用户交互、展示画面、刷新统计信息。两者通过信号槽解耦界面线程永不阻塞检测结果通过信号传回界面线程刷新这是一套标准的PySide6开发模式。4.2 核心检测流程代码解析我先封装一个推理类把所有YOLOv10的调用逻辑集中起来# ui/detector.py from ultralytics import YOLO import numpy as np class Detector: def __init__(self, model_path./weights/yolov10s_plastic.pt, conf_thres0.35, iou_thres0.5): self.model YOLO(model_path) self.conf_thres conf_thres self.iou_thres iou_thres def predict_frame(self, frame): # 输入BGR帧输出标注后的帧和检测信息 results self.model.predict(frame, confself.conf_thres, iouself.iou_thres, verboseFalse) result results[0] annotated result.plot() # ultralytics自带画框函数 boxes result.boxes detections [] if boxes is not None: for box in boxes: cls_id int(box.cls[0].item()) conf float(box.conf[0].item()) xyxy [round(v, 2) for v in box.xyxy[0].tolist()] detections.append({ class: self.model.names[cls_id], confidence: round(conf, 3), bbox: xyxy }) return annotated, detections这里有两个细节值得说明。一是置信度阈值conf_thres的设定默认0.35是我做塑料识别时反复试出来的折中值——阈值太高会漏检反光导致的不清晰目标太低会出现大量误检框如果某个场景重遮挡可以单独调整。二是result.plot()可以直接把框和标签画到图上省去了手动调OpenCV画框的代码量但如果想自定义框的颜色和标签样式可以基于boxes.xyxy自己用cv2.rectangle绘制。界面里通过按钮触发图片检测的流程如下# ui/main_window.py 关键片段 def on_load_image(self): file_path, _ QFileDialog.getOpenFileName(self, 选择图片, , 图片文件 (*.jpg *.png)) if not file_path: return frame cv2.imread(file_path) annotated, detections self.detector.predict_frame(frame) self.display_result(annotated, detections) # 显示到QLabel上摄像头实时检测稍微复杂一点核心在于用QThread跑视频帧循环避免界面卡死。每读一帧就送入检测器检测结果更新画面但我强烈建议做帧率控制——不是每一帧都必须检测比如设定每两帧检测一次其余帧用最近一次检测结果展示实际体验会流畅非常多。4.3 界面布局与交互细节界面布局我选用左右结构左侧占主要宽度是检测画面显示区支持缩放适应窗口右侧是控制区和信息区。控制区放三个模式切换按钮图片检测/视频检测/摄像头检测、置信度滑块、打开文件按钮信息区放检测结果表格按行显示类别、置信度、坐标表格下方有汇总的“当前画面目标总数”和一个导出按钮。有一个交互细节容易被忽略摄像头检测模式下用户往往希望程序能截图保存当前检测结果。这个功能实现很简单——把当前帧的标注图用cv2.imwrite写一份配上时间戳文件名加一个按钮就行。别小看这个功能在样板展示和现场调试时非常常用。导出结果方面图片模式直接保存标注图视频模式则是把逐帧标注图合并写为一个新视频需要用cv2.VideoWriter注意保持帧率和分辨率一致否则导出的视频会出问题。5. 常见问题与排查技巧实录5.1 训练阶段典型问题速查现象可能原因排查思路loss不降或降得很慢学习率过大/过小、标注质量差观察训练前几十轮loss曲线超参回退默认值抽样检查标注框是否贴合mAP高但recall低类别不平衡、难样本未覆盖单独查看每个类别的recall针对性补充样本训练到一半显存溢出batch过大、图片尺寸过大降低batch、降imgsz或开启梯度累积验证集指标与测试集差异大数据划分泄漏、场景单一检查train/val是否来自同批次拍图重新划分场景独立的test集训练阶段最常见也是我最想强调的问题不要盲目堆epoch。很多人认为训练轮数越多模型越好实际上在YOLOv10这种预训练模型微调场景里150-200轮之后模型很可能过拟合训练集导致验证集mAP下滑。观察验证集loss曲线它如果开始反弹就应该停了。5.2 推理阶段常见问题速查现象可能原因排查思路检测框正确但类别错类别定义边界模糊、材质相似样本不足增加相似物对照样本检查标注class_id是否错位反光塑料漏检高光区域特征丢失、置信度过高降低conf_thres加入亮度扰动增强样本重叠目标框黏连NMS-free模型在密集场景有固有特点提高iou_thres或用m尺寸模型提升特征表达摄像头画面卡顿推理耗时大于帧间隔跳帧检测、减小输入分辨率、换GPU推理反光漏检是塑料识别场景里最典型的问题。塑料表面光滑在强光下会产生大片高光严重时瓶子整个区域都是白色反光特征完全丢失。我处理的方法是在训练集里专门加了一组“反光覆盖”样本拍摄时用台灯直射塑料表面制造高光同时在推理时给画面做一次轻微的Gamma调整压低高光区域的过曝。双管齐下漏检率能明显下降。5.3 环境与打包常见问题速查环境层面最常遇到的是CUDA版本和PyTorch版本不匹配导致GPU用不上。检查方法很直接跑python -c import torch; print(torch.cuda.is_available())如果输出False说明PyTorch的CUDA版本和驱动对不上按官方推荐的匹配版本重装即可。打包成独立可执行文件时PyInstaller是常见选择。需要注意两点一是ultralytics和PySide6体积大打包时用--exclude-module排除不需要的模块二是模型权重文件要作为数据文件随程序打包不然启动时会找不到模型路径。我打包时用的是pyinstaller --noconfirm --onefile --windowed \ --add-data weights/yolov10s_plastic.pt:weights \ --add-data dataset/data.yaml:dataset \ ui/main.py打包后的exe体积可能在150MB以上这是正常现象不要试图用各种压缩手段去硬砍体积框架和模型文件本身就占这么多。6. 部署扩展与二次开发方向6.1 模型轻量化与加速系统跑通之后如果想进一步提高性能或者部署到更低配置的设备有两个主要方向。一个是模型导出格式的转换。ultralytics可以一行代码导出ONNX格式然后可以通过ONNXRuntime进行推理比PyTorch原生推理快不少还能脱离PyTorch环境部署from ultralytics import YOLO model YOLO(./weights/yolov10s_plastic.pt) model.export(formatonnx, imgsz640)导出后可以用onnxruntime加载推理代码改动量不大但在CPU上的推理速度有明显提升。如果目标是边缘设备如树莓派、Jetson系列可以继续转成TensorRT或OpenVINO格式把模型的性能和兼容性进一步优化。另一个是模型尺寸的调整。如果发现s尺寸精度不满足要求直接换m或者l重新训练数据加载和训练代码完全不用改如果对速度极度敏感用n尺寸模型搭配ONNXRuntime实时性会更好。这套架构的可替换性是我当初选择ultralytics框架的重要原因——换模型档位只是改一行代码的事。6.2 业务逻辑扩展思路作为可回收塑料识别系统的基础版当前版本完成了“识别-检测-展示”的核心闭环。再进一步扩展时可以考虑的方向包括分类统计报表把每帧检测结果累计到Excel或数据库生成一段时间内的塑料类别占比报告流水线分拣对接把检测坐标输出给PLC或者机械臂控制模块实现自动分拣远程上报通过API把检测数据推送到云端管理平台适合园区级部署。我实际做扩展时最先加的是统计报表功能。原理很简单每次检测完累计一个字典按类别计数在程序关闭时用openpyxl写入Excel表再附带一个柱状图。这个功能对于客户演示和实际使用中的管理层报告价值很大而实现成本却很可控——只需要在Detector类里加一个累加方法在界面关闭事件里触发导出。6.3 代码组织规范建议项目文件多了以后代码规范比功能本身更要紧。我给几个亲测有效的建议第一检测类必须提供统一的输入输出结构不管输入是图片路径、numpy数组还是视频帧输出统一成(标注图, 检测列表)这样界面层永远不需要关心检测内部逻辑第二训练和推理的配置尽量用.yaml文件维护不要散落到各脚本的魔法变量里第三数据、权重这类大文件不进版本管理但requirements.txt和训练参数记录必须提交保证任何一个人拿到源码都能重跑实验。7. 一点经验体会整套系统从零搭到跑通我最有感触的一点是数据集的重要性远超想象。最初为了快速出效果我用网上找的混杂物图片训练了一个版本跑出来的指标还行但一放到真实摄像头面前就露馅——场景一换反光一变mAP跌得厉害。后来老老实实自己拍、自己标把各类别在真实摆放场景下的样本补足模型的稳定性才真正上了一个台阶。另外如果你是这个领域的新手我建议不要一开始就在界面设计上花太多时间。先把模型跑通用ultralytics自带的CLI建一个图片目录做测试确认检测效果基本满足要求再开始写界面。否则界面写了半天模型却因为数据问题迟迟没有进展很容易消磨信心。这个项目的扩展空间是相当大的。环保和回收行业目前对自动化识别有实打实的需求而在技术侧模型框架、数据管线、界面交互都已经沉淀成了可以复用的模板。把这套流程跑通一次后面换任何检测对象比如纸类、玻璃、金属的分类识别都只是换数据集和重新微调的事。希望这篇文章能帮你把这条路走顺。

读完文章,也想定制专属网站?

尧图设计师 24 小时内与您沟通定制方案

免费获取报价 →
↑