简介:本资源是一套开箱即用的YOLOv5垃圾目标检测完整实践方案,面向计算机视觉初学者、AI项目开发者及环境监测类应用研究者,解决生活垃圾图像识别与快速部署难题。压缩包共2000个文件,含1858个标注用txt标签文件(对应COCO/YOLO格式)、61张实拍测试图像、34个核心Python脚本(含训练/推理/PyQt界面代码)、28个配置yaml文件(含数据集路径、类别定义、超参设置)以及xml标注备份、shell环境配置脚本和PDF技术说明文档,整体大小213.62MB。已有279人学习下载,资源提供map超90%的预训练权重、PR曲线与Loss收敛图等关键评估结果,并附带可直接运行的PyQt可视化检测界面,支持图片/视频实时推理与结果展示。所有代码基于PyTorch框架,兼容标准YOLOv5环境,无需额外模型训练即可完成端到端检测演示,大幅降低入门门槛与开发验证成本。
1. YOLOv5垃圾检测实战包:开箱即用的PyQt界面+标注数据集+90%+ mAP权重,3分钟跑通检测流程
你刚拿到一个标着“YOLOv5垃圾检测+PyQt界面+标注数据集”的压缩包,解压后看到labels.cache、一堆.jpg文件(比如2010_002226.jpg)、xml/和txt/两个标签文件夹,还有一堆.pt权重和ui_mainwindow.py——别急着双击运行。这不是“下载即用”的玩具模型,而是一套完整闭环的工业级轻量垃圾识别落地方案:它用真实城市环卫场景采集的图像训练,覆盖瓶子、罐子、烟头、餐盒、易拉罐、垃圾袋等6类高频暴露垃圾;mAP@0.5达92.3%,PR曲线平滑、loss收敛稳定;PyQt5界面非Demo级——支持实时摄像头推流、批量图册检测、结果导出Excel+带框图、阈值动态调节;最关键的是,它不依赖CUDA 11.8或torch 1.12这种玄学组合,在conda环境里仅需4条命令就能复现全部功能。适合一线算法工程师快速验证业务逻辑、城管/环卫单位做原型演示、高校课程设计直接交作业,也适合想练手YOLOv5全流程但被COCO格式绕晕的新手——它把VOC转YOLO、labelImg标注规范、train/val划分比例、PyQt信号槽绑定这些血泪经验全打包装进去了。
2. 模型与数据集结构解析:为什么这个包能直接跑通,而不是又一个“环境配三天”的坑
2.1 权重文件与评估指标:92.3% mAP背后的真实训练配置
项目提供的.pt文件(如best.pt、last.pt)是基于YOLOv5s-v6.0版本训练所得,不是魔改版也不是剪枝版。关键参数如下:
- 输入尺寸:
640×640(兼顾精度与推理速度,实测在GTX1060上达28FPS) - 训练轮数:
300 epochs(早停策略触发于val_loss连续15轮不降) - 优化器:
SGD(momentum=0.937, weight_decay=0.0005) - 学习率:
cosine annealing(初始lr=0.01,末尾lr=0.0001) - 数据增强:
Mosaic=1.0,MixUp=0.1,HSV H/S/V = 0.015/0.7/0.4(针对户外光照变化强的垃圾图像特调)
提示:
results.png中的PR曲线显示,烟头(small object)召回率在0.5 IoU下仍达86.1%,说明anchor匹配策略已针对小目标优化(kmeans++聚类得到新anchor:[10,13, 16,30, 33,23, 30,61, 62,45, 59,119, 116,90, 156,198, 373,326]),这点比直接套用默认anchor的模型强得多。
2.2 数据集双格式标注:txt(YOLO)与xml(PASCAL VOC)如何共存且互不干扰
数据集根目录结构清晰,避免常见混乱:
dataset/ ├── images/ # 所有.jpg原始图(共1247张) ├── labels_txt/ # YOLO格式:每张图对应同名.txt,每行"cls_id x_center y_center w h"(归一化) ├── annotations_xml/ # VOC格式:每张图对应同名.xml,含<filename><size><object><bndbox>完整结构 └── train_val_split.txt # 明确列出train:val = 998:249(8:2比例,非随机shuffle,按拍摄日期分组避免时序泄露)为什么同时提供两种格式?
labels_txt/直接喂给YOLOv5训练脚本(train.py),无需转换;annotations_xml/用于兼容LabelImg二次标注、或导入CVAT做半自动标注;train_val_split.txt是硬性保障——很多开源数据集只给train/val文件夹,但实际划分可能混入同一场景多帧,导致val指标虚高。这里明确按时间戳分组,val集全是独立拍摄日的图像,泛化性更可信。
2.3 PyQt界面工程结构:不是简单封装,而是生产级GUI交互逻辑
gui/目录下包含:
main.py:主入口,初始化QApplication并加载UIui_mainwindow.py:由Qt Designer生成的界面定义(按钮、视频控件、阈值滑块、结果表格)detector.py:核心检测模块,封装了cv2.VideoCapture、torch.hub.load()、NMS后处理、坐标映射到UI控件的逻辑utils/:含draw_bbox.py(抗锯齿绘制)、export_result.py(Excel导出含置信度+类别+坐标)
注意:PyQt5版本锁定为
5.15.6(因5.15.7+存在QVideoSink内存泄漏,该包已规避)。所有信号槽连接采用lambda方式而非partial,避免Python闭包引用导致的崩溃——这是我在树莓派部署时踩过的坑。
3. 环境配置与模型加载:4条命令完成从零到检测,拒绝“pip install失败”式翻车
3.1 Conda环境一键创建:绕过torch+cuda版本地狱
不要用pip install -r requirements.txt!该项目已预编译适配主流显卡驱动。执行以下命令(Windows/Linux通用):
# 创建干净环境(Python 3.8.10是YOLOv5官方推荐版本) conda create -n garbage_det python=3.8.10 conda activate garbage_det # 安装PyTorch(CUDA 11.3,适配GTX10/16/20/30系显卡) conda install pytorch==1.10.2 torchvision==0.11.3 torchaudio==0.10.2 cudatoolkit=11.3 -c pytorch # 安装YOLOv5依赖(注意:必须指定v6.0分支,v8.x不兼容) pip install -U https://github.com/ultralytics/yolov5/archive/refs/tags/v6.0.zip # 安装PyQt5及配套工具 pip install pyqt5==5.15.6 pyqt5-tools==5.15.4.2.2 opencv-python==4.7.0.72 pandas==1.5.3逻辑说明:
v6.0.zip直接安装源码而非pip install yolov5,确保models/common.py中Detect层与权重文件结构完全匹配;opencv-python==4.7.0.72是最后一个支持cv2.dnn.readNetFromONNX无报错的版本,后续版本对YOLOv5导出的ONNX有兼容问题。
3.2 加载预训练权重并验证:3行代码确认模型可用
在detect.py同级目录下新建test_load.py:
import torch from models.experimental import attempt_load # 加载权重(路径需替换为你的实际路径) model = attempt_load('weights/best.pt', map_location='cuda:0') # 或'cpu' model.eval() # 验证输入输出形状 img = torch.zeros((1, 3, 640, 640), device='cuda:0') # 模拟单张图 pred = model(img) print(f"Output shape: {pred[0].shape}") # 应输出 torch.Size([1, 25200, 6])参数说明:
map_location='cuda:0'强制指定GPU设备,避免CUDA out of memory错误(若显存不足,改为'cpu');pred[0].shape中25200是YOLOv5s的anchor数量(3 scales × 8400 anchors/scale),6代表[x,y,w,h,obj_conf,cls_conf];- 若报错
AttributeError: 'NoneType' object has no attribute 'shape',说明权重路径错误或.pt文件损坏——此时应校验MD5(包内附weights.md5)。
3.3 运行PyQt界面:启动即检测,无需修改任何路径
确保当前目录为项目根目录(含gui/、weights/、dataset/),执行:
cd gui python main.py界面启动后:
- 点击【打开图片】→ 选择
dataset/images/2010_002226.jpg→ 自动检测并显示带框图; - 点击【打开视频】→ 选择任意MP4 → 实时检测(FPS显示在右下角);
- 拖动【置信度阈值】滑块至0.3 → 烟头检出数量增加,但误检增多(验证阈值敏感性);
- 点击【导出结果】→ 生成
result_2010_002226.xlsx,含每框的类别、置信度、左上/右下坐标。
关键细节:
main.py中self.detector = Detector(weights='../weights/best.pt')使用相对路径../,因此必须在gui/目录下运行,否则路径报错。这是新手最常犯的错误——不是代码问题,是启动位置错了。
4. 常见问题排查:这6个现象我全遇到过,原因和解法写进注释里
4.1 现象:PyQt界面启动后黑屏/无响应,控制台无报错
原因:Qt平台插件缺失(尤其Windows系统缺少qwindows.dll)或OpenCV视频后端冲突。
解决:
- Windows用户:在
main.py顶部添加
(路径需替换为你的conda环境实际路径,用import os os.environ['QT_QPA_PLATFORM_PLUGIN_PATH'] = r'C:\Users\XXX\anaconda3\envs\garbage_det\Lib\site-packages\PyQt5\Qt5\plugins\platforms'conda list pyqt5查安装位置) - Linux用户:执行
export QT_QPA_PLATFORM=offscreen再运行,或安装libxcb-xinerama0库。
4.2 现象:检测结果框错位(框在图外/偏移严重)
原因:图像原始分辨率与模型输入尺寸(640×640)缩放比例未对齐,且detector.py中resize_and_pad函数未启用letterbox。
解决:打开gui/detector.py,找到def preprocess(self, img)函数,将原生cv2.resize替换为:
def letterbox(img, new_shape=(640, 640), color=(114, 114, 114)): shape = img.shape[:2] # [height, width] if isinstance(new_shape, int): new_shape = (new_shape, new_shape) r = min(new_shape[0] / shape[0], new_shape[1] / shape[1]) new_unpad = int(round(shape[1] * r)), int(round(shape[0] * r)) dw, dh = new_shape[1] - new_unpad[0], new_shape[0] - new_unpad[1] dw /= 2 dh /= 2 if shape[::-1] != new_unpad: img = cv2.resize(img, new_unpad, interpolation=cv2.INTER_LINEAR) top, bottom = int(round(dh - 0.1)), int(round(dh + 0.1)) left, right = int(round(dw - 0.1)), int(round(dw + 0.1)) img = cv2.copyMakeBorder(img, top, bottom, left, right, cv2.BORDER_CONSTANT, value=color) return img, r, (dw, dh) # 在preprocess中调用 img_resized, ratio, (dw, dh) = letterbox(img, (640, 640))然后在postprocess中用ratio和(dw, dh)反向映射坐标。
4.3 现象:训练时loss不下降,val mAP始终<10%
原因:数据集路径配置错误,YOLOv5默认读取data/coco.yaml,但本项目使用自定义data/garbage.yaml,且train:字段指向了错误路径。
解决:检查data/garbage.yaml内容:
train: ../dataset/images # 必须是相对路径,且与yaml文件位置一致 val: ../dataset/images nc: 6 names: ['bottle', 'can', 'cigarette', 'food_box', 'cola_can', 'garbage_bag']若garbage.yaml放在yolov5/目录下,则../dataset/images正确;若放在项目根目录,需改为./dataset/images。
4.4 现象:导出Excel时报错PermissionError: [Errno 13] Permission denied
原因:Windows系统下Excel文件被其他程序(如Excel软件)占用,或路径含中文/空格。
解决:
- 关闭所有Excel进程;
- 修改
gui/utils/export_result.py中导出路径:# 将原路径 save_path = f"result_{os.path.basename(img_path).split('.')[0]}.xlsx" # 改为绝对路径且不含空格 save_path = os.path.join(os.getcwd(), "output", f"result_{int(time.time())}.xlsx") os.makedirs("output", exist_ok=True)
4.5 现象:PyQt界面点击【打开摄像头】后报错cv2.VideoCapture(0) returned False
原因:OpenCV未正确链接摄像头驱动(尤其USB摄像头需额外权限)。
解决:
- Linux:执行
sudo usermod -a -G video $USER,重启终端; - Windows:以管理员身份运行
cmd,再启动python main.py; - 通用:在
detector.py中添加设备探测:for i in range(10): cap = cv2.VideoCapture(i) if cap.isOpened(): print(f"Camera found at index {i}") break cap.release()
5. 微调自己的垃圾数据集:从YOLOv5权重迁移学习,3步搞定新类别适配
5.1 数据准备:严格遵循本包的标注规范,否则训练必崩
你新增了“塑料袋”、“废纸团”两类,必须按以下规则整理:
- 图像:放入
my_dataset/images/,命名用IMG_0001.jpg格式(禁止中文、空格、特殊字符); - 标签:用LabelImg标注,保存为YOLO格式(.txt),且类别ID必须续接原6类之后(即
plastic_bag=6,waste_paper=7); my_dataset/labels/中每个.txt文件行数必须等于图像中目标数,空图也要建空.txt;- 划分:用本包提供的
split_dataset.py(位于tools/目录),它会按train:val:test=7:2:1比例分组,并保证同一拍摄地点的图不跨集。
血泪经验:曾因手动复制粘贴标签导致
.txt末尾多了一个空行,YOLOv5训练时IndexError: index 7 is out of bounds for axis 0 with size 7——因为类别数设为7,但空行被解析为第8类。现在我每次生成标签后都用sed -i '/^$/d' *.txt清理空行。
5.2 修改配置文件:两处关键改动决定微调成败
编辑data/my_garbage.yaml:
train: ../my_dataset/images/train val: ../my_dataset/images/val test: ../my_dataset/images/test # 可选,用于最终评估 nc: 8 # 必须更新!原6类+新增2类 names: ['bottle', 'can', 'cigarette', 'food_box', 'cola_can', 'garbage_bag', 'plastic_bag', 'waste_paper']重点:nc: 8必须与names列表长度严格一致,且names顺序必须与.txt中类别ID一一对应(ID=0→bottle,ID=7→waste_paper)。
5.3 启动迁移训练:冻结Backbone,只训Head层
在yolov5/目录下执行(假设权重路径为../weights/best.pt):
python train.py \ --data ../data/my_garbage.yaml \ --weights ../weights/best.pt \ --cfg models/yolov5s.yaml \ --epochs 100 \ --batch-size 16 \ --name garbage_finetune \ --freeze 10 # 冻结前10层(Backbone),只训Neck和Head参数说明:
--freeze 10:YOLOv5s共有25层,冻结前10层(CSPDarknet部分)可防止小数据集过拟合;--batch-size 16:若显存不足,按比例缩小(如GTX1060用8);--name garbage_finetune:生成runs/train/garbage_finetune/目录,含weights/best.pt和results.png;- 训练100轮后,
val/mAP@0.5应从初始的0%升至75%+(因迁移学习起点高)。
5.4 验证微调效果:用PyQt加载新权重,对比原权重
将runs/train/garbage_finetune/weights/best.pt复制到weights/目录,重命名为best_finetune.pt。修改gui/detector.py中权重路径:
self.model = attempt_load('weights/best_finetune.pt', map_location=self.device)重启PyQt,用新增的plastic_bag.jpg测试——此时应检出“塑料袋”类别,且原6类准确率无明显下降。若新类别漏检严重,说明--freeze层数过多,尝试--freeze 5重新训练。
从那以后我每次微调新数据集,都强制走一遍三步验证:① 用
labelImg检查标签ID是否越界;② 用python utils/general.py --check-dataset data/my_garbage.yaml校验路径和类别数;③ 用test.py单图推理看log输出是否含新类别置信度。少走一步,后面debug三天。希望帮到你。
本文还有配套的精品资源,点击获取