☰
路面垃圾识别数据集构建实战:小目标检测与YOLOv8训练全解析
2026/11/3 11:32:22 网站建设 项目流程

简介:面向目标检测与深度学习实践的路面垃圾识别数据集,采用YOLO与VOC格式规范标注,覆盖塑料瓶、口罩、纸袋、易拉罐、玻璃瓶等17类常见路面垃圾,图片样本共7537张。压缩包内共2000个文件,以txt标签文件为主(1999个),另含1个指定类别信息的yaml配置文件,整体约527MB。所有标注已按训练集、验证集和测试集划分,可直接用于YOLO系列、Faster Rcnn、SSD等模型训练,省去自行整理与格式转换的步骤。对于开展垃圾分类检测、智能环卫等项目的开发者,这份数据能帮助快速搭建并验证目标检测模型,目前已有824人学习使用。

1. 项目概述

1.1 核心需求解析

路面垃圾识别,光听名字好像就是“找个模型,训练一下,识别垃圾”这么简单。但真正做过落地方案的人都知道,这个任务在水面之下藏着一大堆麻烦:垃圾目标的尺寸普遍偏小、形态极度不规则、不同材质之间的外观差异巨大,再加上户外光照变化剧烈、天气影响、道路背景纹理复杂,任何一个环节没处理好,模型性能都会大打折扣。

我最早接触这个方向,是在做一个智慧环卫的试点项目。当时甲方提的需求很简单——“用摄像头自动发现路面的白色垃圾、烟头、纸屑,能告警就行”。等到真正动手才发现,市面上的公开数据集几乎没有专门针对中国城市道路场景的,要么是国外的路面破损检测,要么是笼统的物体检测数据集,直接拿过来迁移效果很差。最后只能自己从数据采集、清洗、标注到训练、调优、部署,完整走了一遍流程。这篇博文,就是把那段时间踩过的坑、验证过有效的方案,以及整个数据集的构建思路,原原本本整理出来。

这套路面垃圾识别数据集,定位就是服务目标检测任务。图像主要来自市政清扫车的前置摄像头、路侧监控杆位以及少量手持设备拍摄的街景,覆盖了城市主次干道、人行道、辅路、学校周边、商业街区等常见场景。目标类别开口不大,但都是实际清扫作业里高频出现的垃圾物——塑料瓶、易拉罐、纸团、烟盒、塑料袋、果皮、树叶堆、碎砖石等。别小看这个类别设计,很多新手做数据集时恨不得塞进去二三十类,结果每类样本量稀薄,模型根本学不出有区分力的特征,最后只能返工。

这个数据集能解决什么?解决的是“有数据才能做检测”的冷启动问题。它既能用来从零训练一个专用的路面垃圾检测模型,也可以作为预训练素材,帮助你快速验证算法选型和评估现场环境的可识别率。适合谁参考?做智慧城市、智慧环卫、自动驾驶道路感知、无人机巡检的朋友都很合适。哪怕你不做路面垃圾,里面关于小目标检测、复杂背景下的特征提取、数据增强的策略,换到其他户外视觉任务也直接能用。

2. 内容整体设计与思路拆解

2.1 为什么路面垃圾检测比想象中难

先说个结论:路面垃圾检测的难点,七成不在模型,而在数据和数据背后的场景理解。

真正做过这个方向的人会有共鸣——路面垃圾是一个典型的“小目标+大背景”任务。一张1920x1080的图中,一个烟盒可能只占几十个像素,一团纸屑甚至只有十几个像素。目标的尺寸跨度极大,从占据画面四分之一的大垃圾袋,到仅指甲盖大小的烟头,都在同一个类别体系里。这种情况下,模型很容易出现“大的能识别,小的全漏掉”的尴尬局面。再加上道路场景的强背景干扰,比如树影、井盖、路面裂缝、口香糖污渍,这些纹理信息和部分垃圾的外观接近,直接拉高了误检率。

我在项目初期用过几套公开的COCO预训练权重做直接推理,效果惨不忍睹。COCO里虽然有bottle、cup这些类别,但它的训练分布是“物体居中、背景干净”的典型构图,而路面垃圾的场景里,垃圾往往在画面边缘、被遮挡、形变严重。这让我确认了一件事:不能指望预训练模型直接迁移,必须自己构建贴合场景的数据集,并且针对小目标特性去设计标注策略和数据增强方案。

2.2 类别体系设计的取舍逻辑

