简介:本资源是一套基于YOLOv8的智能垃圾桶满溢检测完整项目,面向计算机、人工智能、自动化等专业的在校学生及初学者,解决实际场景中垃圾容量状态自动识别与预警问题,适用于毕业设计、课程设计、大作业及项目原型验证。压缩包共8个文件,含3个核心Python脚本(训练、推理、可视化界面)、3个模型权重文件(yolov8n.pt、best.pt等)及2个说明文档(README与项目说明),总大小15.91MB,结构清晰、模块解耦,开箱即用。已有40人学习下载,项目经实机测试验证,可一键运行并生成混淆矩阵、F1曲线、PR曲线、验证集预测图及标签分布统计等关键评估结果。配套部署教程详尽,支持快速本地部署与效果演示,代码注释充分,便于理解YOLOv8训练流程与工业级视觉检测落地逻辑,亦可作为二次开发基础框架拓展其他目标检测任务。 做毕设那段时间,我在一堆题目里挑中了“基于YOLOv8的智能垃圾桶满溢检测”。刚开始以为就是调用一个现成模型跑一下,结果从数据标注、模型训练、界面开发到部署打包,每一步都有不少坑。后来我把整套东西整理成了一个可直接运行的源码包,里面包含可视化界面、完整数据集和部署教程,解压后照着文档跑基本不会卡壳。今天把整套实现从头到尾拆一遍,给正在做相关毕设、课程设计,或者想自己搞一个智能检测小项目的朋友做个参考。
1. 项目拆解与方案选型
1.1 这个项目到底在解决什么问题
垃圾桶满溢检测的本质,是把“垃圾桶满了”这个人工巡检问题,变成摄像头自动识别的问题。城市里垃圾桶数量多、分布散,靠人工检查效率很低;校园、园区、社区里如果能装一个智能识别终端,在垃圾桶满溢时自动通知保洁人员,就能省下大量人力。这个方向非常适合做毕业设计或课程设计,因为它的业务逻辑很清晰,技术链路也完整:目标检测、实时视频流处理、界面展示、告警消息,每一块都能拿出来讲。
实际做的时候,你需要处理的不是“识别垃圾桶”这么简单,而是要判断垃圾桶的盛满状态。我最初只定义了两类:正常和满溢,做到后面发现不够用,因为垃圾桶从空到满是一个连续过程。最终我设了三个类别:empty(空)、half_full(半满)、overflow(满溢),实际使用体验好很多。你完全可以根据自己拍摄的数据情况调整类别,类别越细,数据标注工作量越大,但效果也更贴合真实场景。
1.2 为什么选择YOLOv8而不是传统方案或其他版本
我最早想用传统图像处理方案,比如边缘检测加填充率估计,但试下来发现太脆弱了。垃圾桶本身颜色、材质、灯光、拍摄角度一变,阈值就失效,根本没法泛化。后来换到深度学习目标检测,锁定YOLO系列。
选YOLOv8有几个很现实的原因。第一,它在精度和速度之间平衡得很好,我用一块GTX 1660 Ti显卡就能跑,训练速度能接受,推理也很快,不至于为了跑个课设去租高价服务器。第二,ultralytics这个框架把数据加载、训练、验证、导出封装得很完善,一个pip install就能用,非常省心。第三,它的模型结构相比YOLOv5做了不少调整,比如anchor-free检测头、C2f特征提取模块、解耦分类和回归头,这些改进让它在小目标检测上表现更好,而垃圾桶满溢检测里,小目标场景并不少。
这里顺便说一下为什么不用YOLOv5。YOLOv5本身也很成熟,资料多,但如果从零开始做新项目,YOLOv8的代码结构更清晰,导出ONNX、TensorRT、NCNN等格式都更顺手。项目时间有限的话,我建议直接用YOLOv8。
| 方案 | 精度 | 速度 | 开发成本 | 适合场景 |
|---|---|---|---|---|
| 传统图像处理 | 低,受光照环境干扰大 | 很快 | 中,需要大量调阈值 | 固定机位、环境稳定,不推荐 |
| YOLOv5 | 较高 | 快 | 低,资料多 | 常规目标检测,可用 |
| YOLOv8 | 高 | 快 | 很低,一站式 | 毕设课设、快速落地,推荐 |
1.3 整体架构与核心模块划分
整个项目可以拆成五块:数据准备、模型训练、模型推理、可视化界面、部署运行。数据准备负责采集和标注图片;模型训练负责生成可靠的权重文件;模型推理负责加载权重并对图片、视频、摄像头画面做实时检测;可视化界面负责把检测结果展示给用户,同时提供告警功能;部署运行负责把整套东西打包成可执行程序或导出到边缘设备。
我做完之后回看,这个项目最值得讲的地方不是某个算法有多深,而是完整工程链路的打通。很多教程只讲训练一个模型,却很少告诉你模型训完怎么接界面、界面怎么调摄像头、最后怎么打包给别人用。这篇博文会重点把后面这些环节补上。
2. 数据准备:训练集从哪来、怎么标、怎么分
2.1 数据集来源与采集建议
很多同学第一个问题就是:数据从哪里来。我当时用了两个途径,一是公开数据集,二是在校园里自己拍。公开数据集能帮你快速跑通流程,但直接拿别人的数据做毕设有个问题:画面里的垃圾桶和你在现实场景里见到的往往不一样,泛化效果没法保证。我建议优先自采数据,实在不够再用公开数据集补充。
自采数据需要注意几个点。角度上要覆盖平视、俯视和侧视,因为摄像头安装位置不会固定;光照上要区分白天、傍晚、晚上,如果有可能,室内和室外都拍一些;垃圾桶类型上也要尽量多样化,绿色大垃圾桶、灰色小垃圾桶、带盖和不带盖的都收集进去。我刚开始偷懒,只拍了教学楼门口的同一种垃圾桶,结果训练出来的模型一换场景就翻车,后来老老实实补了一批数据,效果才稳定。
数量方面,每个类别建议至少300张,想训得稳一点就500到1000张。如果你只有一两百张也不是不能训,但过拟合风险会很大,泛化能力基本靠运气。对毕设来说,三个类别总共1000张左右是一个比较合适的起步量。
2.2 标注工具与YOLO格式说明
数据采集完之后就是标注。我用的标注工具是LabelImg,轻量、支持YOLO格式导出,对新手非常友好。最近也有很多人用X-AnyLabeling,支持自动标注辅助,效率高一些,适合图片量大的情况。不管用哪个,核心是把标注结果保存成YOLO训练需要的txt格式。
YOLO格式的标注文件长这样:每一行代表一个目标,五个数值分别表示类别id、归一化后的中心点x坐标、中心点y坐标、目标框宽度、目标框高度。比如一行“0 0.5 0.5 0.3 0.4”,表示类别为0的目标位于图片中心附近,宽高分别占整张图的30%和40%。这里要特别提醒:坐标必须是归一化到0到1之间的小数,不是像素值,很多第一次做标注的同学就是在这里出错。
标注的时候还要注意边界框的紧贴程度。垃圾桶被遮挡时,尽量把可见部分的边界框标准确,不要把遮挡物标进去。像垃圾桶盖、旁边的小树枝这类干扰,能避开就避开。
2.3 数据集划分与增强策略
数据标注完成后,要按比例划分训练集、验证集和测试集。常见的比例是8:1:1或7:2:1。划分时要确保同一场景、同一时间拍的连续帧不要同时出现在训练集和验证集里,否则验证集指标会虚高,换到真实场景立刻露馅。
我建议按文件夹划分,先建好images和labels两个总目录,下面再分train、val、test。目录结构如下:
datasets/ ├── images/ │ ├── train/ │ ├── val/ │ └── test/ └── labels/ ├── train/ ├── val/ └── test/还要写一个data.yaml文件,内容大致是:
train: datasets/images/train val: datasets/images/val test: datasets/images/test nc: 3 names: ['empty', 'half_full', 'overflow']训练时不用手动做太多图像增强,YOLOv8内置了mosaic、随机翻转、HSV色域变换、平移缩放等增强策略,这些参数可以通过超参数文件调整。数据量少的时候,我会把mosaic开启,它能把四张图拼成一张,变相增加样本多样性,对防止过拟合很有帮助。
3. 训练与调优:让模型真正学会满溢检测
3.1 环境配置与依赖安装
训练环境是很多人卡住的第一关。我的建议是先用Anaconda创建一个独立环境,别直接装在系统Python里,不然后面依赖冲突会让人崩溃。
创建环境并安装依赖的命令如下:
conda create -n yolov8-trash python=3.9 conda activate yolov8-trash pip install ultralyticsultralytics会自动装好PyTorch、OpenCV等核心依赖。GPU用户额外注意PyTorch版本要与本地CUDA版本匹配。我的GTX 1660 Ti显存只有6GB,装的是CUDA 11.8对应的PyTorch 1.13,实测训练yolov8n和yolov8s都没问题。
没有GPU的同学也不用太慌。CPU也能跑,只是慢很多。yolov8n训练100个epoch可能要好几个小时,但依然能出结果。如果你想在CPU环境跑,建议把imgsz降到480,workers调低,训练时把模型换成yolov8n这种最小的,还勉强能接受。
3.2 训练命令与关键参数解析
训练命令不复杂,核心一行:
yolo detect train data=data.yaml model=yolov8n.pt epochs=100 imgsz=640 batch=16 device=0如果想在Python脚本里调用,写法是:
from ultralytics import YOLO model = YOLO("yolov8n.pt") model.train(data="data.yaml", epochs=100, imgsz=640, batch=16, device=0)我先解释几个实战中最重要的参数。
| 参数 | 推荐值 | 说明 |
|---|---|---|
| model | yolov8n.pt / yolov8s.pt | 模型大小,n最轻量,s精度稍高,显存小就选n |
| epochs | 100 | 训练轮数,数据少时用早停机制自动截断 |
| imgsz | 640 | 输入图片尺寸,越大精度越高但显存占用越大 |
| batch | 8-16 | 根据显存调,显存不足就减半 |
| patience | 20 | 验证集指标连续20轮不提升就早停 |
| device | 0 | 使用GPU训练,CPU就填cpu |
刚开始训练时,建议直接加载官方预训练权重yolov8n.pt做迁移学习,而不是从头训练。预训练权重已经在COCO数据集上学到了大量基础特征,你只需要微调后面的层来适应垃圾桶场景,这样收敛快、效果好,对数据量要求也低。
3.3 训练结果分析与常见训练问题
训练完,结果会保存在runs/detect/train目录下,里面有权重文件、曲线图和验证图片。我最先看的是results.png里的两张曲线:loss曲线和mAP曲线。训练集loss下降说明模型在拟合数据;验证集mAP50能到0.9以上,说明模型泛化不错。如果训练集loss一直降、验证集mAP却上不去,基本就是过拟合了,需要加数据增强、增加数据量,或者换更小的模型。
训练过程中最容易踩的坑是类别不平衡。比如满溢样本只占10%,模型会倾向于预测成占比最大的类别,导致满溢检测不出。解决办法是给每个类别补数据,或者调整损失函数里的类别权重。我一开始就吃过这个亏,后来专门补拍了一批满溢状态的垃圾桶,问题立刻缓解。
还有一个大家常问的问题:loss降到多少算正常。说实话没有统一标准,关键看验证集mAP和实际检测效果。我做这个项目时,训练集box_loss能降到0.8以下,mAP50稳定在0.92左右,实际界面测试已经够用了。
4. 可视化界面:从命令行到可操作工具
4.1 界面技术选型
模型训练好了,如果只停留在命令行运行,拿去答辩展示会很单薄。可视化界面是让项目“看起来完整”的关键。界面方案有几种:PyQt5、Tkinter、Streamlit、Gradio,我分别说一下。
Gradio和Streamlit适合快速做演示,代码量很少,几行就能出一个网页界面,但定制性和桌面感差一些。Tkinter是Python自带,不需要额外装,界面风格比较朴素。PyQt5功能强大、界面美观,可以做较复杂的交互,打包成exe也比较成熟。我做毕设时选了PyQt5,虽然代码量比Gradio大,但展示效果更好,老师印象分高。
从效率角度,我建议你如果时间紧张就先用Gradio,半小时出一个能用的界面;如果想做得正式一点,再上PyQt5。项目源码包里我默认提供的是PyQt5版本,同时留了一个Gradio简版入口。
4.2 检测主流程与告警逻辑实现
界面的核心逻辑很简单:用户选择图片来源(图片、视频、摄像头),程序把每一帧送入YOLOv8推理,绘制检测框和类别,最后根据检测结果触发告警。
核心推理代码大概这样:
import cv2 from ultralytics import YOLO model = YOLO("best.pt") def detect_frame(frame): results = model.predict(frame, conf=0.45, device=0) boxes = results[0].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]] label = model.names[cls_id] color = (0, 0, 255) if label == "overflow" else (0, 255, 0) cv2.rectangle(frame, (xyxy[0], xyxy[1]), (xyxy[2], xyxy[3]), color, 2) cv2.putText(frame, f"{label} {conf:.2f}", (xyxy[0], xyxy[1] - 10), cv2.FONT_HERSHEY_SIMPLEX, 0.8, color, 2) return frameconf阈值建议设在0.4到0.5之间。设太低会出现大量误检,设太高又会漏检。满溢状态是重点关心的,所以我把满溢类别的置信度阈值单独调低了一点,优先保证不漏报。
告警逻辑我用的是“连续N帧判定”策略,也就是只有连续5帧以上检测到overflow,才触发告警,避免瞬时误检造成的误报。触发后界面会弹窗提示,同时把当时的画面截图保存到record文件夹,并把检测记录写入CSV日志。这个细节在答辩时很加分,体现了工程思维。
4.3 界面性能优化
界面卡顿是最影响使用体验的问题。原因通常是一个线程同时干了推理和UI刷新两件事,摄像头帧率一高,界面就假死了。解决方法是把推理放到后台线程,主线程只负责刷新界面。具体实现可以用Python的QThread,把检测函数放进线程里,通过信号把处理完的画面传回界面显示。
摄像头输入同样有很多细节。OpenCV读取摄像头时,VideoCapture的index在0、1、2之间试,注意有些笔记本电脑自带摄像头和USB摄像头的index不一样。摄像头分辨率不必给太高,1280x720足够,分辨率越高推理越慢。
5. 部署运行:从源码包到稳定运行
5.1 源码包结构与启动流程
我提供的源码包目录结构如下:
smart-trash-can/ ├── datasets/ │ ├── images/ │ ├── labels/ │ └── data.yaml ├── weights/ │ └── best.pt ├── ui/ │ ├── main_window.py │ └── gradio_app.py ├── utils/ │ ├── detector.py │ └── alert.py ├── record/ ├── requirements.txt ├── train.py ├── detect.py └── README.md拿到源码包后,不要急着双击运行。第一步是创建环境并安装依赖,第二步用pip install -r requirements.txt装上所有包,第三步把权重文件放到weights目录,最后运行ui/main_window.py启动界面。如果一切正常,界面启动后就能选择摄像头开始实时检测。
5.2 模型导出与边缘设备部署
毕设演示用本地模型就够了,但如果想让项目更有深度,可以提一下边缘部署。ultralytics支持一键导出多种格式:
yolo export model=best.pt format=onnx dynamic=True导出ONNX后,可以继续转成TensorRT(NVIDIA设备)、NCNN(手机端)、OpenVINO(Intel设备)。我做这个项目时顺便把所有导出格式都试了一遍,实际推理速度和ONNX差不多,但如果要部署到嵌入式设备,TensorRT或NCNN是更实际的方案。
很多同学问手机安装包怎么做。思路是先导出NCNN格式,再用Android Studio写一个简单App加载模型,或者用ncnn-android-demo改。这个工作量不小,建议把它作为扩展内容放在PPT里讲,不要挤占核心毕设时间。以你手头的GTX 1660 Ti跑YOLOv8,使用yolov8n加半精度FP16推理,1080p视频流能稳定跑到30帧以上,这个性能表现已经足够支撑摄像头实时检测场景。
5.3 打包成exe的注意事项
如果你想打包成exe发给别人用,PyInstaller是主流选择。打包命令如下:
pip install pyinstaller pyinstaller -D -w ui/main_window.py --name SmartTrashCan这里有几个坑必须注意。第一,-D模式(目录模式)比--onefile(单文件模式)更稳定,启动速度也更快,虽然会生成一堆文件,但不容易出现运行时解压失败的问题。第二,要记得把权重文件best.pt和data.yaml复制到打包目录下,路径写错模型加载不出来。第三,PyQt5有时需要额外指定hidden-import,比如:
pyinstaller -D -w ui/main_window.py --hidden-import=ultralytics --hidden-import=cv2 --name SmartTrashCan打包出来的exe如果运行闪退,先回到命令行模式运行,看控制台报什么错,不要盲目加依赖。
6. 常见问题速查与避坑经验
6.1 高频报错及解决办法
我整理了一份真实项目中出现频率最高的问题清单,每一条都是我自己踩过的,或者帮同学排查时遇到的。
| 报错/现象 | 原因 | 解决办法 |
|---|---|---|
| ModuleNotFoundError: No module named 'ultralytics' | 依赖没装 | 用pip install ultralytics重装 |
| CUDA out of memory | 显存不足 | 调小batch(16变8),或调小imgsz(640变480),或者换yolov8n |
| labels not found | 标注路径或格式不对 | 检查datasets/labels目录是否存在,data.yaml路径是否写对 |
| 找不到best.pt | 权重路径不对 | 默认在runs/detect/train/weights/best.pt,复制到weights目录时勿改名 |
| 中文路径报错 | OpenCV和PyTorch对中文路径支持差 | 路径全部改成英文,文件夹不要有空格 |
| 界面卡死 | 推理和UI在同一个线程 | 用QThread把推理放到后台线程 |
| 摄像头打不开 | 摄像头索引不对或权限限制 | 换index 0/1/2,台式机确认USB摄像头被系统识别 |
| 模型检测不出满溢 | 数据不平衡或阈值过高 | 补充满溢数据,调整conf阈值,必要时重新标注 |
6.2 毕设答辩中的加分点与扩展思路
做完基础功能后,如果你想在答辩中拉开差距,有几个方向值得投入时间。一是加入垃圾分类识别,在检测满溢的同时识别垃圾桶里是否混入了不该丢的垃圾,这样课题能往“智慧环保”方向拔高。二是把满溢状态做成连续值而不仅仅是离散类别,也就是输出一个0到1的填充率,让判断更精细。三是把告警信息接入消息队列或云端,模拟真实物联网场景,让系统具备远程监控能力。
我实际项目里做的是第三种方向,将检测结果通过MQTT发送到本地服务器,再推送到手机端显示。这个改动大概多花了两天时间,但对项目整体完整度的提升非常明显,属于性价比很高的扩展。即使不做实际推送,在界面里预留一个“IoT上报”按钮,也能体现你对应用场景的考虑。
另一个容易忽略的点是视频检测的稳定性。摄像头画面经常抖,垃圾桶可能被树影遮住。你可以加一个简单的“检测结果平滑”逻辑,比如每5帧取一次众数作为最终状态,这样界面上的状态不会跳来跳去。这种细节,答辩老师一般都会关注。
最后分享一点个人经验
这个项目做完,我最大的体会是:先跑通再调优,比一开始就追求高性能有用得多。很多同学一上来就想用yolov8x加超大模型,结果数据没整理好,模型训了一通发现验证集指标上不去。我建议按“环境→数据→小模型→界面→优化”的顺序推进,每一步确认没问题再进下一步,这样出问题是可定位的,不会一错错到最后。
另外,数据集比模型结构更影响最终效果。我踩过最深的坑就是数据太少、标注不认真,导致模型看着训练准确率很高,一测真实场景就拉胯。后来把数据集补到上千张,重新标注了出错样本,效果立刻上了几个档次。如果你在跑这个项目的过程中遇到问题,欢迎留言交流,很多报错我一看就知道是哪里的问题。
本文还有配套的精品资源,点击获取