简介本资源是面向深度学习目标检测任务的路面积水识别专用数据集适用于YOLO系列v5至v10、Faster R-CNN、SSD等主流检测模型的训练与验证特别适合智能交通、城市内涝监测等实际场景下的算法研发与工程落地。压缩包共2000个文件主体为1999个YOLO格式的txt标签文件每张图像对应一个标注及1个含类别定义与划分信息的yaml配置文件全部图片已按标准比例划分为训练集、验证集和测试集可直接加载至YOLO框架训练无需额外格式转换或数据清洗。目前已有1009人学习下载资源结构规范、标注一致、场景覆盖多样含不同光照、积水程度及拍摄角度配套完整且开箱即用显著降低路面积水检测模型从零构建的数据准备门槛。 雨天跑过车的朋友都有体会路面积水看起来只是一滩发亮的水但对自动驾驶和辅助驾驶来说它意味着湿地附着力下降、可能涉水熄火甚至形成“水面反光导致传感器误判”的连锁问题。我这两年集中做过路面积水识别方向的目标检测项目前前后后攒了上万张图片、标了几千个框也踩了不少坑。这篇内容就把我构建和使用路面积水识别数据集的全过程拆开讲包括数据怎么采集、怎么标注、怎么用YOLOv8训练出可用的检测模型以及上线之后会遇到哪些让人头疼的问题。适合正在做智慧交通、自动驾驶感知、积水监测相关方向的开发者、研究生和产品经理参考哪怕你只是想用目标检测做一个小demo这套思路也能直接用。1. 项目整体思路为什么积水检测最大的难点是“数据”1.1 真正卡住项目的不是模型而是数据分布很多同学接到“路面积水识别”这个需求时第一反应是去下载一个开源目标检测模型想的是“用现成模型直接识别”。但实际做完一轮你会发现真正卡住项目的不是模型结构而是训练数据。公开的通用目标检测数据集比如COCO、BDD100K、Cityscapes里几乎没有带“积水”标注的类别。COCO有“雨伞”“水瓶”“飞机”就是没有“地面水坑”。这意味着你不可能像训练识别车、人那样直接拿公开数据集训一个通用模型出来所有的正样本都要靠自己采集或者转换。我最初也觉得这个工作量可以压缩——先用网上公开的路面积水图片凑一批再找几个视频抽帧。但训练一轮之后问题就出来了模型在晴天、光照均匀的路口表现不错一到逆光、夜里或者雨天反光的路面漏检率直线上升。原因不是模型差而是训练数据里根本没有覆盖这些场景。目标检测模型学到的其实是“数据的分布”数据集只有白天晴天的积水样本模型自然不知道逆光时积水长什么样。1.2 为什么这种任务必须自建数据集目标外观不稳定积水不同于检测车、人这种“形状相对固定”的目标。汽车的几何轮廓清晰、类别之间差异大而积水是地面上的低洼区域它会随光照、视角、路面材质和降雨量无限变化。同一个水坑俯视看是边界模糊的深色区域平视看变成一片高反光沥青路面的小水洼和水泥路面的积水在图像特征上几乎没有一致性。检测器的本质是在学习目标外观的高层特征积水这种“外观极不稳定”的目标对训练数据的覆盖度要求比普通目标高很多。这也解释了为什么单纯增加图片数量不一定有效更重要的是保证场景的多样性。做自建数据集并不是说要把每一滩水都框出来而是要让模型从多个维度理解“积水是什么”反光形态、水面纹理、明暗变化、和阴影的边界关系。这些信息不是靠一两千张图能学会的需要从不同天气、不同时段、不同拍摄角度反复采。整体方案设计上我把数据集当作项目最核心的交付物模型反而成了“验证数据集质量”的工具。2. 数据采集与预处理先解决“拿什么训”的问题2.1 采集策略覆盖比数量更重要如果你问我数据采集最重要的原则是什么我的回答是“覆盖度优先”。5000张覆盖雨天、晴天、逆光、夜间、隧道口、不同路面的图像效果通常好于50000张单一晴天的图像。因为积水识别任务里模型容易过拟合到拍摄场景而不是真正学会“认水”。我采集数据时主要走了三个途径。第一个是自采用行车记录仪、运动相机在雨天和雨后去不同路段拍重点覆盖低洼路口、隧道出入口、高架桥下、停车场坡道。第二个是从可商用授权的视频平台和公开数据集中筛选比如BDD100K中有一些雨天截图标注质量也不错可以先作为预训练基础。第三个是自己合成一部分数据用3D渲染或者图像编辑工具把水体贴图叠加到路面上再通过风格迁移让合成图和真实图像尽量相似。不过合成数据只能做辅助模型最终还是要靠真实样本调优单靠合成样本训练出来的模型实测基本经不起复杂光照考验。采集时记得把不同摄像头型号、不同分辨率的素材分开记录这能帮你后期排查数据偏置。我踩过的一个坑是数据集中80%都是1080p行车记录仪画面结果部署到720p监控摄像头时模型整体掉点严重。后来把不同分辨率的图片混合训练问题才缓解。2.2 视频抽帧技巧与首轮清洗拿到视频素材后第一件事是按照固定间隔抽帧。不要连续帧全抽因为相邻帧内容几乎一样会造成严重的数据冗余模型看到的“有效样本”并没有增加多少。我一般用1秒抽1帧或2秒抽1帧再抽测一批人眼过一遍删除重复度高、严重模糊、目标占比太小的画面。抽完帧之后先做一轮快速清洗。清洗的标准很简单目标太小积水区域小于整张图的1%、画面完全模糊、或者积水区域被大面积遮挡的图直接删掉。不要心疼那些“好像能看到一点水”的图片标注时会浪费大量时间训练时还会给模型增加噪声。我试过保留一批低质量图最后模型准确率反而下降了教训很深。信息密度也很重要。单张图里只有一滩细长的小水洼和一张图里有三处不同形态的积水后者对训练的贡献明显更高。所以抽帧时我会重点挑那些画面中有明显大面积积水、多目标出现的时刻而不是均匀抽完所有的帧。2.3 版权与合规问题快闪提醒自建数据集时还要想清楚合规问题。如果使用行车记录仪视频、监控截图务必获得采集者或权利人的授权如果是网络公开素材务必确认其许可证允许商用或科研使用。Apache License 2.0、CC BY 4.0这类宽松许可协议的数据集通常可以放心用但即使如此也要在项目文档里记录来源和许可信息。这个环节看似和模型无关但一旦项目要落地到产品版权隐患就会变成致命问题我身边确实有团队因为用了未经授权的路况视频最后被迫下线的例子。3. 数据集标注规范决定模型上限的幕后工作3.1 类别设计先做单类后续再细分目标检测是对数据集标注的类别进行学习的数据集有多少个类别模型就只能学到什么区分能力。但这里有一个很巧妙的点对“积水”这一类目标要不要继续细分为“水坑”“水花”“倒影”我的建议是第一版先全部统一标成“water”单类理由有两条模型在训练早期需要的是稳定收敛区分多个相似外观的子类会增加学习难度实际业务里大家关心的只是“哪里有积水”并不需要知道它是水坑还是水花。如果后续你的应用确实需要区分“静态积水”和“流动水痕”再在已标注数据上进行二次细分也不迟。单类标注更简单同类数据量更充足先保证模型检测能力再谈精细化分类。加类别这件事建议在数据集扩到一定规模之后再考虑不然每个子类的样本数都不够模型反而学不到各类别的稳定特征。3.2 标注工具体验与标注框规范标注工具我用过labelImg、Label Studio和X-AnyLabeling。如果你有团队协作需求Label Studio更合适支持多人标注、接口管理和自动保存单人小数据集用labelImg最轻量标注效率也高。X-AnyLabeling适合有预标注需求的项目可以用现成检测模型先打一遍框再人工修正效率能提升不少。标注框的规范是数据集质量的关键。我踩过的坑主要有三个框得太大把大片干燥路面也包进去模型学到的是“路面积水”框得太小只框住水面最亮的核心区边缘积水区域被排除在目标框外导致模型无法学习完整边界对拿不准的区域要么不标、要么统一按低置信度标注并备注不要随心所欲。我自己遵循的标注规则是把边界框贴近可见积水的明显边界包含水面反光区域但不要把干燥路面大量框进来如果水坑边界模糊以颜色明显变深或反光明显的区域为准如果一个区域有水花飞溅水花本身不单独框只框“水面区域”否则类别内外观差异会变得太大。标注完一轮之后我会抽样检查每个标注人员的框风格确保大家标准一致。3.3 负样本最容易忽略但极其重要的一步很多数据集教程都会忽略“负样本”但路面积水识别项目里负样本几乎决定着模型能不能上线。没有负样本模型会倾向于把画面中所有深色区域或者反光区域都识别为积水。深色沥青路面、湿润的路面、阴影、车轮碾过的水痕和积水在外观上高度相似如果训练集里只有正样本模型根本不知道“看起来像水但不是水”长什么样。我加入了大概20%~30%的负样本也就是完全没有积水的正常道路、雨天湿润路面、阴影路面、夜间灯光反射路面等图片用“空标注”文件参与训练。这一步让误报率下降非常明显。记住目标检测训练不只是告诉模型“什么是目标”还要告诉它“什么不是目标”。负样本是免费的模型纠错机制千万别省。3.4 标注文件格式与数据集目录结构我现在使用的标注格式是YOLO格式的txt文件每行对应一个目标框class_id center_x center_y width height四个坐标值都归一化到0~1之间。数据集目录结构建议就按YOLO的标准来dataset/ ├── images/ │ ├── train/ │ ├── val/ │ └── test/ └── labels/ ├── train/ ├── val/ └── test/图片和txt文件名一一对应。如果你从COCO或者BDD100K转过来可以使用ultralytics仓库自带的转换脚本注意类别ID要重新映射。训练前务必检查一遍每个txt文件里的坐标是否都在0~1区间我遇到过标注工具导出后坐标出现负数或大于1的情况训练时模型会直接把整张图当成目标非常坑。4. 基于YOLOv8的训练实操从yaml配置到结果解读4.1 模型选型为什么我用YOLO而不用Faster R-CNN路面积水检测最终要落地到视频流或嵌入式设备上实时性要求高。两阶段检测器比如Faster R-CNN精度确实有优势但速度往往达不到实时推理的需求而YOLO这类单阶段检测器在精度和速度之间平衡得比较好。以我手上的Jetson设备为例YOLOv8s可以在几十毫秒级别完成一帧推理而双阶段模型通常要翻几倍这在车载或者路侧监控场景中是不可接受的。YOLOv8本身有n/s/m/l/x几个版本n最轻x精度最高但速度最慢。第一次训练我建议直接用YOLOv8s起步保证效果的同时平衡训练速度和部署难度。如果只有几千张图的小数据集YOLOv8n也能用但对小目标积水区域可能会力不从心。等验证完整体流程再根据部署设备的算力把模型往上或往下缩放即可。4.2 数据集划分与yaml配置数据划分直接关系到评测可信度。我习惯按train:val:test 7:2:1来分划分时按“视频片段”而不是“单帧”来分避免同一段视频的连续帧同时出现在训练集和验证集里。如果图省事直接随机划分模型可能在验证集上表现优秀但一换新场景就露馅因为连续帧内容太像了模型已经“变相看见过”验证集里的画面。数据集的yaml配置文件很简单比如path: /path/to/dataset train: images/train val: images/val test: images/test nc: 1 names: [water]这里names列表的顺序要和标注文件里的class_id一致尤其你用脚本转格式时经常会出现类别ID错位的问题。准备好之后直接用ultralytics命令行或者Python接口开始训练。4.3 训练参数选择与命令行实践训练不是越久越好参数也不是越大越有效。我试过用100个epoch训练后面20个epoch基本没有增益反而增加了过拟合风险。常用的稳定组合是输入分辨率imgsz640或1280目标太小时可以提升到1280batch size根据显存来通常8到16epoch从100开始同时开启早停机制patience设为20~30优化器用默认的SGD或AdamW数据增强开启Mosaic、RandomAffine、HSV扰动。训练命令可以这样写yolo detect train datawater.yaml modelyolov8s.pt epochs100 imgsz640 batch16 patience30 projectwater_run如果你用Python接口等价代码如下from ultralytics import YOLO model YOLO(yolov8s.pt) results model.train( datawater.yaml, epochs100, imgsz640, batch16, patience30, projectwater_run, )我建议epoch先少设一点跑通流程后再逐步增加。刚开始训练时可以从预训练权重yolov8s.pt开始这样会比从零训练收敛快很多尤其我们的数据集通常只有几千张从零训练很容易欠拟合。4.4 训练过程监控我关心的Loss曲线训练过程中要盯两条关键趋势box_loss和cls_loss是否持续下降并在后期平稳以及验证集mAP是否还在上升。如果训练loss下降但验证loss升高说明过拟合了应该增加数据增强、加大负样本比例或缩小模型版本。如果两组loss都很高可能是数据标注质量有问题比如框的坐标偏差大。另一个容易被忽略的点是类别不均衡不过单类积水检测一般不涉及如果后面加多类就要重点处理。训练结束后输出目录里会有weights/best.pt和weights/last.pt。我建议只用best.pt做后续验证和导出别用last.ptbest.pt是按验证集mAP选出来的最优权重稳定性更好。5. 模型评估与阈值调优为什么mAP80不意味着能用5.1 核心指标mAP、Precision、Recall、F1训练完成后YOLOv8会自动输出一组评估指标。最简单的理解方式mAP50表示IoU阈值为0.5时的平均精度mAP50-95表示在多个IoU阈值下的平均精度后者更严格。Precision是模型预测的框里有多少是对的Recall是真实积水中有多少被检测出来了。F1是两者的调和平均。指标含义对积水检测场景的说明mAP50IoU≥0.5时的平均精度可以用来快速判断训练是否成功mAP50-95IoU从0.5到0.95的平均精度对框的定位精度更敏感值偏低是正常的Precision预测出来的目标中正确比例误报少说明模型不会乱认Recall真实目标中被召回的比例漏检少说明模型不会漏掉积水F1P和R的调和平均综合判断均衡点对积水检测来说mAP50达到80以上只能说明模型“在测试集上可用了”真正上线还要看和你业务相关的Precision/Recall取舍。如果一个系统在全天候视频流里疯狂误报比如把反光井盖当积水那高mAP也没有意义。5.2 PR曲线和置信度阈值决定最终体验的参数每个目标检测模型最终都会有一个置信度阈值conf_thresconfidence threshold。小于阈值的检测框会被丢掉阈值越高精确率高但召回率低阈值越低召回率高但误报多。训练完模型后我会先打开验证集上生成的PR曲线选一个P和R相对均衡的点作为初始阈值。一般来说conf_thres在0.25~0.45之间比较常见。实际部署时还需要调IoU阈值iou_thres用于非极大值抑制默认0.5到0.6之间问题不大。我见过一些人训练完模型就直接默认参数部署结果监控画面里全是框很大概率就是conf_thres设得太低。这个参数和模型精度无关只是后处理阈值但它对用户体验的影响比模型本身还大。5.3 误报和漏报的权衡不同场景要不同的判据路面积水检测在车载场景和交通监控场景里对误报和漏报的容忍度完全不一样。车载场景里漏报可能导致车辆快速冲入积水路段引发失控或熄火误报又可能让辅助驾驶系统频繁提醒干扰驾驶员。这时候我会把Recall优先放在Precision前面宁肯多报几个疑似区域也不要漏掉真正的深水区。但在城市内涝预警这类监控场景误报太多会让后台人员失去耐心反而漏掉真正需要预警的点位所以此时要适当调高置信度阈值保证报警质量。没有“最优”阈值只有“最适合业务”的阈值。我在项目中会带着验证集图片和一段真实视频反复调到肉眼观察下误报和漏报都可接受再固定参数。6. 实测中的高频问题与排查方案6.1 模型把阴影当积水怎么办这是路面积水识别项目里出现频率最高的一个问题。树荫、建筑物阴影、桥体阴影在视觉上和积水一样都是低亮度、边界模糊的区域模型特别容易混淆。我自己排查时发现原因是训练数据里的负样本不够多。解决思路分两步第一步补充大量有阴影但没有积水的图片作为负样本第二步在数据增强中降低亮度扰动幅度否则模型会把“变暗”的语义学成“有水”。另一个有效方法是给模型增加上下文信息比如告诉模型“阴影通常会跟随实体物体”这可以通过加大训练图片的感受野来实现。实测把输入分辨率从640提升到1280之后模型对阴影和积水的边界判断显著改善阴影误报减少约30%。6.2 雨滴反光和夜间灯光干扰雨天地面本来就有水雨滴落在水面激起涟漪会让积水边界变得极不稳定夜间路灯和车灯在水面产生拉长的反光也会让很多模型把整条光带当成积水。这些场景对单帧检测器来说相当困难。我的处理方案有两个一是在训练数据里增加夜晚、雨天、车灯的联合样本让模型见过足够多的“灯光下的水面”二是部署时不再用单帧推理而是引入连续帧信息利用目标在帧与帧之间的运动一致性过滤掉闪烁的灯光干扰。说白了水中倒影会随着视角移动但积水区域本身相对稳定用帧间一致性可以刷掉很多误检。6.3 小目标漏检水洼面积小但很重要监控摄像头画面中距离远一点的微小水坑可能只占几个像素YOLOv8s很容易漏掉。提升小目标召回率的实用手段是增大输入分辨率但显存占用会明显上涨。另一个思路是把检测图切成两个半幅分别推理再合并对小目标更友好。也可以尝试增加Mosaic增强让模型有更多机会学习到包含小目标的场景。我在自动驾驶场景里还会配合一个语义先验积水只会出现在路面区域不会出现在天空、车辆或建筑上。所以我会先用一个轻量级路面分割模型或车道线检测模型做粗筛把检测范围限制在路面区域内这样小目标的搜索空间大幅缩小漏检率也随之降低。6.4 离线测试效果好一上视频流就卡顿模型在图片上测着不错但放到视频流推理时帧率突降这是部署优化没做好的典型问题。排查顺序我一般这样来先确认推理前处理是否做了resize和归一化再确认是否开启了TensorRT或OpenVINO加速最后看是否在循环里重复加载模型。YOLOv8导出ONNX后再转TensorRT推理速度能提升不少。如果设备算力有限把模型从YOLOv8s降到YOLOv8n同时用640分辨率推理基本能在嵌入式设备上跑出流畅效果。不要一上来就在视频流里跑x版本除非你有专业级GPU。7. 部署经验与后续扩展小建议训练完成并调好阈值之后部署环节同样不能马虎。我推荐用NVIDIA Jetson边缘设备或者x86工控机通过ONNX Runtime或TensorRT推理。导出命令直接用ultralytics的export接口yolo export modelbest.pt formatonnx如果目标设备是TensorRT继续转成engine格式。整个过程不太复杂但要注意TensorRT版本和PyTorch版本的兼容性。我因为版本不一致踩过坑导出后推理结果全乱后来统一了CUDA、TensorRT和PyTorch的版本才恢复正常。导出之后建议重新用同一批验证集图片跑一遍推理对比导出前后的框输出一致性这一步可以避免很多部署期的低级错误。关于扩展方向路面积水识别数据集目前只解决了“哪里有水”的问题。后续可以继续做“水有多深”通过水面的光影变化和周围参照物高度估算积水深度这也是很多城市内涝预警项目下一步想做的事。还可以把视觉检测结果和雨量计、液位计数据做融合用多模态信息给出更可靠的内涝风险提示。我在项目里已经做了一版基于积水框面积和侧面参照物的粗略水深分级虽然精度还不能当传感器用但给预警系统提供了比较有效的前置筛选能力。最后说一个我自己的经验路面积水识别算法的核心毕竟在数据。模型结构可以换训练技巧可以学但数据多样性、标注准确度和负样本覆盖度才是决定项目能走多远的东西。如果你正在做一个类似的积水检测项目一定要先把数据采集和标注的流程跑扎实。这个功夫省在哪里部署后的误报和漏检就会在哪里还回来。本文还有配套的精品资源点击获取