简介这份航拍路面病害识别数据集面向从事目标检测与缺陷检测的深度学习开发者、科研人员及学生提供可直接投入训练的标注数据解决路面裂缝与坑槽等病害样本获取难、标注成本高的问题。资源包共约2000个文件以1999个txt标签文件和1个yaml类别配置文件为主压缩包大小约194MBtxt标签对应YOLO格式的边界框标注yaml文件则指定了类别名称与数据路径便于快速接入训练流程。数据集包含3151张航拍图像覆盖Longitudinal crack、Transverse crack、Alligator crack、Oblique crack、Repair、Block crack、Pothole共7个类别并同时提供VOC格式的xml标签兼容YOLO系列、Faster R-CNN、SSD等主流检测模型。图片与标签已预先划分为训练集、验证集和测试集省去手动切分环节可直接用于算法训练与性能评估。目前已有390人学习下载适合需要快速验证模型或开展路面病害检测研究的中高级开发者参考使用。1. 航拍路面病害识别数据集为什么它和普通目标检测数据集不是一回事做道路巡检的团队这两年都在往无人机上迁。理由很直接一条 20 公里的城市主干道人工巡检加拍照归档要一整天无人机飞两个架次、四十分钟就能覆盖还能拿到正射影像。但真正把项目推下去的人很快会撞到同一堵墙——航拍路面病害识别数据集和随手能下到的通用目标检测数据集压根不是一个物种。普通目标检测数据集里一张图里目标占几百像素、背景干净、光照均匀模型随便训训 mAP 就上去了。航拍路面病害完全反过来裂缝在 4000×3000 的原图里可能只有 3 到 8 个像素宽坑槽和阴影、水渍、修补痕迹混在一起同一类病害在不同光照、不同飞行高度下形态差异巨大。你拿 COCO 预训练权重直接 finetune第一轮验证就会看到模型把车道线当成裂缝、把井盖当成坑槽。这篇笔记面向三类人正在做道路巡检自动化、想用无人机影像做病害检测的算法工程师手里已经有一批航拍图但不知道怎么标注和切分的团队以及评估这个方向值不值得投入的技术负责人。我会把数据集的构成逻辑、标注规范、切图策略、训练参数和几个必踩的坑讲清楚让你拿到一批原始航拍图之后能直接开工而不是在数据准备阶段耗掉两个月。2. 航拍路面病害数据集到底长什么样类别、标注与采集边界2.1 病害类别怎么定别照搬公路养护规范公路养护行业有成熟的病害分类标准比如裂缝、坑槽、车辙、沉陷、松散、泛油这几大类往下还能细分横向裂缝、纵向裂缝、网状裂缝。但做数据集时不能直接照搬这套分类原因是标注成本和模型可分性。我一般会把类别收敛到 4 到 6 类按「视觉上可分 养护上可决策」两个标准来切类别视觉特征是否建议单列说明横向裂缝垂直于行车方向线状是与纵向裂缝形态差异大分开训更稳纵向裂缝平行于行车方向线状是常与车道线混淆需重点标注负样本网状裂缝龟裂成块面积状是边界模糊标注框要略大于实际范围坑槽不规则暗色凹陷是与阴影、水渍易混需多光照样本修补规则矩形颜色偏深或偏浅是养护决策上属于已处理但模型必须能识别车辙/沉陷带状变形无明显边界否航拍视角下几乎不可分建议合并或放弃把车辙和沉陷砍掉是血泪经验。这两个类别在正射影像里没有清晰边界标注员之间的一致性极低训出来的模型置信度永远在 0.3 上下晃纯属给评估指标添乱。如果你的养护业务必须要这两类正确做法是走三维重建或者多视角而不是硬塞进二维检测数据集。2.2 标注规范框怎么画、负样本怎么留目标检测标注看似简单航拍场景下有几个必须写进标注手册的规则否则不同标注员产出的框会互相打架。第一条裂缝类用旋转框还是水平框。裂缝是细长目标水平外接框会引入大量背景导致模型学到一堆无关纹理。如果框架支持旋转框比如 mmrotate 那一套优先用旋转框如果只能用水平框那就在切图阶段把图切小让裂缝在局部图里尽量接近水平或垂直减少框内冗余。第二条框的松紧度。坑槽、网状裂缝这类面积目标框要贴紧实际病害边界外扩不超过 5 个像素裂缝类因为太细框宽至少给到 4 到 6 个像素否则标注框本身比目标还窄训练时正样本都采不到。第三条负样本必须显式标注。车道线、井盖、水渍、树影、标线箭头这些是航拍路面检测最主要的误检来源。我一般会单独建一个hard_negative类别或者干脆用空标注图把这几类场景各收集几百张混进训练集。没有负样本的数据集模型上线后误检率能高到你怀疑人生。2.3 采集边界高度、重叠率与光照数据集的质量上限在采集阶段就定了。常见做法是固定飞行高度在 60 到 120 米之间这个区间既能保证裂缝可见又不至于单张图覆盖面积太小。重叠率建议航向 75%、旁向 65% 以上方便后续做正射拼接也方便从同一区域裁出多尺度样本。光照上要刻意制造差异晴天正午、阴天、清晨斜射光各占一定比例。只采晴天正午的数据集模型一到阴天就集体翻车这是航拍检测最典型的玄学问题。如果条件允许同一路段在不同日期各飞一次把时间维度也纳入数据集。3. 从原始航拍图到可训练数据集切图、划分与格式转换3.1 大图切小图滑窗参数怎么设航拍原图动辄 5000×4000 以上直接送进网络要么显存爆掉要么被 resize 到 640 后裂缝彻底消失。标准做法是滑窗切图但窗口大小和重叠率有讲究。import cv2 import os import numpy as np def sliding_window_crop(image_path, save_dir, patch_size1024, overlap200): 对航拍大图做滑窗切图 patch_size: 切图边长建议 1024 或 1280 overlap: 相邻窗口重叠像素建议 patch_size 的 15%~25% img cv2.imread(image_path) h, w img.shape[:2] stride patch_size - overlap base os.path.splitext(os.path.basename(image_path))[0] count 0 for y in range(0, h, stride): for x in range(0, w, stride): # 边界处理保证窗口不越界 x2 min(x patch_size, w) y2 min(y patch_size, h) x1 max(x2 - patch_size, 0) y1 max(y2 - patch_size, 0) patch img[y1:y2, x1:x2] # 过滤掉纯黑或纯白的无效块 if patch.std() 5: continue out_name f{base}_{x1}_{y1}.jpg cv2.imwrite(os.path.join(save_dir, out_name), patch) count 1 return count这段代码的关键在三个参数。patch_size设 1024 是权衡结果太小则单图目标数量少、训练效率低太大则裂缝在 resize 后丢失。overlap设 200 像素是为了保证跨窗口的裂缝不被切断同时给后续 NMS 合并留余地。patch.std() 5这个过滤是防止把纯色区域也切出来那些图对训练毫无贡献还拖慢速度。切图之后标注坐标必须同步做偏移。如果你先标注大图再切图一定要写脚本把标注框按窗口位置平移否则框和图像对不上训练时 loss 直接不收敛。3.2 数据集划分别用随机划分通用数据集习惯用 8:1:1 随机划分但航拍路面数据必须按路段划分。原因很简单同一路段相邻帧的图像高度相似随机划分会让训练集和验证集出现近乎重复的样本验证 mAP 虚高上线后打回原形。正确做法是按飞行架次或路段 ID 分组训练集、验证集、测试集各占不同路段。如果数据量足够再在训练集内部按光照条件分层采样保证每个 batch 里晴天、阴天样本都有。# 按路段前缀分组划分的目录结构示例 dataset/ ├── images/ │ ├── train/ # 路段 A、B、C 的切图 │ ├── val/ # 路段 D 的切图 │ └── test/ # 路段 E 的切图 └── labels/ ├── train/ ├── val/ └── test/3.3 转成 YOLO 格式四个边界坑主流框架里 YOLO 系列的标注格式最省事一行一个目标class_id cx cy w h全部归一化到 0 到 1。转换脚本本身不难坑在边界。def voc_to_yolo(bbox, img_w, img_h): bbox: [xmin, ymin, xmax, ymax] 绝对坐标 返回归一化的 (cx, cy, w, h) xmin, ymin, xmax, ymax bbox # 坑1坐标越界必须裁剪 xmin max(0, min(xmin, img_w - 1)) xmax max(0, min(xmax, img_w - 1)) ymin max(0, min(ymin, img_h - 1)) ymax max(0, min(ymax, img_h - 1)) w xmax - xmin h ymax - ymin # 坑2宽高为0的退化框直接丢弃 if w 0 or h 0: return None cx (xmin xmax) / 2.0 / img_w cy (ymin ymax) / 2.0 / img_h nw w / img_w nh h / img_h # 坑3归一化后仍可能因浮点误差略微越界 cx min(max(cx, 0.0), 1.0) cy min(max(cy, 0.0), 1.0) nw min(max(nw, 0.0), 1.0) nh min(max(nh, 0.0), 1.0) # 坑4极小目标面积占比过低建议过滤否则训练噪声大 if nw * nh 1e-5: return None return cx, cy, nw, nh四个坑分别是坐标越界、退化框、浮点越界和极小目标。其中极小目标过滤要谨慎如果你的业务就是要检测细裂缝阈值不能设太高否则正样本被大量丢弃。我一般会把面积阈值设成可配置项训练前统计一下被过滤的框占比超过 10% 就要回头检查标注质量。4. 训练参数与评估航拍小目标检测的调参重点4.1 输入分辨率与 anchor 设置航拍小目标检测最核心的参数是输入分辨率。YOLOv8 默认 640对裂缝来说远远不够建议直接上 1280 甚至 1536。代价是显存和推理时间翻倍但这是必要投入。如果显存吃紧用梯度累积或者混合精度顶一顶别降分辨率。anchor 方面如果用的是 anchor-based 框架必须重新聚类。COCO 的 anchor 尺寸是为自然图像设计的和航拍裂缝的细长形态完全不匹配。用 k-means 在你的训练集标注上重新聚一遍通常能得到一批又细又长的 anchor召回率会明显改善。anchor-free 框架如 YOLOv8、FCOS省了这一步但要注意正样本分配策略小目标容易被分配到过少的正样本。4.2 数据增强哪些能用哪些会翻车航拍场景下增强要克制。翻转、旋转 90 度、亮度对比度扰动、轻微高斯噪声这些是安全的。但有几类增强会直接破坏语义随机裁剪可能把裂缝裁断标注框和图像对不上慎用。MosaicYOLO 系列默认开但航拍图拼接后会出现不自然的边界模型可能学到拼接缝特征建议降低概率或关闭。透视变换航拍本身已经是俯视再做透视会让病害形态失真不建议。我一般会把 Mosaic 概率降到 0.3 以下同时开启 HSV 扰动来模拟不同光照。如果数据集本身光照多样性够增强可以更保守。4.3 评估指标mAP 之外还要看什么mAP0.5 是标配但航拍路面检测光看这个不够。裂缝这类细长目标IoU 稍微偏一点就掉到 0.5 以下mAP0.5 会低估模型能力。建议同时看 mAP0.5:0.95 和按类别拆分的 AP重点关注坑槽和网状裂缝这两类的表现。更重要的是误检率。养护业务里把正常路面报成病害的代价很高会浪费大量人工复核。评估时单独统计 hard_negative 测试集上的误检数量这个指标比 mAP 更能反映上线后的实际体验。5. 避坑指南航拍路面病害数据集最常见的五个翻车点现象一训练 loss 正常下降但验证 mAP 始终在 0.2 以下。原因通常是标注框和图像不对齐尤其是先标大图后切图的流程坐标偏移没做对。解决方法是随机抽 20 张切图用脚本把标注框画到图上肉眼检查对不上的回头修转换脚本。现象二模型把车道线、标线全部识别成裂缝。原因是训练集里缺少这类负样本模型没见过就默认它们也是病害。解决方法是在标注阶段显式收集车道线、井盖、水渍、树影这几类场景作为负样本或单独类别混入训练集数量至少几百张。现象三同一路段验证集 mAP 很高换一条路就崩。这是随机划分导致的样本泄漏。解决方法是按路段或架次分组划分数据集确保验证集的路段在训练集中完全没出现过。如果数据量不够至少保证同一路段的相邻帧不跨集。现象四模型对细裂缝几乎无响应召回率极低。两个可能原因输入分辨率太低或者 anchor 尺寸不匹配。先把输入提到 1280 以上试一轮如果还不行就重新聚类 anchor。另外检查一下极小目标过滤阈值是不是设太高把真正的细裂缝也滤掉了。现象五推理时同一处病害被重复检测出多个框。滑窗切图带来的边界效应裂缝跨窗口时每个窗口都检出一段。解决方法是在推理后做跨窗口 NMS 合并或者切图时加大重叠率并在合并阶段用 IoU 阈值去重。这个后处理逻辑必须写进推理管线否则输出结果没法用。6. 让数据集真正值钱主动学习与难例回流数据集做完不是终点。航拍路面病害的分布随季节、路段、养护进度一直在变静态数据集训出来的模型半年后就会退化。我现在的习惯是给推理管线加一个难例回流机制模型在线推理时把置信度在 0.3 到 0.6 之间的检测结果自动存下来人工复核后把确认的正样本和误检的负样本一起回流到训练集每季度重训一次。def collect_hard_examples(detections, image, save_dir, low0.3, high0.6): 收集置信度处于灰色区间的检测结果供人工复核 detections: [(cls, conf, x1, y1, x2, y2), ...] for i, (cls, conf, x1, y1, x2, y2) in enumerate(detections): if low conf high: crop image[int(y1):int(y2), int(x1):int(x2)] if crop.size 0: continue # 文件名带上类别和置信度方便复核时排序 name f{cls}_{conf:.2f}_{i}.jpg cv2.imwrite(os.path.join(save_dir, name), crop)这个机制的价值在于它让数据集从一次性产物变成持续迭代的资产。灰色区间的样本信息量最大模型最不确定的地方往往就是数据分布变化最剧烈的地方。坚持回流几个季度你会发现模型在新路段上的冷启动表现明显好于只训一次的版本。另一个值得投入的方向是多尺度训练。航拍飞行高度不固定同一处病害在不同架次里尺度差异很大。训练时随机在 1024 到 1536 之间切换输入尺寸能让模型对尺度变化更鲁棒。代价是训练时间增加但比重新采集多高度数据便宜得多。最后说个我自己的习惯每做完一个版本的数据集我都会留一份冻结测试集只增不改所有模型版本都在它上面跑一遍。这样横向对比才有意义不然每次调完参数换个测试集指标涨了跌了都是玄学。数据集这件事前期多花两周把标注规范和划分逻辑定死后面省下的是两个月的返工。希望帮到你。本文还有配套的精品资源点击获取