类别怎么定,直接决定模型的上限。我跟环卫专家反复沟通过,一线的清扫标准里,垃圾是按“可回收”“不可回收”“有害”来分的,但那是给垃圾桶用的,不适合视觉检测。视觉检测关注的是“看见”和“定位”,分类太细,标注成本成倍上涨,而且很多细类之间外观差异极小,模型学不出区分性。

我最终把类别收敛到了8类:

类别名称主要外观特征典型尺寸范围
plastic_bottle透明或有色塑料瓶,反光明显中目标
can金属易拉罐,圆柱形,高反光中目标
paper_cup纸杯、纸碗,常带印刷图案中目标
plastic_bag塑料袋,半透明,形态多皱褶中到大目标
cigarette_box烟盒,方正,色彩鲜亮小目标
fruit_peel果皮、菜叶等有机垃圾,颜色杂乱小到中目标
leaf_pile落叶堆积,成片出现中到大目标
debris碎砖石、建筑废料小到中目标

为什么这么设计?核心原则是“类间可区分、类内可容忍”。比如烟盒和纸杯虽然都有印刷图案,但烟盒的方正轮廓和相对较小的尺寸是显著的区分特征。碎砖石和混凝土块则归为debris一类,因为它们在作业场景里通常一起出现,没必要拆成两个类。类别越少,模型越容易学到本质的视觉特征。这也是我给所有做自定义数据集的朋友的第一条建议:贪多必失,先保证每类样本量充足,再考虑扩类。

2.3 技术选型:为什么用YOLO系

模型选型上,我最终落在了YOLOv8上,这里说下考量过程。路面垃圾识别是一个典型的边缘端实时检测需求——摄像头采集画面后,需要在极短的时间内完成检测并触发告警或让清扫车执行动作,所以推理速度是第一优先级。Transformer类检测器(比如DETR、DINO)精度确实在多个benchmark上领先,但端侧部署的延迟和显存占用是硬伤,不适合我们这种需要低成本的场景。

YOLOv8作为目前生态最成熟的单阶段检测器,在n/s/m/l/x五个尺度上都有对应模型,我自己实测下来,YOLOv8s在1080p图像上的单卡推理速度在10~15ms左右,完全够用。更关键的是,Ultralytics的开源工程做得很完整,数据加载、增强策略、训练日志、模型导出全流程都是打通了的,适合快速迭代。当然,YOLOv8不是唯一的选择,如果你后续要更极致的性能,尝试YOLOv5的p6模型或者RT-DETR都是可以的。但对大多数项目来说,用YOLOv8起步,把数据和调参吃透,性价比最高。

3. 数据集构建与标注实操

3.1 数据采集方案的实地经验

数据是数据集的根。我实际采集了大约12000张图像,筛选后保留了8600张左右进入标注流程,这部分工作耗时将近两周。采集渠道主要有三条:

  • 清扫车前置摄像头:这是主力来源。清扫车在城市道路上的作业路线基本覆盖了主次干道,摄像头高度约0.8米,视角略微向下,垃圾在画面中占比较大,适合中大型垃圾的检测。这里有个细节要注意:摄像头安装高度不能太高,否则垃圾目标会缩得极小,但也不能太低导致近处大目标超出画面。经验值是在0.6~1.2米之间,具体根据车辆前保险杠的造型调整。
  • 路侧监控杆位:这类摄像头通常架设在3~5米的杆上,俯瞰角度拍摄,画面中垃圾目标像素占比非常小,真实感强,但标注难度大,漏标率高。这部分我只保留了画面中垃圾较清晰的图像,确保标注质量和模型学习效果。
  • 手持设备补充拍摄:针对前两类覆盖不足的场景,比如人行道、绿化带边缘、学校门口,由专人用手机拍摄补充。注意拍摄时保持顺光,避免过度HDR处理导致标注和训练时的色彩失准。

采集时还必须考虑时间和天气的多样性。同一段路,早上逆光和中午顶光下的成像差异很大,雨天和晴天的对比度也完全不同。我采集时故意在早、中、晚三个时段和晴、阴两种天气下分别采集,但刻意剔除了明显的雨天图像——因为雨水反光会让标注特征变得极不稳定,模型在这个阶段去学反而适得其反。等基础模型性能稳定后,再考虑通过域适应或者扩充数据来覆盖雨天场景。

3.2 标注规范与质量控制的血泪教训

