
简介这是一份面向桥梁缺陷检测任务的YOLO格式目标检测数据集适合计算机视觉方向的初学者、算法工程师以及桥梁健康监测项目相关开发者使用。数据集中标注了腐蚀、裂纹、白石灰、泄漏、剥落五类典型桥梁缺陷并已按YOLO标准格式划分出训练集与验证集可直接接入YOLOv5、YOLOv8等主流模型开展训练。压缩包内共包含两千个文件其中有一千九百九十九个文本标签文件和一个可视化脚本资源包整体大小约为一百二十三点三七兆字节。文本标签中记录着每一张图像对应的缺陷框坐标及类别信息可视化脚本则能够快捷地把标注框绘制在原始图像上便于使用者直观检查标注质量。截至目前已有四百一十八人学习下载这份资源。它既可以作为桥梁缺陷自动识别研究的起步数据也可用于模型精度调优、算法对比验证等实际环节文件结构清晰并附带类别定义文件部署门槛低下载后即可直接开始相关训练实验。1. 桥梁缺陷检测数据集先搞懂要检测什么再谈模型做桥梁缺陷检测的人多半是拿着无人机或桥检车拍回来的照片想用目标检测模型自动找出裂缝、剥落、露筋这些病害。但很多人第一步就卡在“没有数据”网上公开的桥梁缺陷数据集少类别杂标注质量残次不齐直接拿COCO预训练模型去跑检测出来的全是人、车、交通标志跟缺陷毫无关系。这篇笔记要解决的就是这个痛点在没有现成数据的情况下怎么从零构建一份能用来训练YOLO系列模型的桥梁缺陷检测数据集以及把数据集喂给模型后有哪些参数值得调、哪些坑不值得踩。适合正在做桥梁检测项目、需要落地目标检测方案的一线工程师和研究生。2. 桥梁缺陷检测数据集的构成缺陷类别、标注规范与成像条件2.1 缺陷类别裂缝、剥落、露筋、渗水别只标一种桥梁缺陷检测不是“找出所有损坏的东西”那么简单。检测目标必须提前定死否则标注员会自由发挥把锈迹、污渍、青苔全标成缺陷模型学出来就是一团浆糊。常见做法是把缺陷分成四到六个类别每类再定义清楚“什么算、什么不算”。我一般建议最小集是四类裂缝crack、剥落spalling、露筋exposed rebar、渗水water seepage。如果需要更细可以加“蜂窝麻面”honeycomb和“锈蚀”rust stain。但这六个类别已经足够让数据标注成本可控。定义规则要落到文字上比如裂缝宽度大于0.1mm、长度在图像上至少占20个像素、并且是线状延伸的才算剥落混凝土表面成块掉落能看到凹坑或骨料外露露筋钢筋外露且周围混凝土已经缺失或严重开裂。这些规则写进标注规范比让标注员自己理解省心得多。一个常见误区是只标裂缝。很多论文和演示项目把裂缝当成唯一目标因为裂缝最多、最好标。但实际桥梁检测要交付的是“全病害清单”只做裂缝一个类别剥落和露筋全漏了现场复核时会被业主追着问。所以数据集的类别粒度必须跟着检测需求走而不是跟着标注难度走。2.2 标注格式选型VOC还是COCOYOLO系列怎么接桥梁缺陷检测现在用得最多的是YOLO系列因为它推理快、部署方便适合无人机巡检测完之后回机房批量跑。YOLO的训练接口一般吃两种格式一是YOLO自己的txt格式每张图对应一个txt每行是class_id x_center y_center width height二是COCO JSON格式。而标注工具普遍输出VOC XML格式所以转换是绕不开的一步。选VOC还是COCO取决于你后面要不要做实例分割。做纯矩形框目标检测VOC XML足够转换脚本简单如果打算以后升级到Mask R-CNN或者YOLOv8-seg做裂缝轮廓分割那直接标COCO多边形会少一次返工。我的建议是第一版数据集用矩形框VOC格式起步因为桥梁缺陷大多数是紧凑区域矩形框浪费不多标注速度快一倍。等检测框稳了再针对裂缝单独补一份多边形分割数据。对YOLO来说txt格式最省事但有个缺点类别名和类别id的映射在训练配置里定义txt文件本身不含类别名。如果你同时跑YOLOv5和YOLOv8不同版本的类别顺序定义可能不一致就会出现“训练时第0类是裂缝推理时第0类成了剥落”的翻车现场。所以项目里最好固定一份classes.txt所有转换脚本、训练配置都从这份文件读取不要手写。2.3 成像条件无人机、桥检车、手机补拍光照和角度怎么统一桥梁缺陷数据集最麻烦的不是标注而是图像来源五花八门。无人机拍的是俯视视角桥梁底面裂缝在阴影里桥检车贴近拍的是正视视角分辨率高但视野窄手机补拍有时是斜视角。如果这些图混在一起训练模型会学到“角度”和“光照”的偏见而不是缺陷本身。解决办法是主动记录每张图的采集方式并在划分训练集和验证集时按“采集批次”而不是按“图像随机”划分。举例来说无人机一个架次的1000张图可能来自同一段桥面如果随机切训练集和验证集里都出现同一区域的图验证分数会虚高到现场换一座桥就崩。正确做法是按拍摄时间或拍摄路段分组一个组的图整体进训练集或整体进验证集避免数据泄漏。另外光照条件不能只靠调色。桥梁底面裂缝在逆光下几乎看不见这时候应该补拍而不是强行做亮度增强。现场采集时我习惯让飞手对疑似病害区域从两个角度各拍一张一张直射光、一张侧光。侧光能让裂缝阴影更明显对训练和现场复核都有用。3. 从零构建桥梁缺陷数据集采集、清洗与标注的落地流程3.1 采集方案最少拍多少张覆盖哪些部位目标是训练一个能用的检测模型不是发论文刷榜所以数量不用追求“上万张”。我的经验是每个类别最少300个标注实例四类加起来1200到1500个实例一张图里可能同时有多个缺陷所以对应图像数量在800到1000张左右。这个量级够YOLOv8从预训练权重微调出能上场的模型。如果类别多或者场景复杂再加到每类500个实例。采集部位要按桥梁结构拆桥面系铺装裂缝、伸缩缝破损、上部结构梁底裂缝、腹板剥落、翼缘露筋、下部结构墩身渗水、盖梁剥落、基础冲刷。每个部位至少拍50张否则模型容易只认某一段桥的特征。另一个容易被忽略的是背景多样性同一类裂缝在混凝土表面、涂层表面、有青苔的表面、有水渍的表面视觉差异很大。每个背景类型至少要有20张。拍摄分辨率有讲究。无人机相机一般2000万像素以上但一块几百像素的裂缝区域在整张图里可能只占1%。训练时YOLO会把图缩放到640×640小裂缝直接被压没了。所以对原始大图要做切片tiling把一张4000×3000的图切成若干张1024×1024的块缺陷所在的块单独留下做标注空白块可以删掉。切片后再标注框的相对尺寸会大很多模型学起来更轻松。3.2 用LabelImg做矩形框标注最小操作与快捷键LabelImg是最常见的VOC标注工具单机可用支持预定义类别。装好之后先把类别写进classes.txt然后用快捷键标注W画框A/D切换上一张下一张CtrlS保存Space标记已验证。标注时要按缺陷的实际轮廓画尽量贴边不要留大块背景。# 安装LabelImgPython 3 Qt5 pip install labelImg # 启动前预定义类别 # 编辑 data/predefined_classes.txt每行一个类别名 crack spalling exposed_rebar water_seepage # 打开标注界面默认输出VOC XML到指定目录 labelImg images/ annotations/ --labels data/predefined_classes.txt这里有个参数说明--labels指定预定义类别文件后画框时弹出的类别列表就是固定的不会出现标完发现类别名打错的低级问题。输出格式默认PascalVOC如果你想要YOLO格式启动时加--yolo可以直接生成txt但我不推荐一上来就用YOLO格式因为XML里带有图像尺寸、类别名、坐标绝对值后面做清洗和过滤更方便。标注的边界框有个实操技巧裂缝通常是长条形的画框时别画得太宽否则多个裂缝重叠后框之间IoU高后处理NMS会误删。推荐让框的长边方向跟裂缝主方向一致宁可窄一点。剥落和露筋形状不规则框稍微留2到3个像素的余量即可别为了省时间把整个大区域圈进去。3.3 数据增强Mosaic、混合复制粘贴哪些对桥梁缺陷有效数据增强不是越多越好。桥梁缺陷检测的场景特殊性在于缺陷是局部小目标且大多在混凝土纹理背景上。通用目标检测常用的随机翻转、缩放、颜色抖动都有效但有一类增强要慎用——随机擦除Random Erase。如果擦除的区域恰好覆盖裂缝主体模型会被逼着学“看到混凝土纹理就预测裂缝”反而增加误检。YOLOv8默认开的Mosaic增强把4张图拼成一张对桥梁缺陷有效因为它强行让模型在多个尺度上学习缺陷特征同时增加了背景多样性。训练时mosaic参数一般设在0.5到1.0之间我通常用0.8。另外copy-paste增强把一张图里的缺陷框复制到另一张图的随机位置也很适合桥梁场景因为桥梁背景干净、缺陷位置可重复复制后视觉上不违和。# 用albumentations做在线增强的配置片段 import albumentations as A transform A.Compose([ A.RandomBrightnessContrast(p0.5), A.HueSaturationValue(hue_shift_limit10, sat_shift_limit20, val_shift_limit10, p0.3), A.Rotate(limit15, border_mode0, p0.5), A.RandomSizedBBoxSafeCrop(width640, height640, erosion_rate0.2, p0.8), ], bbox_paramsA.BboxParams(formatyolo, label_fields[class_labels]))这段代码里的RandomSizedBBoxSafeCrop是专门为检测设计的它会随机裁剪一个带标注框的区域到指定尺寸但保证裁剪后所有框不被截断。这比直接resize更能保留小裂缝的原始像素。border_mode0表示旋转时超出边界的区域填黑不会引入彩色噪声。如果你用的是YOLO自带的增强记得把translate控制在0.1以内平移太多会让框跑到图像外产生大量空标注。4. 把数据集喂给YOLO系列格式转换、训练配置与参数调优4.1 VOC转YOLO的转换脚本XML到TXT的边界坑标完的VOC XML要转成YOLO txt才能训练。转换脚本网上很多但容易在四个边界坑上翻车一是坐标系归一化时没有除以图像宽高二是类名和id映射错位三是多个对象共用一个框比如裂缝和渗水叠在一起四是XML里有损坏文件导致ElementTree解析崩溃。下面是我经常用的转换脚本带异常处理import os import xml.etree.ElementTree as ET from glob import glob CLASSES {crack: 0, spalling: 1, exposed_rebar: 2, water_seepage: 3} def convert_xml_to_yolo(xml_path, out_dir): tree ET.parse(xml_path) root tree.getroot() img_w int(root.find(size/width).text) img_h int(root.find(size/height).text) if img_w 0 or img_h 0: print(f跳过 {xml_path}: 图像尺寸为0) return txt_name os.path.basename(xml_path).replace(.xml, .txt) txt_path os.path.join(out_dir, txt_name) lines [] for obj in root.iter(object): name obj.find(name).text if name not in CLASSES: print(f未知类别 {name} 在 {xml_path}, 跳过) continue box obj.find(bndbox) x1 float(box.find(xmin).text) y1 float(box.find(ymin).text) x2 float(box.find(xmax).text) y2 float(box.find(ymax).text) # 过滤无效框 if x2 x1 or y2 y1: print(f无效框在 {xml_path}, 跳过) continue x_center (x1 x2) / 2 / img_w y_center (y1 y2) / 2 / img_h w (x2 - x1) / img_w h (y2 - y1) / img_h # 裁剪到[0,1]范围防止越界 x_center min(max(x_center, 0), 1) y_center min(max(y_center, 0), 1) w min(w, 1) h min(h, 1) lines.append(f{CLASSES[name]} {x_center:.6f} {y_center:.6f} {w:.6f} {h:.6f}) with open(txt_path, w) as f: f.write(\n.join(lines)) # 批量转换 xml_files glob(annotations/*.xml) os.makedirs(yolo_labels, exist_okTrue) for xml_file in xml_files: convert_xml_to_yolo(xml_file, yolo_labels) print(f转换完成共处理 {len(xml_files)} 个XML)这段逻辑里值得说明的是那个“裁剪到[0,1]”的操作。有些标注员会把框画出图像边界如果不做裁剪YOLO训练时会出现AssertionError: bbox must be in [0,1]然后整个训练中断。另外text获取尺寸字段时是字符串必须转float很多新手忘掉这一行导致除零报错。如果你用OpenCV读图来获取尺寸记得图片路径和XML文件名要一一对应别用全大写后缀和全小写后缀混着来。4.2 训练配置batch size、学习率、anchor怎么设以YOLOv8为例训练命令看似简单但参数要按数据集规模调整。桥梁缺陷数据集一般只有几百到一千张图属于小数据集微调不能照搬COCO的默认超参。yolo train \ modelyolov8s.pt \ databridge_defect.yaml \ epochs200 \ imgsz640 \ batch16 \ lr00.01 \ lrf0.01 \ mosaic0.8 \ patience30 \ cacheTrue参数说明batch16在2080Ti级别显卡上够用如果显存只有8GB改成batch8并同时减小imgsz到480。lr00.01是默认值但对小数据集来说偏高我一般设lr00.005避免前几十个epoch就发散。patience30是早停轮数模型连续30个epoch没提升就停省时间。cacheTrue可以把图像提前加载到内存训练速度快一倍前提是内存够。anchor这块要单独说。YOLOv5和YOLOv8在训练时会自动从你的标注框里重新聚类anchor所以你不需要手工设定anchor大小。但聚类结果是基于你当前训练集算出来的如果验证集里出现训练集没有的极宽极窄框比如一条横向贯穿整个桥面的裂缝推理时按聚类的anchor去预测召回率会下降。做法是训练完成后用yolo val的PR曲线看局部召回如果发现宽度大的目标漏检可以考虑把anchor_tanchor与真实框的宽高比阈值从默认4调大到6允许模型预测更极端的宽高比。databridge_defect.yaml的内容如下path: ./bridge_defect train: images/train val: images/val names: 0: crack 1: spalling 2: exposed_rebar 3: water_seepage注意names必须和转换脚本里的CLASSES一致。如果哪个框的类别id写错了训练不报错但推理时标签全错。4.3 模型选型YOLOv8、YOLOv11还是DETR小目标怎么权衡桥梁缺陷检测的小目标问题很突出一条0.5mm宽的裂缝在无人机50米高度拍摄的照片里只占几个像素。模型选型时先看计算资源和对延迟的要求。如果跑全桥视频流检测需要实时性YOLOv8n或YOLOv8s就够了配合切片后推理单帧耗时能压在30ms以内。如果只做照片批量筛查不在乎延迟YOLOv8m甚至YOLOv8l召回率更高对小目标更友好。YOLOv11系列比v8在骨干网络上做了改动推理速度略快精度也不错但我个人在缺陷检测上没看到质的飞跃选v8还是v11看你团队熟悉哪个。DETR这类Transformer检测器在通用目标上很强但小目标需要更大的训练数据桥梁缺陷这种千张级数据集容易过拟合不推荐第一版就上。如果非要提升小目标检测有两个更实际的招。一是把训练图分辨率从640提到960或1280代价是显存和训练时间暴涨但对裂缝这种极细目标分辨率比模型参数量更重要。二是用SAHI切片辅助推理库对推理图做切片再拼接预测结果。SAHI在无人机和遥感场景验证很多桥梁检测同样是“大图、稀疏小目标”直接套用能显著提高召回。缺点是后处理逻辑复杂每张图有几十个切片漏检的错检交织在一起需要写额外的NMS逻辑。5. 桥梁缺陷检测的避坑与常见问题标注不一致、过拟合、漏检5.1 缺陷边界判定不一致同一条缝两个标注框差一倍现象训练集和验证集的mAP很高但现场测试时同一张图两次推理框大小抖动明显。原因标注员对裂缝起止点判定不统一。有人把裂缝从起点到终点整个拉一条框有人只框明显断裂段造成同类目标宽高比分布极广模型学到的“裂缝”概念是模糊的。解决标注规范里写死“框必须包含裂缝可见的全部连续区域但不包含延伸的隐约痕迹”。同时做一个双人标注交叉校验随机抽10%的图像让两个人独立标计算每个框中心点距离和长边IoU偏差大于15%的打回重标。这个校验成本不高但能稳定提升数据质量。5.2 数据类别极度不均衡裂缝占80%剥落只有几十张现象训练完的模型对裂缝很灵敏对剥落完全无感即使剥落面积很大也漏检。原因采集时桥梁表面裂缝最多剥落和露筋少标注实例数差距悬殊。默认的损失函数会被多数类主导。解决先用类别频率重采样对少数类图像做过采样简单复制或轻度增强让每个类别的实例数接近。这里不推荐用focal loss粗暴调权重因为桥梁缺陷类别间特征差异大过采样更直接。另外可以在训练配置里启用class_weights但需要在验证集上多测几次看F1是否真的提升。我踩过的坑是把剥落权重调太高后所有蜂窝麻面都被误判成剥落误检率暴涨。所以权重调整幅度以1.5倍为上限。5.3 小目标漏检裂缝宽度只有几个像素怎么调现象验证集mAP有0.75但把模型用到无人机原始大图上宽度小于5像素的裂缝全漏了。原因训练时图像被resize到640×640原来在4000×3000图里占10像素的裂缝缩放后只剩1个像素几乎不可见。模型根本没见过足够清晰的小裂缝特征。解决两个方向并行。一是训练时用1180的大分辨率并配合切片数据二是推理时用SAHI切片。如果不想引入SAHI依赖可以人工把原始大图按50%重叠裁成1024×1024的小图对小图推理后再把边界框坐标映射回原图并滤除那些边界上被截断的不完整框。这个做法的缺点是推理时间增加了5倍左右但桥梁检测通常是离线批量跑时间换召回是值得的。5.4 误检渗水痕迹阴影和渗水怎么区分现象桥墩侧面大片阴影被识别成渗水晴天高架桥面下排水管附近的黑色污渍也被标成渗水。原因渗水痕迹在颜色上和阴影、污渍相似都偏深色模型学到的是“深色区域”而不是“水迹的不规则边缘和湿润纹理”。解决标注时把渗水影像细分为两类有明确水迹边缘的“渗水”和只有颜色变深的“水渍”。如果水渍不构成结构病害就把它单独作为负样本背景类不参与缺陷检测。另外建议在训练集里加入“阴影”和“反光”两类的负样本标注类别名设为0即背景但给个框让模型有明确的负样本信号。YOLO支持背景类只需在txt里额外引入一个id并给低权重实测能明显降低误检。5.5 模型在实拍现场翻车训练集太干净部署时遇逆光现象实验室测试一切正常到了现场无人机拍出来的图有雾霾、逆光、运动模糊模型漏检严重。原因训练集大多来自天气好、光线好的巡检照片没覆盖低光照和退化条件。深度学习模型对分布外数据很脆弱桥梁现场的环境变化比想象中剧烈。解决在数据采集阶段就要有意识地加入退化场景。具体做法是从已有的正常图中用随机gamma变换模拟逆光暗部用高斯模糊模拟轻微失焦用高斯噪声模拟低照度。这些增强的强度要适中不要把裂缝纹理消掉。更重要的是务必保留一批完全没有增强的原始图作为最终验证集否则你无法判断模型在干净图上有没有退化。6. 用一份自建数据集验证检测效果mAP之外还要看什么模型训练完习惯上先看mAP0.5。但对桥梁缺陷检测mAP不能单独决定能不能交付。你需要做三件事看PR曲线确认召回瓶颈看混淆矩阵确认类别串扰拿真实大图做端到端推理验证。PR曲线要重点关注召回率在0.5到0.8之间的下降速度。裂缝检测的召回率如果低于0.8意味着每10条裂缝会漏掉2条以上现场复核成本会翻倍。这时候优先调置信度阈值验证集上画出不同置信度下的F1曲线选F1最高的置信度作为部署阈值。不要机械用默认0.25桥梁缺陷场景通常会把阈值拉到0.3到0.4因为误检的代价是派人排查空点漏检的代价是结构安全隐患。混淆矩阵看的是类别串扰。最常见的是剥落和蜂窝麻面相互误判露筋和锈蚀相互误判。如果混淆矩阵里非对角线数值超过10%说明类别定义本身不够清晰需要回炉重建类别标准而不是调模型。这一步很多人跳过到了现场被业主发现一张剥落的照片被标成裂缝再回来补就晚了。最后用没参与训练的另一座桥的原始照片做端到端测试。把模型输出的框叠加到大图上检查三个问题框是否比缺陷实际范围大出很多裂缝是否只检测出断裂段而漏掉连续段以及同一区域是否出现重复框。重复框多说明NMS阈值太松目标密度高时需要调低NMS的IoU阈值到0.4漏检集中在同一位置说明切片重叠率不够提高重叠率到30%。我自己做过一个桥梁底面裂缝检测项目第一次交付时mAP到了0.82满以为没问题结果现场用无人机实拍一整座桥裂缝召回只有0.6。后来排查发现训练集里全是用桥检车拍的近距离图宽度和角度很单一加上现场逆光模型直接把阴影当成背景吞掉了。后来补了侧面光和逆光数据又把Mosaic关了半个epoch做微调召回才上来。这件事后我养成了一个习惯任何数据集做完先按采集条件分组再做验证mAP再高也不急着部署。希望这篇笔记能帮你在桥梁缺陷检测数据集上少走一段弯路。本文还有配套的精品资源点击获取