资讯动态

无人机巡检道路病害:YOLO数据集构建与训练实战全流程解析

发布时间:2026/10/23 5:19:57 来源:尧图企业网站定制
无人机巡路这事这两年市政口子上越来越常见了。以前靠人工坐车巡查或者徒步记录效率低不说很多细微裂缝和早期坑洞根本看不到。换成无人机低空航拍之后一天能扫几十公里路但新的问题跟着来了拍回来的素材堆积如山靠人眼一帧一帧看眼睛看花了不说漏判率还高得吓人。我做这个道路病害巡检数据集项目初衷就是把“拍到的画面”变成“能直接训练检测模型的数据”让裂缝识别和坑洞检测真正落地。系列已经做到第10402期每一期的数据采集、筛选、标注、格式转换都有固定的套路和踩坑记录这篇把整个流程里最核心的东西拆开讲讲给同样在搞市政巡检数据集和YOLO检测训练的朋友做个参考。1. 项目定位与数据规划1.1 巡检缺陷识别的核心需求市政道路巡检的缺陷目标其实没有想象中那么复杂。真正需要检测的病害类型百分之八九十集中在两种裂缝和坑洞。裂缝是路面最常见的早期病害表现为线状、网状或不规则开裂如果能在裂缝阶段就发现并修复养护成本最低。坑洞则是路面结构破坏后的典型表现通常伴随松散、剥落对行车安全影响最大必须优先处理。我在做这个数据集的时候最初的组内讨论也在争要不要把修补痕迹、车辙、拥包也纳入检测目标。后来实际跑了几轮才发现类别越多标注负担和模型误检率就同步上升。第10402期这个数据集最终只保留了裂缝和坑洞两类把每类的样本量做得足够扎实。对小目标检测来说宁缺毋滥类别聚焦是提升精度的捷径。1.2 类别定义与标注边界类别定义看着简单真正执行标注时尽是细节。裂缝有横向、纵向、块状、网状的区分对于检测任务来说这些都需要统一归为crack坑洞则主要指路面材料脱落形成的凹坑如果只是表面龟裂还没脱落仍然归为裂缝。在标注规范里我明确了一条边界凡是断裂面可见、宽度超过约3mm就标裂缝凡是凹坑深度肉眼可辨、边界清晰就标坑洞两者在同一区域重合时优先标坑洞因为它对安全影响更严重。尺寸边界也是踩坑重灾区。无人机航拍的高度和角度不同同样的裂缝在画面里的像素尺寸差异非常大。我统一规定最小标注框边长不低于8像素因为低于这个尺寸任何检测模型都很难学到有效特征标了等于没标还容易干扰损失收敛。这个8像素的阈值也是反复测试后得出的经验值YOLO系列模型在特征金字塔里对8像素以下的目标基本无能为力。1.3 为什么选择YOLO格式数据集最终交付为YOLO格式说白了就是一类目标一个txt文本内容是归一化后的中心点坐标和宽高。为什么不用COCO或VOC格式一是YOLO系模型是目前边缘设备和巡检场景最常用的检测框架权重文件小、推理速度快适合后续部署到机载或者便携终端二是YOLO格式的标注文件轻量单个txt几行数字处理几千张图压力很小方便批量校验。从COCO转YOLO格式我用过一个笨办法先用标注工具导出JSON再写脚本做坐标换算和归一化。这个转换脚本是整个数据生产线里最重要的零件后面专门讲实现细节。这里提一句如果只打算用标注工具直接出YOLO格式也能做但后续做数据清洗、合并、增强时统一用脚本转一遍格式和命名都更可控长远看省心得多。2. 数据采集无人机航拍方案与质量筛选2.1 飞行参数与成像质量第10402期数据里涉及的航拍素材来自多个路段的巡检飞行任务。无人机飞行高度我统一控制在25米到40米之间这个高度能兼顾单张影像覆盖面积和地面分辨率。飞太高了裂缝细节丢失飞太低覆盖效率太低测了一轮下来35米左右是比较舒服的折中档。镜头角度要尽量保持垂直向下但实际巡检时难免受杆塔、树木影响轻微的倾斜角在可接受范围内。关键是不能让影子大面积遮挡路面阴影在标注时真的很难分辨是真裂缝还是光影。所以拍摄时段优先选在上午10点前或下午3点后太阳高度角的影子长度刚好能避开裂缝区域这个细节直接影响标注效率和模型泛化能力。图像重叠率我设置在75%以上。航拍巡检的路线规划用自动航线相邻两张照片的重叠率不够时后续拼接或者单帧检测都会出现漏检。重叠率高一点同一条裂缝可能出现在两三张图里对训练集来说是天然的正样本扩展虽然标注工作量增加了但对模型收敛很有帮助。2.2 场景多样性的把控道路巡检数据集最怕的就是场景单一。全是光照良好的水泥路做出来的模型一到阴天沥青路就失灵。所以在采集任务分配上我会刻意覆盖几种典型场景城市主干道的沥青路面、老旧社区的混凝土路面、乡道上的碎石和裂缝混合路面、雨后积水路面、桥梁伸缩缝周边。另外不同时间段采集的素材也要混合。清晨路面有露水裂缝里积了水和干燥时的裂缝外观完全不同午后沥青反光强度高裂缝边缘的对比度下降。如果一个数据集里全是干燥晴天素材训练出来的模型遇到雨后巡检就完全没法看。第10402期里我专门混入了约15%的阴天和雨后素材实测下来模型的雨天鲁棒性提升非常明显。同类场景扣得细一点还有分层表面纹理粗糙度、裂缝走向、阴影分布、水泥缝和真实裂缝的区分这些都是导致误检的隐形因子。采集时尽量把这些情况都覆盖到后面模型报错时你才不会到处找原因。2.3 初筛与清洗策略无人机飞完一趟下来存储卡里可能有大几千张图片把这些全部标注是不现实的成本和时间都撑不住。第10402期的方法是把初筛分成两道第一道是自动筛选。写一个简单的脚本统计每张图的灰度分布和梯度信息凡是纯路面、无明显纹理变化或大面积过曝的图直接标记为low_value这部分通常能砍掉30%左右。还有一个指标是清晰度用Laplacian算子计算方差低于设定阈值的图说明画面模糊直接淘汰这类图即便标了也是增加噪音。第二道是人工快筛。把自动筛选后的图按路段切片快速扫一遍图片墙把重复出现、非道路区域过多、或者无人机桨影干扰严重的图剔除掉。初筛这件事很磨人但太重要了。很多做数据集的朋友上来的第一件事是急着标注结果几千张图标完发现质量不合格又回头返工时间全浪费了。数据集的质量80%在采集和初筛阶段就定下了后期标注只是把这些质量兑现出来而已。3. 标注规范与质量双检3.1 标注工具与配置文件标注工具用过好几款最终固定下来的流程是LabelImg做初标再用一个自研的小工具做格式校验和转换。LabelImg虽然老但胜在稳定、轻量框选逻辑简单部署不需要环境折腾团队协作时上手成本最低。LabelImg安装没什么好说的pip安装或者直接拉release包都行关键是配置好类别文件。我习惯在项目根目录放一个classes.txt里面就两行crack pothole标注前先让所有标注人员确认预置类别文件加载成功否则容易出现类别标注成数字编号错乱的问题。曾经有组员在没加载classes.txt的情况下标了一百多张图导出XML后类别全是数字转换脚本直接跳错。从那次以后我要求开工前先标注十张测试图并跑一遍转换流程验证通过再大规模开工。3.2 裂缝和坑洞标注的边界标准标注标准细化到具体操作要给出非常明确的操作指引。比如裂缝框选范围要求是完整包住主裂缝区域但背景路面占比不得超过框面积的30%。裂缝走向如果比较曲折直接用最小外接矩形框住即可不需要沿着裂缝走向画多边形。YOLO检测本身就是矩形框输出强行用多边形标注初始数据到转换时还是得回归到矩形框中间损耗太大。坑洞标注要严格贴合坑洞边缘留2到3像素的余量即可千万不要把周围松散的区域全包进来。这里有一个容易犯的错看到一片路面破损习惯于把整个破损区域拉一个大框但破损区域可能包含多个独立坑洞框太大会把一个目标框住多个目标模型训练时损失函数会混乱检测时也很容易出现一个预测框覆盖多个目标的情况。我在标注规范里还加了一条铁律肉眼无法确认的模糊目标宁可不标也不要勉强框。训练集里错误的负样本带来的危害远大于漏标一个正样本这个体会后面在模型测试时体会特别深。3.3 交叉质检与争议仲裁标注完成后我要求做两轮交叉质检。A标完的图由B复检复检不是抽查而是全检标注框的偏移、遗漏、类别错误都需要标记。复检率控制在90%以上才算合格。交叉质检里最常发现的问题是裂缝的断开标注。一条连续裂缝因为阴影或路面标线的干扰被分成了两三个框这在检测任务里是允许的因为在模型看来这些本来就是不同的局部特征。但有一种情况必须返工同一处裂痕在相邻图里标注框尺寸差异超过30%这种通常意味着一张图标漏了或者标得过紧需要核对原图修正。遇到标得模棱两可的争议样本组里会拉一个三方仲裁组由一位经验比较丰富的人做最终裁定。裁定的标准答案会记录在标注规范文档里并在每周例会上同步给所有人这样一来标注不一致的问题会随时间推移越来越少。4. YOLO格式转换与数据集组织4.1 格式转换脚本与目录结构标注产出后最重要的环节就是把XML或JSON格式转换成YOLO训练要求的txt格式。转换的核心是坐标计算读取标注框的左上角和右下角坐标计算出中心点坐标和宽高然后分别除以图片的宽和高得到归一化数值。这里有一个明显的坑有的标注工具导出框坐标时是把左上角记为(x_min, y_min)但有的工具记录的是中心点坐标。如果不先确认工具的输出格式转换脚本算出来的框会整体偏移训练出来的模型预测框全部错位。第10402期的数据转换脚本里我在头部加了一个坐标源格式的选择参数从数据源头就避免了这类低级错误。转换后的目录结构我通常是这样的dataset/ ├── images/ │ ├── train/ │ ├── val/ │ └── test/ ├── labels/ │ ├── train/ │ ├── val/ │ └── test/ ├── classes.txt └── data.yaml图片和标签严格同名只是后缀不同这个约定在YOLO训练流程里是硬性要求。组织数据前先跑一个校验脚本确保每张训练图片都有对应的标签文件、每个标签文件都不为空这步能避免训练时很多莫名奇妙的报错。4.2 数据集划分与分布验证数据集划分我首选按路段划分而不是按图片随机划分。同一路段的照片背景、路面纹理非常接近如果同一路段的图片既出现在训练集又出现在验证集验证结果会虚高。按路段切分才能真实反映模型面对陌生路段的泛化能力。划分比例上第10402期用了78:12:10训练集占大头但验证集尽量贴近真实巡检场景。验证集里刻意混入一些晴天之外的光照情况这样验证指标才更有参考意义。划分完成后还要做一次分布检查统计各类别在训练集和验证集中的数量比例确保没有出现某一类在验证集里只有个位数的极端情况。还有一点YOLO格式的标签文件里类别编号要和classes.txt的顺序严格对应。我以前犯过把crack设为0、pothole设为1结果classes.txt里顺序反了模型训练时类别名和标签序号对不上最后预测输出全是错的排查好久才找到原因。4.3 数据增强的边界数据增强能拉升模型泛化能力但对道路病害这种特殊目标增强尺度需要克制。翻转、旋转、缩放、亮度调整是最安全的基础操作但像马赛克增强、混合增强这类会改变目标语境的增强方式在裂缝检测任务里要慎重使用因为裂缝和坑洞对周边路面纹理的依赖度很高过于激进的混合增强会让模型学到错误的上下文特征。第10402期的增强策略是训练时在线增强只开mosaic_9(轻量版)、随机翻转、随机亮度和色度扰动离线增强则针对坑洞样本做了两次复制粘贴式增强增加小目标的数量。实测下来mosaic开太重确实会出现坑洞被误检成阴影的问题所以后来一直维持轻量增强配置。5. 模型训练验证与问题排查5.1 训练配置要点训练部分我直接选了YOLOv8作为基线模型理由很简单部署方便文档齐全社区生态成熟有问题很容易查到解决方案。输入尺寸设成640这个尺寸对巡检场景来说是速度和精度的均衡点。如果巡检中遇到特别小的裂缝目标可以把输入提升到1280但训练时间和显存占用都会显著增加需要自己权衡。训练轮数设定300轮但实际不用跑满。我习惯监控验证集上的mAP50和mAP50-95曲线当mAP50连续30轮不再上升时就手动早停保存最优权重。第10402期实际在210轮左右停的最终mAP50在0.87左右mAP50-95在0.51左右对于裂缝和坑洞这种外形差异较大的目标来说这个指标已经可以接受。学习率方面用默认的SGD优化器初始学习率0.01weight_decay调到0.0005。如果loss曲线震荡比较厉害可以考虑把batch size减半或者降低初始学习率这个要看显卡实际负载来调。5.2 常见问题与排查技巧实录训练和测试过程中整理过几类高频问题这边直接给一个排查表每一条都是实际踩过坑后的结论。问题现象可能原因排查方向Loss不下降标签框坐标严重错误抽检labels/目录下的txt文件确认坐标落在0到1区间内验证集mAP为0划分时同一路段图片泄漏到训练集和验证集按路段重新划分所有预测框集中在画面中心anchor尺寸设置不当或输入尺寸和训练尺寸不一致检查训练超参里的imgsz和anchors配置坑洞误检率高坑洞样本量不足或增强过度补充坑洞样本调低在线增强强度模型对阴影敏感训练集里缺少不同角度光照的样本增加上午/下午不同时段的素材比例标注框和预测框类别错位classes.txt顺序与标签编号不一致检查classes.txt和所有标签文件的第一列还有一个高频问题训练日志正常但预测时results图显示空白。这通常是类别名称显示问题YOLO预测输出时按索引查类别名如果classes.txt里类别名开头有空格或者换行符显示就会异常肉眼看不出来用文本编辑器打开确认一下就行。5.3 实测验证与迭代路径数据集质量到底行不行最终还是要靠模型实测来打分。第10402期单独预留了一组完全没有参与训练的实拍素材跑了一批测试结果裂缝检出率大概在八成五左右坑洞检出率近九成整体误检率每百帧约2到3次。这个水平对半自动巡检初筛来说已经够用真正到了实际线路巡检只需要人工复核模型标出的可疑区域就行相比纯人眼筛查效率提升是数量级的。迭代路径上下一步我打算加入高速公路路段的素材因为高速路面的纹理均匀、光照条件相对稳定但车速影响下的图像运动模糊和桥梁接缝是新的干扰源。另外还会加入夜间补光素材市政巡检并不只有白天进行这部分对数据集的完整性有实际意义。写在最后的实操体会这个数据集项目做到第10402期我最大的感受就是数据的“脏”和“杂”远比想象中严重采集、标注、清洗这前半程消耗的时间至少占整个项目七成。模型训练本身反而是最省心的一段框架成熟、文档齐全真正决定模型精度的就是数据质量和标注一致性。最后分享一个小技巧在标注完成后可以把所有标签的框尺寸和长宽比做一个统计分布图和模型的预测结果分布放在一起对比。如果训练后模型的预测框尺寸分布和标签统计相差很大基本可以确定是数据划分或者增强策略出了问题这个诊断方法很有效能帮你把问题定位准确率提高不少。项目还会继续做下去每一期的数据都在沉淀成更扎实的巡检样本库后续有机会再专门写写关于模型部署到机载端的小目标检测优化思路。

读完文章,也想定制专属网站?

尧图设计师 24 小时内与您沟通定制方案

免费获取报价 →
↑