标注环节是整个数据集构建里最容易被低估的部分。一个不严谨的标注,直接导致模型学习到错误信息,而且这种错误是结构性的,后期再调参也很难弥补。

我用的标注工具是LabelImg和X-AnyLabeling。前者轻量灵活,适合纯矩形框标注;后者效率高一些,但是要注意它自带的模型辅助标注功能,在生成预标注框后一定要人工复核,否则框的位置可能会存在偏移。

标注规范里,我最想强调的几个点:

  • 遮挡处理:垃圾被树叶部分遮挡、或露出一半时,只标注可见的完整主体区域。如果遮挡超过50%或者只有极小部分可见,直接不标。
  • 紧密相邻的同类目标:比如一堆落叶里混着几个纸团,就要严格给每个纸团单独画框,不能图省事把整堆落叶框成一个矩形。如果一个矩形框同时包含了两个相同类别的目标且难以分割,允许用一个大框框住整体,但这种情况要控制在总数的5%以内。
  • 边界目标:只露出目标的1/4甚至更少,不标注。这个看起来很保守,但我实测下来,这种edge case放进训练集,很容易让模型在推理时产生大量误检。
  • 画面模糊的图片直接丢弃,不用犹豫。

每批标注完成后,我会做两轮复核。第一轮是交叉检查,标注者互相审查对方的框是否贴边;第二轮是抽检,我随机抽10%的图像,用显示标注框的脚本跑一遍,人工确认类别和位置。这一套流程下来,平均一张图要花费大概1分半钟标完,贵是贵了点,但最后模型收敛的指标让我觉得这笔投入是值的。

3.3 目录结构与YAML配置

数据准备好后,目录结构的规范程度直接决定后续训练的顺利程度。我最终采用的目录结构是:

roadsurface_garbage/ ├── images/ │ ├── train/ # 6800张 │ ├── val/ # 1200张 │ └── test/ # 600张 ├── labels/ │ ├── train/ # 6800个对应txt │ ├── val/ # 1200个对应txt │ └── test/ # 600个对应txt ├── data.yaml └── README.md

每个txt文件的内容是标准的YOLO格式,每行代表一个目标:

class_id x_center y_center width height

其中x_center、y_center、width、height全部是归一化到0~1的浮点数。举个例子,一个标注框的像素坐标是(360, 480, 720, 960),图片尺寸是1080x1920,那么对应的内容是:

2 0.3333 0.25 0.3333 0.5

这里class_id是paper_cup在当前类别表中的索引。归一化坐标是我推荐的保存方式,它不依赖具体图片尺寸,后续换分辨率做训练也不会出坐标错位的问题。

data.yaml配置很简单,指向对应的目录和类别名。下面是我用的配置,可以直接复制改:

train: roadsurface_garbage/images/train val: roadsurface_garbage/images/val test: roadsurface_garbage/images/test nc: 8 names: ['plastic_bottle', 'can', 'paper_cup', 'plastic_bag', 'cigarette_box', 'fruit_peel', 'leaf_pile', 'debris']

这里要注意路径推荐使用绝对路径,尤其是跨机器操作时。我在本地用相对路径没问题,但换到服务器上训练时,因为目录结构不同,整整浪费了一天时间排查路径问题。

3.4 数据增强:让小目标不再“隐身”

路面垃圾识别的数据增强策略,跟普通目标检测有明显区别。通用数据集里常用的水平翻转和随机裁剪当然要用,但对小目标来说,最重要的增强手段是Mosaic和Copy-Paste增强,而这里面有讲究。

Mosaic增强在YOLOv8里默认开启,它会将4张图拼接成一张新图,这不仅能提高背景多样性,还能让模型在一个batch内看到更多的小目标信息。我自己在训练时,把Mosaic增强的开关保留为开启,epochs前70%使用,后30%关闭。为什么这样设置?因为Mosaic生成的图像跟真实场景的图像分布有偏差,训练的后期关闭它,可以让模型回归到真实数据分布上,最终测试指标会有1~2个mAP点的提升。这个细节在Ultralytics的官方文档里没有明确说明,是我反复对比实验验证出来的。

另外针对小目标,我额外增加了随机旋转和轻微透视变换。路面垃圾多位于地面,摄像头视角近似俯视,所以旋转角度控制在±15度以内,透视变换的幅度控制在0.1以内,幅度过大会导致目标形变失真,模型学到的是畸变特征,反而有害。

