ARTICLE DETAIL

资讯详情

深耕网站建设、视觉设计与SEO优化的一线实战洞察。

智慧城市道路设施检测数据集:13000张已标注图片,目标检测直接可用

智慧城市道路设施检测数据集:13000张已标注图片,目标检测直接可用

最近在做一个智慧城市巡检项目,需要训练一套能识别城市道路设施和道路安全隐患的检测模型。最头疼的其实不是模型怎么搭,而是数据从哪来。自己带车去路上拍,一个区跑下来就是好几百公里,还要处理光照、遮挡、运动模糊一堆问题,等数据整理干净,两个星期就过去了。后来拿到一套城市道路设施及道路安全隐患数据集,13000张图片已经划分好、已经标注完,直接就能送进目标检测流程里跑,省掉的时间不是一点半点。

这套数据集覆盖的内容很明确:城市道路里的各类设施(井盖、护栏、标线、标志牌、路灯等)和安全隐患(坑洼、裂缝、破损、积水、施工区临时设施等),都是道路养护和智慧交通场景里最常见的检测目标。适合这几类人:做智慧城市/智慧养护项目的算法工程师,需要快速验证目标检测方案的团队,搞自动驾驶感知但想补充结构化道路要素的开发者,以及拿真实场景数据做毕业设计或课题研究的学生。如果你正在找一份“拿来就能用”的道路场景检测数据,这篇就把这套数据的底细、怎么用、以及我实际踩过的坑一次讲清楚。

1. 数据集整体设计与思路拆解

1.1 为什么需要“道路设施+安全隐患”联合数据集

传统道路巡检基本靠人工。养护工人开着巡检车,或者干脆步行,用肉眼一张张看路面哪里有坑、哪里有裂缝、哪块护栏歪了。这种方式的问题不用多说:效率低、主观性强、很容易漏检,而且巡检结果没有标准化的记录方式,今天这个师傅记一段,明天那个师傅记一段,后期做统计和维修排期非常痛苦。

所以现在行业里都在往自动化巡检方向走,核心就是给巡检车装上摄像头,用目标检测模型实时识别路面病害和设施异常。但“识别”的前提是“数据”。一个能用的道路目标检测模型,训练数据必须有这几个特点:场景覆盖面广、目标类别足够全、标注质量稳定、划分逻辑合理。这套13000张图片的数据集,就是围绕这个需求来的。

它把“道路设施”和“安全隐患”放在同一个数据集里,这一点很关键。因为在实际巡检中,设施完好与否本身就是判断安全隐患的依据——一个破损井盖既是“设施异常”也是“安全隐患”,一条严重裂缝既是“路面病害”也预示着结构风险。把两类目标放在统一的数据体系里,模型学到的特征更接近真实巡检逻辑,训练出来的模型也能在一个框架里同时输出设施状况和风险提示,而不是分两套系统跑两遍。

1.2 13000张图片的构成逻辑与方案选型

先说为什么是图片,不是视频帧。视频数据虽然量大,但相邻帧之间高度相似,直接拿去训练会造成严重的冗余——模型见过同一段路的几十张“几乎一样”的图,真正能够提升泛化能力的信息并没有增加多少。这套数据集直接给的是图片,而且是经过抽帧清洗后的有效图片,相当于已经帮你把视频数据里最核心的“关键时刻”都挑出来了。13000张里面,train/val/test已经按比例划分好,不用自己再动手分割。

为什么用目标检测,而不是实例分割或语义分割?这也是个现实考量。道路巡检这类任务,业务上需要知道的是“哪里有问题、什么问题、大概多大范围”,目标检测输出的边界框(bounding box)已经能支撑这些需求——比如知道一个坑洼的坐标位置和尺寸,就足够派单给养护班组去维修了。实例分割精度更高,但标注成本几乎是检测的3到5倍,对硬件部署的要求也更高。在巡检车这种边缘计算场景里,检测模型在算力有限的工控机上能跑实时,分割模型往往做不到。所以目标检测是这个场景里性价比最高的选择。

