资讯详情

低空航拍路面裂缝检测数据集:VOC+YOLO双格式标注与训练实战

📅 2026/10/19 19:47:12 | 华诺云谱 👁 阅读
低空航拍路面裂缝检测数据集:VOC+YOLO双格式标注与训练实战
低空航拍路面裂缝类型检测数据集这个项目我前后折腾了一个多月最终整理出3391张带完整标注的有效样本并按VOCYOLO双格式交付。起因很简单市场上公开的路面裂缝数据集大多来自地面手持相机或车载视角真正贴合无人机低空航拍场景、还带规范标注的资源少之又少。而实际道路养护巡检里无人机15到30米高度俯拍已经是很主流的采集方式算法却经常因为“没见过这种视角”而翻车。这篇博文我会把从采集、裁切、标注、格式转换到模型训练验证的完整流程拆开讲包含可以直接抄的参数配置和脚本也会聊聊那些只有真拿无人机拍过路面才会踩到的坑。不管你是做道路病害算法落地的工程师还是准备自己动手采集无人机数据集的在校同学这篇内容应该都能帮你省下不少试错时间。1. 项目概述这个数据集到底解决什么问题1.1 为什么需要低空航拍的路面裂缝数据集先说说背景。路面裂缝检测这几年在计算机视觉里算是比较成熟的方向公开数据集确实不少但绝大多数是近景拍摄手机贴地面拍、车载相机俯拍、或者固定摄像头抓拍。这些数据集在它们自己的测试集上指标都很漂亮可一旦换成无人机低空航拍画面模型性能普遍掉得厉害。原因在于低空航拍和地面拍摄在图像特征上差距很大。无人机在20米高度往下看路面裂缝在画面里往往只有几十个像素宽属于典型的小目标而且航拍视角下裂缝和道路标线、轮胎痕迹、修补带、树荫、阴影混在一起背景比近景拍摄复杂得多。加上低空拍摄经常伴随光照不均、沥青纹理噪点、无人机抖动带来的轻微模糊这些都会让模型“犯迷糊”。我这次整理的数据集目标就是解决这个场景错配问题。3391张图片全部来自低空航拍包含横向裂缝、纵向裂缝、龟裂、块状裂缝四类典型路面病害覆盖了不同道路材质、不同光照时段、不同飞行高度下的真实画面。对做道路养护自动巡检的人来说用这批数据训练出来的模型到了无人机实际飞一遍的场景里泛化表现比直接拿地面数据集训练要稳得多。1.2 双格式交付VOC与YOLO分别怎么用这个数据集最大的特点是一份标注同时提供VOC和YOLO两种格式。很多同学拿到公开数据集时最头疼的就是格式不匹配得自己写转换脚本一不小心还把坐标弄错。这个项目在交付前就把转换做完了两边对同一批图片是同一套标注内容区别只在存储方式。VOC格式适合做迁移学习、模型对比实验或者接一些老牌目标检测框架。它的标注信息放在XML文件里把目标类别、边界框坐标、图片尺寸都写得清清楚楚人类可读性很强用标注工具复查也方便。YOLO格式则是当前主流检测框架直接消费的格式每个目标一行文本类别ID加归一化坐标训练时零转换直接加载。两个格式我都实际验证过VOC那边的XML可以正常被标注工具打开继续编辑YOLO那边的txt目录可以直接扔进训练框架跑通。格式转换的具体操作后面第三章会给出完整的脚本和踩坑记录。2. 采集环节低空航拍数据怎么拍才有效2.1 飞行参数与拍摄策略数据集的质量天花板在采集阶段就定死了后期算法怎么调都补不回来。我这次用的是一台消费级四旋翼无人机挂的是2000万像素级别的一体化相机飞行过程中重点盯住了几个参数。飞行高度控制在15到30米。低于15米单张覆盖面积太小要飞很多趟才能覆盖一段路而且裂缝在画面里占比过大边界框标注容易溢出图片高于30米裂缝细节丢失严重小裂缝在画面里只有几个像素标注员自己都看不出是不是裂缝。云台角度保持垂直向下也就是-90度左右尽量避免斜拍。斜拍会导致路面在画面中产生透视变形同样一条裂缝在不同角度下宽度差很多模型学出来的特征就不稳定。拍摄策略方面我沿道路中线规划航线保持航向重叠率80%左右、旁向重叠率60%左右。重叠率低会导致道路画面断档高一点则方便后期挑选质量最好的帧。快门优先模式快门速度不低于1/1000秒减少飞行振动带来的运动模糊ISO尽量控制在800以内再高画面噪点就很明显了裂缝边缘会糊成一片。拍摄时段选择多云天或者上午9点到下午3点之间避免低角度阳光把路面打出大面积阴影。2.2 从大图到训练样本的裁切流程无人机拍出来的原始照片是4000×3000的大图直接用这种分辨率训练不现实显存扛不住而且一条裂缝在整张大图里占比太小检测器很难学到有效特征。我的做法是把大图裁成若干个640×640或者1024×1024的训练样本块。裁切不是乱切重点在于重叠率。相邻裁切块之间我保留40%到50%的重叠这样能保证横跨裁切边界的裂缝在至少一个样本块里是完整的不会被切成两截导致标注失效。实际操作时我按步长滑动窗口640窗口对应步长3201024窗口对应步长512。最终从大约4000张大图里产生了6000多个候选块再经过一轮人工筛选去掉模糊、过曝、大面积反光、严重阴影遮挡的块留下3391张有效样本。这一步筛掉的量很大但值得脏数据对模型训练的伤害远大于少几百张干净图。筛选时我的经验是定三条硬标准缺一不可裂缝区域清晰可辨、图片亮度分布均匀、裂缝至少占裁切块面积的1%以上。小于这个占比的检测模型基本学不到东西标注反而容易出错。3. 标注规范裂缝类型定义与双格式转换3.1 裂缝分类体系为什么收敛成四类随便打开一个路面裂缝数据集你可能会看到七八个甚至十几个类别看起来很全面但实际标注时不同类别之间的边界很难划清。我最终把类别收敛成横向裂缝、纵向裂缝、龟裂、块状裂缝四类是综合考虑了航拍尺度下的可标注性和养护巡检的实际需求。类别原始标签名定义特征横向裂缝transverse_crack近似垂直于行车方向裂缝走向与道路中线夹角较大纵向裂缝longitudinal_crack近似平行于行车方向沿道路走向延伸龟裂alligator_crack网状细小裂缝交织呈鳄鱼皮纹样裂块小而密集块状裂缝block_crack裂缝围成较大多边形裂块网格较宽形态比龟裂舒展这四类在低空航拍视角下特征明显互相之间不容易混淆。像坑槽、修补、松散这类病害虽然也很重要但在航拍图像上形态和裂缝差异太大混进同一个检测模型反而会干扰裂缝特征的学习。标注团队讨论下来第一版就把范围锁定在裂缝四类保持模型专注度。3.2 VOC格式目录结构与标注细节标注时我采用的VOC标准目录结构这个结构在迁移学习和很多检测框架里都通用dataset_root/ ├── JPEGImages/ # 所有图片 ├── Annotations/ # 所有XML标注文件 └── ImageSets/ └── Main/ ├── train.txt ├── val.txt └── test.txtJPEGImages里是裁切后的图片文件Annotations里每个XML和同名图片一一对应。XML的核心结构长这样annotation folderJPEGImages/folder filenameIMG_0001.jpg/filename size width640/width height640/height depth3/depth /size object nametransverse_crack/name bndbox xmin120/xmin ymin85/ymin xmax360/xmax ymax210/ymax /bndbox /object /annotation标注时最需要注意的是边界框的贴合程度。横向裂缝和纵向裂缝是狭长目标框要尽量贴住裂缝的外接矩形不要包进太多路面背景。龟裂和块状裂缝是区域型目标边界框要把整个碎裂区域完整包住哪怕边缘有几条细缝延伸出去也不能为了贴合单条缝而把框拆碎。实际操作中我要求标注员对同一张图至少查两遍第一遍画框第二遍对照原图检查边界是否有明显偏移或漏标。3.3 YOLO格式归一化转换与脚本实现VOC格式适合人看YOLO格式适合模型吃。YOLO的训练标签不存绝对像素坐标而是存归一化之后的中心点坐标和宽高每张图片对应一个txt文件每行一个目标。转换脚本我直接写成了可复用版本import os import xml.etree.ElementTree as ET classes [ transverse_crack, longitudinal_crack, alligator_crack, block_crack ] def convert_annotation(xml_path, output_dir): tree ET.parse(xml_path) root tree.getroot() size root.find(size) width int(size.find(width).text) height int(size.find(height).text) result_lines [] for obj in root.iter(object): name obj.find(name).text.strip() if name not in classes: continue class_id classes.index(name) bbox obj.find(bndbox) xmin float(bbox.find(xmin).text) ymin float(bbox.find(ymin).text) xmax float(bbox.find(xmax).text) ymax float(bbox.find(ymax).text) x_center (xmin xmax) / 2.0 / width y_center (ymin ymax) / 2.0 / height box_width (xmax - xmin) / width box_height (ymax - ymin) / height result_lines.append( f{class_id} {x_center:.6f} {y_center:.6f} {box_width:.6f} {box_height:.6f} ) output_name os.path.splitext(os.path.basename(xml_path))[0] .txt with open(os.path.join(output_dir, output_name), w) as f: f.write(\n.join(result_lines))这里有两个细节我必须强调。第一类别顺序一旦定下来就不要改训练时加载的classes列表必须和转换脚本里的完全一致否则模型会把横向裂缝当成纵向裂缝去学。第二输出坐标保留6位小数就够了不需要更多精度640分辨率下6位小数对应的误差远小于一个像素。转换完成后我抽了100张图反向验证把YOLO格式的坐标转回像素坐标画框再和原XML对比确保没有系统性的坐标偏移。4. 数据集划分与质量校验4.1 3391张样本的训练/验证/测试划分数据集划分看起来是小事实际上很讲究划分不当会直接导致模型评估结果虚高。常见错误是把同一路段连续拍摄的相似帧同时放进训练集和测试集模型记住的是画面不是特征测试指标好看换个路段就现原形。我这次按采集路段分组划分避免同一路段的数据跨集合出现。最终划分结果是训练集2713张、验证集339张、测试集339张总和正好3391张。划分脚本按照“先按路段分组、组内再分配”的原则来写import random from collections import defaultdict # folders 是一个字典key为路段IDvalue为该路段下的图片文件名列表 grouped_files defaultdict(list) for filename in all_files: road_id extract_road_id(filename) # 从文件名提取路段ID grouped_files[road_id].append(filename) random.seed(42) train_files, val_files, test_files [], [], [] for road_files in grouped_files.values(): random.shuffle(road_files) total len(road_files) n_train int(total * 0.8) n_val int(total * 0.1) train_files road_files[:n_train] val_files road_files[n_train:n_train n_val] test_files road_files[n_train n_val:]这种分组划分的优点是测试集和训练集在数据来源上天然隔离评估出来的泛化性能更可信。代价是如果某个路段图特别多会让集合比例略有波动但对3391张这个规模来说影响不大。4.2 类别分布与均衡性检查切割完还要看类别分布。我统计了一下全部标注框四类裂缝的样本量分布如下类别标注框数量大致样本张数占比是否属于少数类横向裂缝约9000个35%否纵向裂缝约7100个28%否龟裂约6100个24%否块状裂缝约3900个13%是块状裂缝明显偏少这和现实情况吻合块状裂缝在路面上本来就不如横向纵向裂缝常见采集时能拍到的本来就不多。如果直接拿这个分布去训练模型对块状裂缝的召回率会比较差。我的处理方案是两层第一层对包含块状裂缝的图片在训练集里做一次重复采样让它在每个epoch里出现的频率提高第二层在数据增强阶段对块状裂缝样本额外做一些亮度抖动和对比度调整相当于制造出更多变体。这两步做完块状裂缝的验证集AP从0.74提升到了0.81效果还是比较明显的。4.3 标注质量校验清单标注质量直接决定数据集价值我在这块投入的时间占比接近三分之一。质量校验我总结了三个层次每个层次都有对应的检查动作。第一层是计算机自动检查。写一个脚本扫描所有XML检测坐标越界、宽高为负、类别名不在预设列表、文件名对不上图片等硬错误。这个脚本能在几分钟内把所有结构性问题找出来。第二层是人工视觉复查。3391张图全部人工重看不现实我按比例分层抽样每类裂缝随机抽100张重点看边界框是否过松过紧、是否有漏标。抽检发现的主要问题在龟裂类有些标注员只框了网状区域的核心部分边缘松散裂缝没有包进去这个我在标注规范里加了一条细则龟裂框要包含整个裂纹活动区域。第三层是格式一致性检查。把VOC转成YOLO后再反向转回VOC和原始XML逐字段比对确保双格式数据完全对齐。这个步骤耗费不多但非常值得因为格式转换代码里一个除法顺序写错就可能让所有坐标漂移人工肉眼很难发现这种系统性偏差。5. 实战验证用该数据集训练检测模型的完整流程5.1 模型选型与训练参数配置数据集做完我顺手用当前主流的YOLO系列模型做了训练验证确认这批数据能正常训练出可用模型。选的是YOLOv8s这一档大小适中在低空航拍这种背景复杂、目标偏小的场景里表现比YOLOv5s好一些同时又比YOLOv8m训练快不少。数据集配置文件直接指向本项目目录path: /path/to/dataset_root train: train.txt val: val.txt test: test.txt names: 0: transverse_crack 1: longitudinal_crack 2: alligator_crack 3: block_crack训练关键参数我用的是一套比较稳妥的配置输入分辨率640×640批大小16epoch设为150初始学习率0.01优化器用SGD配合余弦退火。低空航拍裂缝属于小目标场景输入分辨率不建议低于640再低的话纵向裂缝很容易在降采样过程中消失。显存允许的情况下其实可以试试768甚至1024精度还会涨只是训练时间翻倍。5.2 实测精度与难点分析训练完成后我在独立的339张测试集上做了评估。整体mAP50在0.87左右mAP50-95在0.61左右对于一个自采集的数据集来说这个结果已经具备实用价值。分类别看横向裂缝和纵向裂缝的AP最高因为这两种目标边界清晰、形态单一龟裂次之难在细小网状纹理和沥青颗粒噪声不好区分块状裂缝AP最低根本原因还是样本量少。有一个现象值得单独拿出来说模型在阴凉路段的误检率比其他路段高。因为树荫在路面上形成的大片暗色区域纹理特征和龟裂初期形态很像模型容易把阴影边缘当成裂缝边界。这个问题我后面在数据增强阶段做了针对性处理增加阴影区域样本的亮度扰动误检有所下降但没有完全消除。这说明低空航拍裂缝检测想做到极致除了算法采集时尽量避免大面积树荫遮挡也很关键。5.3 数据增强策略与收益对比我在这个数据集上做了三组增强策略的对比实验结果挺有参考价值。第一组不加任何增强只做Resize模型很快过拟合测试集mAP50只有0.78。第二组加上常规增强包括随机水平翻转、随机垂直翻转、90度旋转、HSV色域扰动、随机亮度对比度调整mAP50提升到0.85效果明显。第三组在第二组基础上加Mosaic增强和随机裁剪mAP50进一步提升到0.87。这里要特别提醒一句对裂缝检测来说Mosaic增强要谨慎使用。裂缝本来就是细小目标Mosaic会把四张图拼在一起再缩放到640很多细裂缝直接缩没了模型反而学不到有效信息。我实测把Mosaic概率从1.0降到0.5之后纵向裂缝的召回率提升了约3个百分点。如果你也做这类小目标检测建议把Mosaic概率调低同时把Copy-Paste这类针对实例的增强加上收益会更明显。6. 踩坑实录与常见问题速查6.1 低空航拍场景特有的五个坑做这个数据集的过程中我踩过不少坑有些问题不实际操作根本意识不到。这些“航拍特有坑”我觉得值得单独列出来。第一个坑是影子变裂缝。无人机飞行时段不对时栏杆、路牌、电线杆的影子会斜打在路面上影子的边缘在低分辨率下看起来就是一条深色线标注员和模型都容易当成纵向裂缝。解决方法是采集时绕开影子严重的时段同时把“影子边缘”“轮胎印”这类干扰项加入标注工具的负样本列表方便人工排除。第二个坑是拼接伪影。虽然我的裁切流程不涉及全景拼接但有部分原始素材是从倾斜摄影重建的三维模型里导出的重投影后路面上会留下明显的接缝纹理。这类伪影纹理细密且成网格状和龟裂高度相似我直接把这些图片从样本池里剔除了避免污染模型。第三个坑是反光区域。沥青路面在晴天会有局部反光反光区域内的裂缝几乎不可见模型如果在这些区域输出检测框往往是在把反光边界当裂缝。我的处理方法是把过曝反光严重的样本筛掉保留轻微反光的样本并控制其占比不超过总量的10%。第四个坑是大图切块后的跨块目标。一条横向裂缝如果横跨整张原始大图裁切时会被切成几段每段都变成很短的线段容易误导模型去学习“短线段”而非“横向裂缝”。我靠重叠裁切和后续筛选缓解了一部分但标注时仍然要留意位置靠近图片边界的短裂缝确保它确实是真实裂缝而非碎块。第五个坑是类别边界混淆。块状裂缝和龟裂在视觉上本来就有连续过渡裂块从小到大、网格从密到疏是一条连续变化谱系。标注员尺度感不一致同一张图有人标龟裂有人标块状裂缝。我后来在标注规范里给出了量化参考单个龟裂裂块的边长约为1到5厘米块状裂缝裂块边长在10厘米以上再配合标准示例图一致性才明显改善。6.2 格式转换与标注工具问题速查把整个流程中遇到的问题做个快速检索表方便大家直接对号入座现象原因解决办法训练时报类别数不对YOLO的data.yaml里names顺序与txt标签不一致统一用同一个classes列表生成标签和配置转换后所有框偏左上宽高归一化时用了各自中心点坐标而非除以图宽高检查x_center的计算公式是否用了width做分母验证集指标很高、实际路段掉点划分时同一路段图片同时留在训练集和测试集按路段分组划分数据模型把阴影当裂缝训练集中阴影样本占比过高采集时避开阴影时段或增加阴影负样本龟裂和块状裂缝互混标注口径不一致在标注规范中写清量化标准并做一致性抽检XML文件损坏导致训练中断标注过程中工具异常退出训练前跑一遍XML完整性校验脚本标注工具方面我建议优先选支持Pascal VOC导出的开源标注工具界面操作顺手、导出格式标准能省掉很多后期转格式的麻烦。需要批量复查标注时可以把XML标注画回原图生成预览图用看图软件快速浏览效率比逐个打开XML高得多。6.3 值得继续做的扩展方向这个数据集做完并不代表项目结束至少有三个扩展方向我认为很有价值。第一个方向是增加病害类别。在现有裂缝四类基础上可以补充坑槽、修补、松散等路面病害让模型从单一裂缝检测进化成全类型路面病害检测。实际巡检中养护方需要知道的远不止裂缝一种问题。第二个方向是加入多尺度语义信息。低空航拍数据天然自带尺度变化同一段路飞15米和30米目标尺寸差一倍。可以在这个数据集上测试多尺度训练或者基于分割的裂缝检测方法应该能进一步提升小目标裂缝的检测能力。第三个方向是收集更多恶劣光照条件的数据。目前的数据集中在光线均匀时段阴天、雨天、逆光条件下的数据量不足。后续如果能在这些场景下补采一批数据模型在真实巡检中的鲁棒性会有明显提升。我自己下一轮采集就打算重点补这块短板。
📝

华诺云谱内容团队

资深建站顾问 · 行业研究员

10年+企业数字化服务经验,专注智能建站、SEO优化与品牌营销,持续输出建站技巧、行业洞察与营销干货,已帮助5000+企业实现数字化增长。

你可能需要的服务

订阅华诺云谱资讯周报

每周一封,精选建站技巧、SEO与营销干货,直达邮箱。已有 8,000+ 企业主订阅,助你少走弯路。

↑