首页 / 资讯中心 / 文章详情

航拍路面病害识别数据集:YOLO与Faster R-CNN实战训练指南

航拍路面病害识别数据集:YOLO与Faster R-CNN实战训练指南 ★ FEATURED ARTICLE
简介这是一份面向深度学习目标检测方向的航拍路面病害识别数据集适合从事缺陷检测、智慧交通与道路巡检研究的开发者及学生使用可支撑YOLO系列、Faster R-CNN、SSD等主流模型的训练与验证。数据集共包含3151张航拍图像覆盖纵向裂缝、横向裂缝、龟裂、斜向裂缝、修补、块状裂缝、坑洞共7个类别标注信息完整。压缩包为zip格式内含约2000个文件以1999个txt标签文件和1个yaml类别配置文件为主整体大小约194.08MBtxt标签可直接对接YOLO训练流程yaml文件则用于指定类别名称与路径信息。资源已按训练集、验证集和测试集完成划分同时提供VOC格式的xml标签方便在不同框架间灵活切换。目前已有390人学习下载适合需要快速搭建路面病害检测基线、验证模型效果或开展对比实验的读者直接取用。1. 航拍路面病害识别数据集3151 张图、7 类病害为什么它值得先跑一遍城市道路巡检这几年从人工拍照往无人机倾斜摄影转一个绕不开的卡点就是模型训不出来往往不是网络结构的问题而是手里那批航拍图根本没有像样的标注。我见过太多人拿手机拍的近景裂缝图去训 YOLOmAP 卡在 0.3 上不去最后发现是视角和尺度跟实际部署场景对不上。这份航拍路面病害识别数据集解决的正是这个错位——3151 张航拍视角图片7 个病害类别同时给了 YOLO 的 txt 标签和 VOC 的 xml 标签还预先切好了训练集、验证集、测试集拿到手就能直接喂给 YOLO 系列、Faster R-CNN、SSD 这些主流检测器。适合做道路巡检算法验证的工程师、赶目标检测课程设计的学生以及想拿一个真实缺陷检测场景练手的人。它不解决从零采集的问题但能让你把精力放在模型调优和部署链路上而不是耗在标注上。2. 数据集结构与格式拆解txt、xml、yaml 三件套怎么对上2.1 七个类别与标注体系先把类别清单摆出来这是后面所有配置的基准。数据集共 7 类英文名和常见中文对应如下类别英文名中文含义典型形态Longitudinal crack纵向裂缝沿行车方向延伸的细长裂缝Transverse crack横向裂缝垂直于行车方向的裂缝Alligator crack龟裂网状裂缝多边形状密集裂纹Oblique crack斜向裂缝与行车方向成夹角的裂缝Repair修补人工修补后的矩形/不规则区域Block crack块状裂缝大块分割状裂缝Pothole坑槽局部凹陷破损这 7 类里龟裂和块状裂缝在航拍视角下容易混因为两者都是成片的破损区别在于龟裂是细密网状、块状裂缝是较大块的边界分割。训练时如果这两类 mAP 一直上不去先别急着换模型去验证集里翻一翻标注框大概率是标注边界本身就有歧义。修补类Repair是唯一一个非病害的正样本类别它的存在会让模型学会区分破损和已修复实际巡检里这个区分很有用但也会拉低整体收敛速度因为它的纹理特征和坑槽边缘有重叠。2.2 目录组织与文件命名从项目正文给出的文件名能看出命名规律0156_6_1.txt、0729_4_2.txt、0029_1_7.txt这种格式。拆开看下划线分段第一段是图片编号后面几段是划分标识或类别相关字段。实际拿到数据集后目录结构常见做法是这样组织的dataset/ ├── images/ │ ├── train/ │ ├── val/ │ └── test/ ├── labels/ │ ├── train/ │ ├── val/ │ └── test/ ├── annotations/ # VOC 格式 xml ├── data.yaml └── classes.txt图片和 txt 标签已经按 train/val/test 切好这是最省事的地方。很多人自己切数据集时用随机种子切结果同一段路的相邻帧被分到训练集和验证集验证指标虚高上线就翻车。这份数据既然已经切好直接用它的划分别自己重切。2.3 YOLO txt 与 VOC xml 的字段含义YOLO 的 txt 标签每行格式是class_id x_center y_center width height全部归一化到 0~1。举个例子一张图里有一个坑槽txt 里可能长这样6 0.512 0.634 0.087 0.1126是 Pothole 的类别索引按上面表格顺序从 0 开始后面四个是归一化后的中心点和宽高。注意这里的宽高是相对于整图尺寸的不是像素值所以换分辨率不用改标签。VOC 的 xml 则是绝对像素坐标结构是bndbox里放xmin/ymin/xmax/ymax。两种格式并存的好处是YOLO 系列直接读 txtFaster R-CNN 这类读 VOC 的框架直接读 xml不用来回转。但要注意xml 里的坐标是绝对像素如果图片被 resize 过而 xml 没同步更新框就会偏。我一般会写个校验脚本随机抽 20 张图把 xml 框画出来看一眼确认没偏再开训。2.4 data.yaml 的写法与路径陷阱YOLO 训练靠的是 yaml 配置文件这份数据集里已经给了指定类别信息的 yaml。典型内容长这样path: ./dataset train: images/train val: images/val test: images/test nc: 7 names: 0: Longitudinal crack 1: Transverse crack 2: Alligator crack 3: Oblique crack 4: Repair 5: Block crack 6: Pothole这里最容易踩的坑是path和train的拼接逻辑。Ultralytics 的 YOLOv8/v11 里train如果是相对路径会相对于path解析但如果你写的是绝对路径path就被忽略。我见过有人path写对了、train写成./images/train结果训练时找不到图报No labels found排查半天。稳妥做法是path写数据集根目录的绝对路径train/val/test写相对路径跑之前用一行 Python 确认路径能拼出来。from pathlib import Path import yaml with open(data.yaml, r, encodingutf-8) as f: cfg yaml.safe_load(f) root Path(cfg[path]) for split in [train, val, test]: p root / cfg[split] imgs list(p.glob(*.jpg)) list(p.glob(*.png)) print(split, p, 图片数:, len(imgs))这段脚本的作用是读 yaml、拼路径、统计每个 split 下的图片数量。参数上cfg[path]是根目录cfg[split]是相对子路径glob同时匹配 jpg 和 png 是因为航拍图格式可能不统一。如果某个 split 打印出 0说明路径拼错了或者图片扩展名不在匹配范围里先解决这个再谈训练。3. 用 YOLOv8 跑通训练从环境到第一个 mAP3.1 环境准备与依赖版本训练环境我一般用 conda 隔离避免和系统里的 torch 打架。核心依赖就三个ultralytics、torch、opencv。版本上ultralytics 8.x 对 YOLOv8/v11 都支持torch 选和显卡驱动匹配的 CUDA 版本。conda create -n road-detect python3.10 -y conda activate road-detect pip install ultralytics opencv-python pyyaml # 确认 GPU 可用 python -c import torch; print(torch.cuda.is_available(), torch.cuda.get_device_name(0))torch.cuda.is_available()返回 True 才说明 GPU 能被调用。如果返回 False先查驱动和 CUDA 版本别急着改代码。航拍图分辨率通常不低用 CPU 训 3151 张会慢到怀疑人生GPU 是刚需。3.2 启动训练与关键参数环境好了直接开训。下面这条命令是我跑这类数据集常用的起点yolo detect train \ data./dataset/data.yaml \ modelyolov8s.pt \ epochs100 \ imgsz640 \ batch16 \ lr00.01 \ patience20 \ projectruns/road \ nameexp1逐个说参数。modelyolov8s.pt选 s 而不是 n是因为航拍图里裂缝是细长目标n 的容量偏小容易漏检s 在速度和精度之间比较平衡显存够的话可以上 m。imgsz640是默认值但航拍图如果原图是 2000 像素以上缩到 640 会丢细节裂缝可能只剩几个像素宽这时候要么提到 1024要么先切图。batch16看显存调8G 显存跑 640 一般能到 16跑 1024 就得降到 4 或 8。patience20是早停20 轮验证指标不涨就停省时间。lr00.01是初始学习率YOLOv8 默认就是这个量级别乱改大。3.3 训练日志怎么看开训后终端会刷每个 epoch 的指标重点盯三个box_loss、cls_loss、mAP50。box_loss是边界框回归损失cls_loss是分类损失两个都应该整体下降。如果box_loss降但cls_loss不降说明框的位置学得还行但类别分不开这时候去看是不是龟裂和块状裂缝混了。mAP50是 IoU 阈值 0.5 下的平均精度航拍裂缝这类细长目标能到 0.5 以上就算可用0.7 以上算不错。如果训到 50 轮mAP50还在 0.2 附近晃别硬训回去查标注。3.4 推理验证与结果可视化训完拿测试集跑一遍推理确认模型不是只在验证集上好看yolo detect predict \ modelruns/road/exp1/weights/best.pt \ source./dataset/images/test \ conf0.25 \ saveTrue \ projectruns/road \ namepred_testconf0.25是置信度阈值低于这个的框不输出。裂缝检测里这个值别设太高0.25 到 0.3 比较合适设 0.5 会漏掉很多弱响应的小裂缝。saveTrue会把画了框的图存下来去runs/road/pred_test里翻重点看两类漏检的图里有病害但没框和误检的把路面纹理当裂缝。漏检多就降 conf 或提 imgsz误检多就升 conf 或加负样本。4. 换模型与格式转换Faster R-CNN、SSD 怎么接这份数据4.1 VOC xml 直接喂给 Faster R-CNN这份数据集给了 xmlFaster R-CNN 这类框架可以直接用。以 torchvision 的检测模块为例需要把 xml 解析成target字典包含boxes、labels。常见做法是写个 Dataset 类import torch from torch.utils.data import Dataset from PIL import Image import xml.etree.ElementTree as ET from pathlib import Path CLASSES [Longitudinal crack, Transverse crack, Alligator crack, Oblique crack, Repair, Block crack, Pothole] CLS2ID {c: i 1 for i, c in enumerate(CLASSES)} # 0 留给背景 class RoadDataset(Dataset): def __init__(self, img_dir, xml_dir, transformsNone): self.img_dir Path(img_dir) self.xml_dir Path(xml_dir) self.transforms transforms self.imgs sorted(self.img_dir.glob(*.jpg)) def __getitem__(self, idx): img_path self.imgs[idx] img Image.open(img_path).convert(RGB) xml_path self.xml_dir / (img_path.stem .xml) tree ET.parse(xml_path) boxes, labels [], [] for obj in tree.findall(object): name obj.find(name).text 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) boxes.append([xmin, ymin, xmax, ymax]) labels.append(CLS2ID[name]) target { boxes: torch.tensor(boxes, dtypetorch.float32), labels: torch.tensor(labels, dtypetorch.int64), } if self.transforms: img self.transforms(img) return img, target def __len__(self): return len(self.imgs)逻辑说明CLS2ID从 1 开始编号因为检测框架里 0 通常保留给背景。__getitem__里读图、读对应 xml、遍历object节点抽类别和框坐标。参数上img_dir和xml_dir要指向同一个 split别训练集图片配验证集 xml。transforms里记得加ToTensor否则 img 还是 PIL 对象模型吃不下。4.2 类别索引对齐的坑YOLO 的类别索引从 0 开始VOC 转过来如果也按 0 开始和 YOLO 的 yaml 就对不上。上面代码里CLS2ID从 1 开始是为了适配 torchvision 检测模型如果你要把 VOC 转成 YOLO txt就得从 0 开始。这个差异是血泪经验——我见过有人转完格式直接训模型把所有类都预测成同一类查了两天才发现是索引整体偏移了一位。转换脚本里一定要显式打印类别映射表人工核对一遍。4.3 SSD 的输入尺寸适配SSD 对输入尺寸敏感常见配置是 300x300 或 512x512。航拍图缩到 300 会让小裂缝几乎消失所以用 SSD 的话建议 512 起步并且把 anchor 的尺度调小匹配裂缝的细长形态。SSD 的默认 anchor 比例是 1:1、1:2、2:1 这些对细长裂缝不够贴合可以加 1:5、5:1 这种极端比例。这一步不是必须但做了之后小目标的召回会明显好一些。5. 避坑与排查训练不收敛、mAP 虚高、路径报错5.1 训练 loss 不降mAP 卡在低位现象训了 30 轮box_loss和cls_loss都在 2.0 以上不降mAP50低于 0.1。原因通常是标注格式和配置对不上比如 txt 里坐标没归一化、或者类别索引超出nc范围。解决抽 5 个 txt 文件检查每行是不是 5 个字段、坐标是不是都在 0~1 之间、class_id 是不是小于 7。再确认 data.yaml 里nc: 7和names的键值对完整。这两步能排掉八成的不收敛问题。5.2 验证集 mAP 很高测试集一塌糊涂现象验证集mAP50到 0.8换测试集掉到 0.3。原因多半是数据划分有问题训练集和验证集里有同一段路的相邻帧模型记住了场景而不是病害。解决这份数据集已经切好先确认自己没重切。如果确实要重切按路段或按拍摄批次切别按图片随机切。另外检查验证集和测试集的类别分布如果测试集里某类样本极少那一类的 AP 波动会很大看整体 mAP 时要结合每类 AP 一起看。5.3 报错 No labels found 或路径找不到现象启动训练立刻报No labels found in ...或Dataset not found。原因是 data.yaml 里path和train拼接后指向的目录不存在或者图片和标签目录名不匹配。解决用第 2.4 节那段 Python 脚本打印每个 split 的实际路径和图片数路径不对就改 yaml图片数为 0 就查扩展名。YOLO 默认找images同级的labels目录如果标签放在别处要在 yaml 里显式指定或者用软链接把目录结构对齐。5.4 显存溢出CUDA out of memory现象训练跑几个 batch 后报 OOM。原因是imgsz或batch太大。解决先把batch减半还不行就降imgsz。航拍图如果原图很大可以在数据加载时先缩到目标尺寸再进模型而不是让模型内部缩。另外workers设太大会占额外显存一般设 4 到 8 就够设 16 反而可能拖慢。5.5 龟裂和块状裂缝互相误检现象这两类的混淆矩阵里互相误判比例高。原因是标注边界本身模糊加上航拍视角下纹理接近。解决先抽查 50 张这两类的图看标注框是否一致如果标注没问题训练时对这两类加类别权重或者在数据增强里加随机旋转和缩放让模型学到更鲁棒的特征。实在分不开可以考虑合并成一类网状裂缝看业务上能不能接受。6. 进阶技巧用切片推理把大图小目标召回拉上来航拍图动辄 2000 像素以上直接缩到 640 训练裂缝这种细长目标会丢细节。我后来固定用的一套做法是切片推理SAHI 思路训练时用 640 或 1024推理时把大图切成带重叠的小块每块单独推理再把框映射回原图做 NMS 合并。这样小目标的召回能明显提升代价是推理变慢。具体操作上先装 sahi然后写推理脚本from sahi import AutoDetectionModel from sahi.predict import get_sliced_prediction model AutoDetectionModel.from_pretrained( model_typeyolov8, model_pathruns/road/exp1/weights/best.pt, confidence_threshold0.25, devicecuda:0, ) result get_sliced_prediction( test_big.jpg, model, slice_height640, slice_width640, overlap_height_ratio0.2, overlap_width_ratio0.2, ) result.export_visuals(export_dirsahi_out/)参数上slice_height/width设成和训练imgsz一致模型见过的尺度最稳。overlap_ratio设 0.2 是为了让跨切片的裂缝不被切断重叠太少会在切片边界漏框太多会拖慢速度。confidence_threshold和训练时推理保持一致别这里调高那里调低不然对比不了。验证切片有没有用别只看整体 mAP要单独统计小目标框面积小于 32x32 像素的召回率。我一般会写个脚本按框面积分桶对比切片前后的召回变化。如果小目标召回涨了但大目标掉了说明重叠比例或 NMS 阈值要调。从那以后我每次拿到航拍类数据集都先跑一遍切片推理的基线再决定要不要在训练阶段就切图。这个习惯帮我省了不少训了半天发现方向错了的时间。希望帮到你。本文还有配套的精品资源点击获取
阅读完成 · 觉得有帮助?
咨询建站