还有一个容易被忽略的点:色彩抖动。路面场景的色调会受到路面材质影响,沥青路面偏灰蓝,砖石路面偏红棕,如果不做色彩扰动,模型可能过拟合到特定路面的色偏上。我在训练时加入了HSV空间的色相、饱和度、明度扰动,参数分别为0.02、0.4、0.4,实测下来对泛化性的提升很明显。

4. 模型训练与核心环节实现

4.1 训练流程与参数配置

训练部分,我用的YOLOv8s模型,在单张NVIDIA RTX 3090上跑。因为数据集规模不大,整个训练过程大约6个小时完成300个epoch。

关键的训练参数配置:

from ultralytics import YOLO model = YOLO('yolov8s.pt') results = model.train( data='roadsurface_garbage/data.yaml', epochs=300, imgsz=640, batch=16, optimizer='AdamW', lr0=0.001, lrf=0.01, momentum=0.937, weight_decay=0.0005, warmup_epochs=3, cos_lr=True, patience=30, seed=42, workers=8, device=0 )

几个参数的选择逻辑:

  • imgsz=640是YOLOv8的默认值,很多人觉得放大到1280会让小目标更好检测,实测确实有效果,但推理速度会大幅下降,显存占用也会成倍增加。我的建议是先用640跑通流程,如果小目标(烟盒、纸屑)的recall不理想,再用imgsz=960做第二轮微调。最终我用的就是640和960双模型验证,选择了一个精度和速度的折中点。
  • 优化器选AdamW而非默认的SGD。原因很简单:我现在这个数据集规模不大,AdamW的收敛速度明显优于SGD,能更快定位到合适的超参数范围。
  • warmup设置3个epoch。YOLO训练初期学习率太大容易导致loss爆炸,warmup相当于给模型一个“热身期”,让权重从预训练值缓慢过渡到目标学习率。
  • patience=30配合cos_lr,意味着如果验证集loss在30个epoch内没有下降,训练提前终止。这个机制能避免中后期过拟合。

4.2 常见问题与排查技巧实录

整个流程走下来,踩坑无数。挑三个最典型的,按“现象 - 原因 - 解法”的结构写出来。

问题一:小目标recall低得离谱,烟盒几乎全部漏检

排查思路:先用可视化脚本把标注框在图上画出来,我标注的烟盒框平均只有28x28像素左右,这个尺寸在YOLOv8的640输入下会被缩小到约10x10像素,几乎没有有效特征。这个问题的解法不复杂,第一个是提高输入分辨率到960,第二个是调整锚框,把默认的8个锚框的最小尺度从4缩小到2。YOLOv8的anchor设置是在配置文件里的,手动改后重新训练,烟盒的recall直接从15%涨到了41%。

问题二:树影和路面裂缝导致大量误检

树影和裂缝的特征跟垃圾在某些角度确实相似,但最核心的问题是在数据增强时加入了过多的随机亮度扰动,导致模型把“暗色区域”都当成了垃圾。解决方案也很直接:把亮度扰动的参数从0.4下调到0.2,同时增加了一些真实负样本(纯背景无目标的图像)参与训练。我往训练集里塞了900张纯背景图,标注文件为空,这样模型会学到“没有目标时就该输出空”,大幅压低了误检率。

问题三:类间混淆——纸杯和塑料袋分不清

纸杯因为印刷图案和皱褶的原因,在一些角度看跟塑料袋确实很像。这个问题的根源在于类别的特征描述不够明确。我去标注现场拿了几十个真实的纸杯和塑料袋,从各个角度拍了一组照片,发现关键区分特征在于边缘轮廓:纸杯的边缘是硬朗的直线或弧线,塑料袋则是软的、不规则的曲线。于是我在标注规范里明确要求:如果目标边缘轮廓不清晰,倾向于标为plastic_bag而不是paper_cup。这是纯标注层面的调整,带来的收益却比改模型结构还明显。训练后,这两个类别的混淆率下降了近一半。

4.3 评价指标解析:mAP之外更要看什么

很多人拿到训练结果,只看mAP50和mAP50-95两个数,这其实不够。对不同尺寸目标的性能差异进行分析,才是指导优化的关键。在模型测试阶段,除了常规指标,我重点关注了这几个维度。