数据划分的比例也经得起推敲。按照常见的7:2:1划分,训练集约9000张,验证集约2500张,测试集约1500张。这种划分的好处是:训练集足够支撑模型收敛,验证集能稳定反映调参方向,测试集又能提供一个相对公平的最终评估基准。有些数据集的划分非常随意,测试集太大导致训练不充分,或者验证集太小导致调参噪音大,这套数据没有这个问题。

1.3 标注体系背后的“为什么”

拿到数据我先做了个统计,发现它的标注类别设计是有讲究的。不是把路上所有东西都标出来,而是聚焦在“与道路安全和养护直接相关”的目标上。比如井盖破损/缺失、护栏破损/缺失、路面坑洼、路面裂缝、标线磨损、交通标志异常(倾斜/破损/被遮挡)、施工围挡、路障锥桶、路面积水、路灯异常等。

这个类别体系的合理性在于覆盖了两种尺度差异很大的目标。井盖、锥桶、裂缝属于中小目标,在画面里可能只占几十个像素;而施工围挡、护栏属于大目标,可能横跨整幅图像。如果只做单一尺度的数据,模型很容易对某个尺度产生偏置。这套数据里大目标、中目标、小目标都有分布,对训练一个尺度鲁棒的检测器很有帮助。

标注选项采用矩形框,但框得比较严格,对所有目标都按照“包含整个目标本体、不截断、不扩边”的原则来标。这一点我在后面做训练评估时深有体会——标注框贴合目标,模型学到的边界才干净,推理阶段的定位精度才会高。很多公开数据集的标注都松松垮垮的,用起来非常难受,这套数据在这点上做得比较规整。

2. 核心细节解析与实操要点

2.1 类别体系与标注格式详解

这套数据的标注格式兼容主流目标检测流程。我拿到手看到的是比较标准的格式,同时附带了转换脚本,可以根据需要转成你要的格式。以下是常见的三种格式对比:

格式文件后缀关键内容典型框架
VOC格式.xml目标类别、坐标(xmin/ymin/xmax/ymax)老牌检测框架,Faster R-CNN等
COCO格式.json类别ID、分割/框坐标、图片元信息Detectron2、MMDetection
YOLO格式.txt类别ID、归一化中心坐标(x_center/y_center/w/h)YOLO全系、Ultralytics框架

这里要特别提醒:YOLO格式的坐标是归一化到0到1之间的,不是像素坐标。我第一次用某个数据集的时候没注意这点,直接把像素坐标喂进去,结果模型训练了50个epoch后loss完全没降,最后发现是归一化处理出了问题。如果你的数据源是VOC或者COCO格式,转换到YOLO格式时一定要做归一化,公式很简单:

x_center = (xmin + xmax) / 2 / image_width y_center = (ymin + ymax) / 2 / image_height w = (xmax - xmin) / image_width h = (ymax - ymin) / image_height

如果拿到的是已划分好的YOLO数据,布局一般是这样的:

dataset/ ├── images/ │ ├── train/ # 约9000张 │ ├── val/ # 约2500张 │ └── test/ # 约1500张 ├── labels/ │ ├── train/ # 对应的txt标注 │ ├── val/ │ └── test/ ├── data.yaml # 数据配置文件 └── classes.txt # 类别列表

data.yaml的内容也很简单,按需调整一下路径就能用:

path: /path/to/dataset train: images/train val: images/val test: images/test nc: 10 names: ['manhole_damaged', 'guardrail_broken', 'pothole', 'crack', 'marking_faded', 'sign_abnormal', 'barrier', 'cone', 'water_accumulation', 'streetlight_off']

2.2 标注质量对训练效果的影响到底有多大

很多人低估了标注质量的影响。同一份数据,标注框贴合度差2到3个像素,最终训练出来的mAP可能差3到5个百分点,这不是玄学,是实打实的loss信号质量差异。目标检测的回归头学的是“预测框到真实框的距离”,如果真实框本身位置不准确,模型学到的映射关系就是错乱的,推理时哪怕分类对了,定位也会偏。

