拓十年匠心定制 · 商业建站与技术教学双线并行 咨询热线:400-886-1026 service@lmnt.cn
ARTICLE DETAIL

资讯详情

深耕网站建设与运营推广的一线实战洞察。

基于YOLOv8的垃圾分类目标检测系统:从数据集到答辩全攻略

基于YOLOv8的垃圾分类目标检测系统:从数据集到答辩全攻略 简介面向计算机相关专业学生完成毕业设计、课程设计或期末大作业的深度学习实战项目基于YOLO等目标检测算法实现垃圾分类识别并配套答辩PPT、设计报告与参考文档。项目代码完整、可独立运行适合具备基础Python知识、希望快速搭建可演示系统的学习者。资源压缩包共126个文件大小约66.07MB主要包含Python源码、ipynb训练与演示脚本、Vue前端页面及JS交互逻辑另有ONNX模型文件、CSS样式、SQLite数据库、Dockerfile与YAML部署配置等覆盖从模型训练、后端服务到前端展示的完整闭环。当前已有199人参与学习下载。借助这份资料读者能拿到整套可直接运行的检测系统以及答辩PPT、三份Word报告/模板、实践大作业参考、PDF说明等文档便于对照源码理解目标检测思路、快速补齐项目文档并打磨答辩材料是冲刺高分毕设的实用参考。1. 从“能跑起来”到“能答辩”这套垃圾分类目标检测系统到底在做什么同一个宿舍楼里有人用三个月磨一个垃圾分类app有人一周就把检测系统跑通并拿去答辩拿了高分差别不在编程基础而在选了一条可复现、可解释、能扛住答辩追问的技术路线。这篇笔记要讲的就是一套基于深度学习的目标检测方案用YOLO系列模型对可回收、有害、厨余、其他四类垃圾做实时识别配套Python后端和可视化界面最终以“源码答辩PPT”的形式交付毕业设计。它不是论文复现也不是算法创新而是一个资源有限、时间有限的学生能在本地跑通并给自己加分的完整闭环。适合谁看选题是“目标检测”方向但还没定具体做法的本科生以及想用现有数据集快速做出一版毕设系统、把主要精力留给论文和答辩的人。全文按“数据→训练→系统→答辩”推进每一步都给可抄的命令和参数。2. 搞定数据集没有现成数据时把公开数据集改造成自己的训练集2.1 选数据集时的现实考量做垃圾分类目标检测最直接的路径是找一个现成的垃圾分类数据集比如华为云垃圾图片数据集、TrashNet这类公开资源。它们的好处是类别标注齐全、已经被很多人跑通用起来不容易翻车。但毕业设计有一个隐性要求答辩老师极大概率会问“数据集是怎么来的”。如果你直接说“网上下载的”第一轮追问就会落在数据来源合法性、类别定义依据这些点上。所以常见做法是以公开数据集为基础补充一部分自己拍摄的样本把“数据来源与构建”写成论文里独立的一章。另一个现实问题是Class Balance。垃圾分类四类的样本极其不均衡厨余垃圾里有剩菜剩饭这类标注难度大的图片有害垃圾样本总量少。训练前先做一次类别分布统计比直接开跑训练更省时间。2.2 数据集划分与目录结构标准化无论你最终用YOLOv5还是YOLOv8数据集目录结构都必须对齐模型训练脚本的预期。我的习惯是统一按下面的结构组织dataset/ ├── images/ │ ├── train/ │ ├── val/ │ └── test/ ├── labels/ │ ├── train/ │ ├── val/ │ └── test/ └── data.yamldata.yaml内容如下path: dataset/ train: images/train val: images/val test: images/test nc: 4 names: [recyclable, kitchen, hazardous, other]这里有个关键点path字段建议写成相对路径不要写绝对路径。因为答辩现场可能要换机器演示绝对路径会导致数据集找不到这个坑我在自己跑项目时踩过一次当场把模型路径改成相对路径才救回来。2.3 标注工具选择与标注格式转换如果你补充了自己拍摄的图片或者想把某个只有VOC格式标注的数据集转成YOLO格式我会选择LabelImg或X-AnyLabeling这类开源标注工具。前者老牌稳定后者支持自动标注辅助适合样本量大的场景。标注完成后VOC格式的XML转成YOLO格式的txt转换逻辑不复杂核心是把XML里的边界框坐标转换成归一化的中心点坐标和宽高import xml.etree.ElementTree as ET import os def convert_voc_to_yolo(xml_file, out_dir, class_names): tree ET.parse(xml_file) root tree.getroot() img_w int(root.find(size/width).text) img_h int(root.find(size/height).text) lines [] for obj in root.iter(object): cls obj.find(name).text if cls not in class_names: continue cls_id class_names.index(cls) box obj.find(bndbox) x_min float(box.find(xmin).text) y_min float(box.find(ymin).text) x_max float(box.find(xmax).text) y_max float(box.find(ymax).text) x_center (x_min x_max) / 2 / img_w y_center (y_min y_max) / 2 / img_h w (x_max - x_min) / img_w h (y_max - y_min) / img_h lines.append(f{cls_id} {x_center:.6f} {y_center:.6f} {w:.6f} {h:.6f}) if lines: base os.path.basename(xml_file).replace(.xml, .txt) with open(os.path.join(out_dir, base), w) as f: f.write(\n.join(lines)) class_names [recyclable, kitchen, hazardous, other] xml_dir VOC/Annotations out_dir dataset/labels/train os.makedirs(out_dir, exist_okTrue) for xml_file in os.listdir(xml_dir): if xml_file.endswith(.xml): convert_voc_to_yolo(os.path.join(xml_dir, xml_file), out_dir, class_names)这段脚本的逻辑是遍历XML文件提取每张图片的尺寸和每个目标的类别及坐标然后按YOLO格式写入txt。参数说明class_names的列表顺序决定了类别ID这个顺序必须和data.yaml里的names顺序一致否则训练出来的模型类别对应关系全乱。xml_dir和out_dir按你自己的目录结构调整。2.4 数据增强避免过拟合的常用组合YOLO模型在训练时会内置Mosaic、随机翻转、色彩空间变换等增强策略但这不代表数据准备阶段不能做预处理。对于垃圾分类场景光照变化和拍摄角度是影响精度的主要因素所以数据增强的重心放在亮度调整、旋转和透视变换上。我用的是albumentations库import albumentations as A train_transform A.Compose([ A.RandomBrightnessContrast(brightness_limit0.2, contrast_limit0.2, p0.8), A.HorizontalFlip(p0.5), A.Rotate(limit15, p0.5), A.RandomSizedBBoxSafeCrop(width640, height640, p0.5), ], bbox_paramsA.BboxParams(formatyolo)) # 使用时通过 pipeline 把增强后的结果写回训练集两点提醒一是RandomSizedBBoxSafeCrop必须显式指定bbox_params否则边界框不会随图片裁剪训练完的检测框全是偏的二是增强部分和模型训练时Mosaic增强不要叠加过猛否则厨余垃圾里的糊状物会被增强得面目全非。一般建议增强系数保持在0.3~0.5之间。3. 训练环节模型选型、参数设置与训练结果判断3.1 为什么用YOLOv8而不是Faster R-CNN或SSD做毕设系统模型选型有三个核心诉求精度够用、训练时间可接受、部署简单。Faster R-CNN两阶段检测精度上限更高但训练和推理速度慢在CPU机器上跑一个界面演示会卡到没法看。SSD速度可以但小目标检测能力弱垃圾图片里的小物体比较吃亏。YOLO系列在速度和精度的平衡上更合适YOLOv8对新手友好训练脚本封装完整ultralytics库一条命令就能启动训练对毕设来说是最稳妥的选择。如果追一句“为什么不用YOLOv5”主要考虑是版本维护和文档完整性。YOLOv8在导出模型、调整训练参数、推理调用上都更统一答辩时被问到也能讲得更清楚。3.2 最小可用训练命令与参数说明先安装依赖再拉训练命令。我在vscode里配Python环境时比较容易翻车的是虚拟环境混用这里把步骤写成可复现的python -m venv venv source venv/bin/activate pip install ultralytics然后开始训练yolo detect train \ datadataset/data.yaml \ modelyolov8n.pt \ epochs80 \ imgsz640 \ batch16 \ patience15 \ projectruns \ nametrash_detect参数说明modelyolov8n.pt表示用YOLOv8n作为预训练权重n是最小版本训练快适合毕设场景。如果你机器显存足够大于6GB可以换成yolov8s.pt精度会略高。patience15表示连续15个epoch验证集精度不提升就早停这能帮你把时间省下来。batch16要根据显存调整显存不够就降到8。训练过程中重点看的指标是mAP50和mAP50-95。mAP50是IoU阈值0.5下的平均精度垃圾分类这种场景mAP50能到0.85以上就算可用mAP50-95是更严格的综合指标不要期望太高。另外注意观察训练集和验证集的loss曲线差距训练集loss降但验证集loss横盘或反弹说明过拟合已经开始需要停止或加增强。3.3 训练后如何验证模型真的可用训练结束后直接跑验证命令yolo detect val \ modelruns/trash_detect/weights/best.pt \ datadataset/data.yaml跑完要看模型对每类垃圾的单独表现。我遇到过的情况是“可回收物”和“其他垃圾”两类混淆严重因为纸箱和塑料瓶在特定角度下外形接近。这时不要盲目调训练参数先检查是不是标注本身有模糊边界比如矿泉水瓶到底算可回收还是其他。验证通过后导出模型权重后续系统调用统一用best.pt这个文件不要用last.pt。4. 做成一个能演示的系统Flask后端与可视化界面4.1 系统的整体架构毕设答辩时评委要看的是“一个能用的系统”而不是一个裸模型。所以我会把系统拆成两个部分模型推理服务与前端交互界面。模型推理服务用Flask搭建一个轻量API接口接收前端传过来的图片返回识别结果前端界面负责图片选择、结果展示。4.2 Flask接口核心实现以下是Flask后端处理图片检测的完整代码import cv2 from flask import Flask, request, jsonify from ultralytics import YOLO app Flask(__name__) model YOLO(runs/trash_detect/weights/best.pt) app.route(/detect, methods[POST]) def detect(): if image not in request.files: return jsonify({error: no image uploaded}), 400 file request.files[image] img_bytes file.read() img_array np.frombuffer(img_bytes, dtypenp.uint8) img cv2.imdecode(img_array, cv2.IMREAD_COLOR) results model.predict(img, conf0.45, iou0.5) detections [] for r in results: for box in r.boxes: x1, y1, x2, y2 box.xyxy[0].cpu().numpy().astype(int) conf float(box.conf[0]) cls_id int(box.cls[0]) label model.names[cls_id] detections.append({ bbox: [x1, y1, x2, y2], confidence: round(conf, 2), class: label }) return jsonify({detections: detections}) if __name__ __main__: app.run(host0.0.0.0, port5000)这个接口的逻辑就是把上传的图片从字节流解码成OpenCV格式用yolo模型推理再把检测框、置信度和类别拼成JSON返回。参数说明conf0.45是置信度阈值低于这个值的检测框会被过滤掉。如果发现漏检严重可以降到0.35如果发现误检多可以调高到0.55。iou0.5是NMS的IoU阈值用来去除重叠框一般保持0.5即可。需要注意model.predict每次调用都会重新跑前向推理在CPU机器上单张图片可能要1~2秒加上前端展示延迟整体体验是能接受的。如果要提高流畅度可以把模型加载放到全局变量里上面的代码就是这个模式避免每次请求重复加载权重。4.3 前端展示页面与本地调试前端不用做得花哨一个HTML页面配合JavaScript就能完成演示。核心是选中本地图片、调用接口、展示结果!DOCTYPE html html head title垃圾分类检测系统/title /head body h3垃圾分类目标检测系统/h3 input typefile idimageInput acceptimage/* canvas idcanvas width640 height640/canvas script document.getElementById(imageInput).addEventListener(change, function(e) { const file e.target.files[0]; const formData new FormData(); formData.append(image, file); fetch(http://localhost:5000/detect, { method: POST, body: formData }) .then(res res.json()) .then(data { const canvas document.getElementById(canvas); const ctx canvas.getContext(2d); const img new Image(); img.onload function() { ctx.drawImage(img, 0, 0, 640, 640); data.detections.forEach(item { ctx.strokeStyle #ff0000; ctx.lineWidth 2; ctx.strokeRect(item.bbox[0], item.bbox[1], item.bbox[2] - item.bbox[0], item.bbox[3] - item.bbox[1]); ctx.fillStyle #ff0000; ctx.font 16px sans-serif; ctx.fillText(item.class item.confidence, item.bbox[0], item.bbox[1] - 5); }); }; img.src URL.createObjectURL(file); }); }); /script /body /html这个页面把检测框直接画在canvas上类名和置信度显示在框上方。本地调试时先启动Flask后端再用浏览器打开HTML文件注意canvas的绘制尺寸固定为640x640如果传入图片比例不是1:1显示会变形。这个问题虽然不影响检测结果但答辩演示时容易被评委指出来。更好的做法是把canvas宽高设为图片原始尺寸或者在画像前等比缩放。5. 答辩避坑五个高频翻车点与排查方案5.1 环境依赖没锁版本答辩现场跑不起来现象本机训练好模型答辩前换到教室电脑演示运行报错ModuleNotFoundError: No module named torch或ultralytics导入失败。原因面对这种场景最常见的原因就是没有做依赖冻结。你在自己电脑上可以用pip freeze把环境导出成requirements.txt直接打包带走。而且本机系统环境可能装过多个版本的库一旦换机器所有依赖都得重新装。解决项目根目录必须有一份完整的requirements.txt包括torch、torchvision、ultralytics、flask、opencv-python、numpy。最好到答辩前一周把项目迁移到一台干净虚拟机里从零按照requirements.txt安装一遍确保依赖能完整复现。5.2 数据集路径写死换机器后全部失效现象在A机器上训练时代码里写的data: C:/Users/xxx/dataset/data.yaml照搬到B机器后报错File not found。原因开发机与答辩机的目录结构不一样。数据集路径一旦用绝对路径整个项目的复用性就毁了。解决把data.yaml里的path改成相对路径前面2.2节已经演示过项目根目录作为相对路径的基准。后端和模型加载路径同理用os.path.join(os.path.dirname(__file__), ...)来定位权重文件。5.3 答辩演示用测试集图片被质疑“见过答案”现象演示时拿训练集或测试集里的图片跑检测效果极好评委随口问“用一张没有训练过的照片试试”现场翻车。原因这不算模型失效而是演示策略没打好。检测模型对这四类生活垃圾的泛化能力有限遇到真实桌面照片会有误检或漏检。解决答辩前专门留出10张“从网上下载评价不好找的实拍图、或自己用手机拍的不同角度照片”在答辩前测一遍记录每张图的识别情况。演示时主动说“下面用一张不在训练集里的实拍图测试”这是加分项因为它在展示模型的鲁棒性。5.4 置信度阈值调太低误检框把画面糊满现象界面显示大量错误的框一张图里有七八个检测框互相重叠整个演示效果没法看。原因模型对部分易混淆类别比如透明塑料瓶和玻璃瓶输出的置信度在0.3~0.5区间徘徊如果把conf降到0.25这些弱检测框全部涌出。解决尝试验证集上不同conf阈值下的表现把阈值设置在一个既保留正常检测又不溢出误检的值。实际操作中把conf设置为0.5左右配合NMS的iou参数能压掉大部分误检框。如果单靠调阈值压不干净等回到数据层面检查两类样本的数量差异。5.5 答辩PPT里“创新点”写成了“自创算法”现象答辩时评穷“你说创新点是改进YOLO的网络层结构具体改在哪一层”结果答不上来。原因把“用了深度学习目标检测技术”当成创新点或者把网上模型换了个名字当成自己的改进。这种回答在答辩现场会被追得很深。解决毕业设计原创性的正确写法是系统集成创新——比如“设计了一套针对校园场景的垃圾分类识别流程”“结合了数据增强与置信度融合策略”。在论文和PPT里写清楚技术选型对比、系统架构设计、数据集构建过程这些才是真实可控的完整部分。6. 进阶给加分视频流检测与模型量化如果你还有余力系统加一个视频流检测功能演示效果会明显提升。Flask后端用OpenCV读取本地摄像头或视频文件逐帧送入模型推理import cv2 from ultralytics import YOLO model YOLO(runs/trash_detect/weights/best.pt) cap cv2.VideoCapture(0) while cap.isOpened(): ret, frame cap.read() if not ret: break results model(frame, conf0.45) annotated results[0].plot() cv2.imshow(Trash Detection, annotated) if cv2.waitKey(1) 0xFF ord(q): break cap.release() cv2.destroyAllWindows()这段代码每帧都跑一次推理CPU机器上帧率只有个位数但答辩演示时“摄像头实时识别”这句话本身就是加分项。为了提升帧率可以先把模型导出为TensorRT或OpenVINO格式再做推理加速如果不想引入额外依赖简单方法是把输入帧分辨率降低到640x640后再推理。再提一个量化技巧把模型导出成FP16精度在不明显掉点的情况下减小内存占用换来的推理速度提升大概在10%~20%。用ultralytics库一行就能完成yolo export modelruns/trash_detect/weights/best.pt formatengine device0这个命令要求本机有GPU和TensorRT环境没有的话不要强上毕设系统用原始PyTorch权重已经足够。我个人的习惯是在答辩前把三个权重文件都准备好best.pt精度优先、best_quantized.pt速度优先、原始训练参数记录。这样演示时可以根据实际机器性能快速切换。把“换模型不换接口”做进系统设计里答辩时讲起来也有说服力。希望这套方案能帮你把毕设从“跑通”做到“讲得清、扛得住问”少走一段弯路。本文还有配套的精品资源点击获取
返回列表