评价维度关注指标在本任务中的意义
精确率Precision@0.5误检情况,清扫垃圾频繁误报会直接影响系统可信度
召回率Recall@0.5漏检情况,垃圾没发现比误报更严重
小目标性能mAP@small(面积<32x32像素)烟头、纸屑等的检测能力,这是路面垃圾任务最容易翻车的区域
假阳率分析FPR(False Positive Rate)树影、路面纹理导致的误报占比

我把最终版本模型的评估结果记录了下来:mAP50为0.83,mAP50-95为0.56。单看数值不算顶尖,但分解到不同尺寸后发现,大目标的mAP50在0.9以上,小目标只有0.6。这说明模型的主要瓶颈依然在小目标的特征提取上,后续如果要进一步提升,方向很明确——针对图像切片增强超大图推理,或者引入更细粒度的数据增强策略。这个分析逻辑,是任何检测任务都要养成的习惯。

5. 实操过程的关键复盘

5.1 数据质量优先于模型结构

整个项目做完,我的一个核心体会是:路面垃圾检测,在算力有限的前提下,收益最大的投入是对数据的管理,而非对模型的调参。

前面提到过,我在初期为了追性能,花了很多时间尝试不同的backbone、引入attention模块、换FPN结构,但这些改动带来的提升很有限,有的甚至还把速度拖垮了。后来我把重心切回到数据侧,做了三件看似“笨”但极其有效的事:一是针对每类目标,逐张统计标注框面积,找出小目标比例偏低的类别,补充采集夜间弱光下的小目标样本;二是实施严格的数据清洗,把带水印的、有遮挡过多的大目标图像全部删除;三是在标注时强制要求框边缘与目标贴合,这个细节让AP值直接提升了2个百分点。

其实道理很简单:数据集里的噪音和偏差,模型会忠实地学进去。你给它一堆边缘不贴合的标注框,它学习的特征就是模糊的。标注质量是模型性能的上限,结构设计只是逼近这个上限的手段。

5.2 应用到实际场景的延伸建议

路面垃圾检测这个方向,做成数据集和单机演示只是一个起点。如果你要把它落地到真实项目中,还有三个方向值得投入:

第一个是模型轻量化。YOLOv8s已经很快了,但要部署到低成本边缘设备上(比如RK3588、Jetson Nano或者更是轻量级的算力设备),还需要用TensorRT做量化加速。我这里实测过,FP16量化后模型体积缩半,精度损失控制在0.5%以内,推理时间缩短到5ms左右,完全满足秒级响应。

第二个是半监督学习。标注是整个构建过程里成本最高的部分,在积累一定量标注数据后,可以尝试用训练好的模型给未标注的采集图像打伪标签,再人工复核。这样能大幅扩展数据量,每次迭代都能在更丰富的数据分布上提升模型鲁棒性。

第三个是难例挖掘。路面垃圾场景中的hard example主要来自遮挡和极端光照。把这些难例挑出来,可以用一些在线难例挖掘策略,也可以简单做一个小型难例数据集,每隔几轮训练周期拿它来验证模型在困难样本上的表现,随时跟踪瓶颈。

5.3 再分享两个小技巧

最后聊两个操作层面的技巧,都是我自己反复试出来的,通用性很强。

技巧一是训练时把Val集的图像分辨率设置成比训练分辨率高。比如训练用640x640,验证时用960x960。这样评估出来的mAP更接近部署场景的上限。原因在于,训练时的高分辨率会显著拉长单batch的迭代时间,而验证时仅推理一次,耗时可以忽略不计,却能提前预判模型在高分辨率推理时的表现。

技巧二是善用Ultralytics提供的混淆矩阵热力图。训练完成后,YOLOv8会生成混淆矩阵的图像,很多人不看,我看得很仔细。它不仅能告诉你哪两个类别容易混淆,还能帮你反推标注定义是否需要调整。我之前把纸杯和塑料袋的混淆率从18%降到了9%,就是靠混淆矩阵定位到类别定义问题,而不是盲目调参数。

整理这次路面垃圾识别数据集的构建经验,对我来说也是一次系统性的复盘。从需求拆解、数据采集、标注规范、模型选型到最终训练和评估,每一步都有可复用的方法论,也有专属这个场景的坑。如果你正在做类似的自定义数据集项目,希望这篇记录能让你少走一些弯路。还是那句话——把数据管好,模型自然会给你惊喜。

本文还有配套的精品资源,点击获取

需要专业的网站建设服务?

联系我们获取免费的网站建设咨询和方案报价,让我们帮助您实现业务目标

立即咨询