这套数据集在标注质量上做得比较难得,主要体现在三点:一是框的贴合度高,基本没有包含大量背景的多余边距;二是目标被遮挡时,依然按照可见部分来标,而不是直接漏标;三是同一类别的标注标准统一,比如“井盖破损”统一只标井盖本身,不把周围路面也圈进去。这些细节在训练时可能感觉不出来,但在测试集上对比评估时差距非常明显。

另外,我建议拿到任何数据集后都不要直接开跑,先做一轮标注质量快速抽查。方法很朴素:随机抽200张图,用可视化脚本把标注框画出来,肉眼过一遍,看看有没有类别标错、框完全偏掉、或者漏标的。200张图大概半小时就能看完,但能帮你避免跑完整个训练流程后才发现数据问题的尴尬。

2.3 小目标占比与背景复杂度这两个隐藏难点

道路场景的目标检测,两大难点是绕不开的:小目标和复杂背景。这套数据的图片分辨率不低,但井盖、裂缝、锥桶这类目标在画面中占比仍然很小,特别是裂缝,往往是长条形的,宽只有几个像素,长可能跨几十个像素,检测器要准确捕捉这种细长目标并不容易。背景复杂度也很高,树影、路面纹理、轮胎痕迹、水渍这些都会形成干扰,模型很容易把“很像裂缝的阴影”误检成裂缝。

所以我拿到数据后做的第一件事,不是调模型结构,而是先统计小目标的分布比例。具体做法是计算所有标注框相对于图片的面积占比,如果小于0.05%,则视为小目标,然后统计这个比例在训练集和验证集中是否一致。如果一致,说明数据划分是均匀的;如果不一致,就需要做层次采样重新划分,否则验证集评估出来的指标不具备参考性。这套数据在我统计下来类别分布和尺度分布都还算均衡,没有出现某个类别在训练集里很多、验证里几乎没有的极端情况。

3. 实操过程与核心环节实现

3.1 环境准备与数据完整性检查

实操第一步不是装环境,而是检查数据完整性。图片和标注文件要一一对应,这是最容易出问题的环节。我写过一个快速校验脚本,核心逻辑很直接:遍历所有图片文件,检查同名的标注文件是否存在,再检查标注文件里的类别ID是否越界、坐标是否在图片尺寸范围内、框是否宽高为0。

import os from PIL import Image def check_dataset(img_dir, label_dir, nc=10): img_files = [f for f in os.listdir(img_dir) if f.endswith(('.jpg', '.png'))] errors = [] for img_file in img_files: label_file = os.path.splitext(img_file)[0] + '.txt' label_path = os.path.join(label_dir, label_file) if not os.path.exists(label_path): errors.append(f'{img_file}: missing label') continue with open(label_path, 'r') as f: lines = f.readlines() if not lines: errors.append(f'{label_file}: empty label') for line in lines: parts = line.strip().split() if len(parts) != 5: errors.append(f'{label_file}: bad format') continue cls_id = int(parts[0]) if cls_id >= nc: errors.append(f'{label_file}: class id {cls_id} out of range') return errors errs = check_dataset('dataset/images/train', 'dataset/labels/train') print(f'errors: {len(errs)}') for e in errs[:10]: print(e)

环境方面,我用的就是目前的Ultralytics检测框架,一条命令装完所有依赖。GPU环境建议显存至少8GB,batch size可以开到16,如果显存不够就调到8,模型选轻量版。

pip install ultralytics

3.2 模型选型与训练参数设定

在模型选择上,我建议从YOLO系列的轻量级模型开始。以开源的YOLOv8s为例,参数量约1100万,在道路场景的复杂背景下,精度和速度的平衡比较好。如果你有更强的算力,可以尝试m或l版本,精度会有提升,但对部署端的帧率要求要提前评估。

训练参数这边,我第一轮用的是比较保守的配置:

yolo detect train \ data=road_data.yaml \ model=yolov8s.pt \ epochs=200 \ imgsz=640 \ batch=16 \ lr0=0.01 \ optimizer=SGD \ patience=30

几个关键参数为什么这么定,我展开说说:

  • imgsz=640:YOLO系列在640输入下能兼顾精度和速度,道路设施目标大多数在中等尺度,640足够了。如果你要重点优化小目标,可以试768或896,但推理耗时也会相应增加。
  • epochs=200:这个量级的训练集,100个epoch模型基本能收敛,200个epoch是为了确保曲线平稳,配合早停机制,不会浪费太多时间。
  • batch=16:这是16GB显存机器上的稳妥选择。batch过小会导致loss波动大,收敛慢;过大可能在复杂背景数据上过拟合更早。
  • lr0=0.01 + SGD:SGD比AdamW泛化性好一些,在道路场景这种背景多样化的数据上,SGD训练出来的模型往往稳定性更好。AdamW收敛快但容易在后期震荡,适合做迁移学习的第二阶段微调。

我第一轮训练的结果,在验证集上mAP@0.5大约在0.83左右,mAP@0.5:0.95在0.57左右。这个水平对道路巡检来说已经能用了,但还有不少提升空间,后面就是针对难点逐步调优。

3.3 训练评估与针对性调优

训练完之后不要只看mAP,要拆开看具体类别的表现。我通常用混淆矩阵和各类别PR曲线来分析。在道路场景里,最容易出现两类问题:一是“裂缝”被误检成阴影,二是“井盖破损”和“普通井盖”之间的混淆——如果数据里没有标注“正常井盖”作为负样本,模型很容易把所有井盖都判定为破损。

我自己排查时的做法是,把验证集里所有预测错误的图片全导出,按错误类型分类。一张张看误检图比看指标有用得多。比如我发现“护栏破损”的漏检主要集中在远处目标上,通过进一步分析找到原因:护栏这种细长结构,在远处只有很小的高度,特征不明显。解决方案是在训练时把mixup和mosaic增强都打开,并且适当上调输入分辨率到768,让模型在训练时能看到更清晰的远处护栏特征。

数据增强这块,我强烈建议在道路场景下开启马赛克增强和HSV色彩扰动。马赛克增强可以将四张图拼接成一张,增加背景多样性,对减少过拟合效果明显;HSV扰动则模拟不同天气、不同光照下的色彩变化,增强模型的色彩鲁棒性。我实测在不开任何增强时,mAP@0.5大概在0.78左右,开启马赛克和HSV后提升到0.83以上,涨点非常明显。

3.4 模型导出与边缘部署

道路巡检的部署场景大多是边缘设备,也就是巡检车上的工控机或者嵌入式设备。训练完模型后,一般要导出成ONNX或者TensorRT格式再部署。以测边部署为例,导出命令很简单:

yolo export model=best.pt format=onnx opset=12 imgsz=640

如果目标设备是N卡工控机,可以直接转成TensorRT加速引擎,推理速度能提升2到3倍:

yolo export model=best.pt format=engine device=0 imgsz=640

部署时要注意输入图像的预处理细节——YOLO系列的预处理是在内部完成的,但如果你自己写推理代码,就要保证resize的方式和训练时一致,否则检测精度会明显下降。具体来说,YOLO的resize是等比缩放加padding到640×640,而不是直接拉伸,这个细节很重要。

我实际部署到一块低功耗工控机上跑过,YOLOv8s在640输入下,TensorRT推理速度大约在15到25毫秒每帧,换算下来帧率足够覆盖巡检车正常行驶速度下的抓拍需求,实时性完全没问题。

4. 常见问题与排查技巧实录

4.1 样本不均衡:少样本类别的处理思路

巡检数据天然存在不均衡问题。坑洼、裂缝这类常见病害样本多,而路灯故障、交通标志异常这类样本相对少。在13000张数据集里,各类别样本量虽然有差异,但差距没有到“完全训练不起来”的程度。

如果遇到少样本类别,我的处理顺序是:先看类别样本量分布,如果最少的类别与最多的类别差距超过10倍,才需要额外处理。处理手段从轻到重依次是:

  • 收集同场景公开数据补充少类样本
  • 对少类样本做复制粘贴增强,把目标贴到不同的背景图里
  • 在训练重加权(class weighting),提高少类别的loss贡献

不建议一上来就删多类样本做均匀采样,这会浪费大量有效数据。我见过有人为了让各类别数量一致,把井盖样本从3000张降到300张,结果井盖检测精度直线下降。

4.2 小目标漏检与阴影误检的针对性解法

小目标漏检和阴影误检是道路数据集里最常见的两个问题,绝大多数时候这两个问题是同时出现的。裂缝在远处很小,容易被漏检;树影形状又像裂缝,容易被误检。

我实测下来最有效的组合方案是:将输入分辨率从640提到896,开启马赛克增强,并在训练后处理中适当提高置信度阈值到0.35到0.4。提高阈值虽然会让部分真目标漏掉,但能大幅压低误检率,让最终部署的效果更可用。如果你希望兼顾召回,可以低阈值加上目标轨迹跟踪,时序信息能帮你在多帧中确认同一目标,误检会被自然过滤掉。

也有人用切图(tiling)的方式处理小目标,把大图切成若干640的小图分别推理,小目标检测率提升最明显,但推理耗时也会成倍增加。巡检车的算力有限,我一般不建议这么做,优先靠多尺度训练来缓解。

4.3 标注松弛与类别混淆的“清洗三板斧”

公开数据集的清洗是必修课,这套数据也不能说100%完美。我的经验是拿到数据后做一次“清洗三板斧”:

第一板斧是尺寸过滤。把所有标注框宽度或高度小于3像素的目标直接删掉,这些极小目标对训练只有噪音,没有有效信息。第二板斧是宽高比过滤。如果某个目标的标注框宽高比极其夸张(比如超过20:1),检查一下是不是标错了,或者是不是本就该用实例分割来表示的更细长目标。第三板斧是类别一致性检查,特别留意“同物异名”或“异物同名”的情况,比如“pothole”和“socket”在某些地区是不同概念,但在标注时可能被混用。

这三板斧做一次,大概半小时能过滤掉不少问题样本。过滤后重新跑一次训练,mAP能稳定提升0.5到1个百分点,虽然不多,但属于白捡的收益。

4.4 不同天气与光照的泛化问题

道路巡检不可能只在晴天中午跑,雨天、阴天、夜间都是真实作业场景。如果是用白天晴天数据训练的模型,雨天推断时误检率通常会显著上升,因为雨滴反光和水面倒影都会制造出“看起来像坑洼”的特征。

这套数据集在不同天气和光照环境下都有覆盖,但分布不均。我的建议是训练时把HSV增强的参数范围调大一些,比如Hue扰动调到0.015左右,Saturation扰动调到0.7,Value扰动调到0.4,这样模型能学到更宽泛的色彩变化模式。如果想要更极端的鲁棒性,可以在推理前端加一个简单的自适应图像增强模块,对低照度图像做直方图均衡化后再送进模型。

实测下来,经过HSV增强训练后的模型,在阴雨天的mAP下降幅度可以从8到10个百分点收窄到4到5个百分点。如果项目对恶劣天气有硬性要求,更稳妥的方案是额外采集雨天、雾天的数据做补充训练,单靠数据增强无法完全替代真实场景样本。

写在最后

这套13000张图片的道路设施及道路安全隐患数据集,我实际拿来跑项目之后最大的感受是:省下的最宝贵资源是我的时间。数据划分合理、标注格式标准、类别覆盖贴合真实业务,从拿到手到跑出像样指标,只花了两天时间。如果自己采集清洗,这个周期至少要三到四周。

不过我也要提醒一句,任何数据集都不可能完全替代针对性采集。如果项目要交付给某个特定区域使用,最好在模型基本可用后,再去目标区域采集一小批代表性数据做微调,尤其是当地特有的设施类型和路面材料特征,这种区域适配不是通用数据集能解决的。我现在的做法是,永远把公开数据集当作起点,把领域采集当作终点,两者配合,最终交付的模型才真正扛得住现场环境的考验。

返回列表