
简介面向混凝土裂缝检测与分类研究者的数据集汇总包覆盖SDNET2018、ConcreteCrackImagesforClassification、crack-detection-master等公开分类集合并额外提供作者自制的3100张VOC格式目标检测图片适合深度学习、计算机视觉方向的科研与工程人员快速获取可用的训练数据与可运行源码。压缩包共3个文件以html页面、inscode配置和gitignore为主整体仅6KB属于轻量级资源导航与代码入口使用时需配合外部数据集链接。目前已有129人学习资源虽小但信息密度较高可帮助读者节省逐站搜索时间对于无法直接获取的数据集作者也提供留言索取与持续补充的渠道便于后续扩展实验场景。从标签来看该整理兼具软件开发与源码属性适合作为裂缝识别项目起步阶段的资源索引。 做混凝土裂缝检测的朋友应该都经历过一个非常尴尬的阶段模型框架选好了训练代码也跑通了结果卡在数据上——公开数据集散落在各个老旧的论文主页下载链接失效、标注格式五花八门、有的甚至只有分类标签没有定位框。我接触这个方向三年多前前后后整理过不下十份裂缝数据集也写过配套的训练和转换脚本这次干脆把口碑好、拿过来能用的数据集汇总成一份清单再把我平时整理好的可运行源码链路一起拆开讲覆盖格式转换、YOLOv8训练、实战问题排查和裂缝宽度测量扩展。不管你是做桥梁隧道检测的工程师还是正在准备毕业设计的同学照着这份内容走一遍至少能省掉一半无效试错的时间。1. 混凝土裂缝公开数据集盘点哪几份值得你下载1.1 五份公认好用的裂缝数据集横向对比先给一张汇总表方便你快速判断自己该下哪一份。这里的“标注类型”很重要因为它直接决定你拿到数据后要做哪些预处理。数据集来源/机构图像数量标注类型适用任务备注CrackForest (CFD)国内高校联合发布118像素级分割/检测路面裂缝为主量大但单张信息量大Crack500北大联合Rutgers等500像素级分割/检测手机拍摄尺度跨度大适合练手DeepCrack高校研究团队537像素级分割/检测复杂背景多粗细裂缝都有GAPs德国亚琛工业大学590像素级分割/检测建筑混凝土表面含蜂窝、麻面等缺陷SDNET2018美国犹他州立大学23万patch级分类二分类/预训练切片尺寸固定没有检测框CrackForest也就是常说的CFD是很多裂缝分割论文的基准数据集。118张图虽然不多但每张图里裂缝的形态都比较完整背景包括沥青路面和水泥路面用作算法可行性验证非常合适。缺点是数量少直接拿它训练YOLO容易过拟合更适合用来评估分割模型或者做预训练。Crack500是我个人用得最多的一份。它是用手机在不同距离下拍摄的路面裂缝图像分辨率高裂缝粗细变化明显有的裂缝像素宽度只有两三个像素有的则能到二三十个像素。这种尺度差异对检测模型来说是很好的训练样本能让模型逐渐适应不同严重程度的裂缝。DeepCrack的亮点在于复杂背景里面有不少带树叶阴影、路面纹理干扰、光照不均的样本对模型鲁棒性要求更高。如果你最终要部署到户外真实场景建议把DeepCrack和Crack500混合起来训练。GAPs严格来说不是纯裂缝数据集它包含裂缝、蜂窝、麻面、露筋等多种混凝土表面缺陷裂缝只是其中一类。这个数据集的价值在于多类别适合做混凝土外观缺陷的综合检测而不仅仅是单一裂缝检测。注意它是像素级标注做检测任务时需要转换。SDNET2018则是大规模分类数据集它的图像是固定大小的切片每张只标注“有裂缝”或“无裂缝”不提供位置信息所以它没办法直接用来训练目标检测器。我通常用它做二分类任务或者当作数据增强的辅助来源比如用它来扩充背景负样本。1.2 路面、桥梁、水下场景的数据集怎么扩展很多人一上来就想找“桥梁裂缝数据集”“水下裂缝数据集”但实际情况是这类数据公开的非常少大部分是工程项目内部自采的不会完整放出来。常见的公开裂缝数据集绝大多数都集中在道路路面和建筑表面真要面向桥梁墩柱、水下水工结构最现实的路径是先用上述通用数据集完成预训练然后再采几组目标场景的数据做微调通常每组几百张图就能有明显效果。如果项目中确实需要水下或隧道场景可以关注学术界公开发布的少量水下结构检测数据集另外也可以用形态学方法自己合成一部分噪声样本比如把裂缝叠加到水下背景上做数据增强。这不是一个完美的方案但在样本不足时能显著提升模型在目标场景的初始收敛速度。2. 可运行源码第一步把标注格式统一起来2.1 为什么最终建议全部转成YOLO格式公开数据集的标注格式非常混乱有的给VOC的XML文件有的给COCO的JSON有的干脆是一张二值mask图片。训练目标检测模型时我习惯统一转成YOLO格式的txt文件原因有三第一YOLO生态的配套工具最完善Ultralytics、YOLOv5、YOLOv6等主流框架都支持第二txt文件按图像逐行存类别和归一化坐标体积小、易读写方便现场调试第三后续做数据增强或者格式再互转时YOLO格式的转换损失最小。VOC转YOLO的脚本并不复杂核心就是把XML里的xmin、ymin、xmax、ymax换算成归一化的中心点坐标和宽高。下面这段脚本我一直在用直接保存成voc2yolo.py就能跑import xml.etree.ElementTree as ET import os def voc2yolo(xml_file, class_names): tree ET.parse(xml_file) root tree.getroot() size root.find(size) w float(size.find(width).text) h float(size.find(height).text) lines [] for obj in root.iter(object): name obj.find(name).text if name not in class_names: continue cls_id class_names.index(name) bbox obj.find(bndbox) x1 float(bbox.find(xmin).text) y1 float(bbox.find(ymin).text) x2 float(bbox.find(xmax).text) y2 float(bbox.find(ymax).text) xc (x1 x2) / 2.0 / w yc (y1 y2) / 2.0 / h bw (x2 - x1) / w bh (y2 - y1) / h lines.append(f{cls_id} {xc:.6f} {yc:.6f} {bw:.6f} {bh:.6f}) return lines if __name__ __main__: class_names [crack] xml_dir Annotations out_dir labels os.makedirs(out_dir, exist_okTrue) for xml_name in os.listdir(xml_dir): if not xml_name.endswith(.xml): continue lines voc2yolo(os.path.join(xml_dir, xml_name), class_names) txt_name os.path.splitext(xml_name)[0] .txt with open(os.path.join(out_dir, txt_name), w) as f: f.write(\n.join(lines))COCO格式转YOLO稍微绕一点需要先解析JSON里的images和annotations字段再根据image_id建立映射关系。实际操作时可以直接用Ultralytics提供的coco2yolo工具也可以借助pycocotools把目标区域的坐标取出来再套用上面的归一化公式。重点提醒一句转换脚本跑完后一定要随机抽几组图和txt叠在一起可视化确认仅仅看坐标数值没意义重叠框偏差超过个把像素都会影响训练效果。2.2 像素级mask怎么生成检测框Crack500、GAPs、DeepCrack这些数据集给的是像素级分割mask很多人拿到手就懵了。其实转检测框的思路很简单利用OpenCV查找轮廓把每个独立裂缝区域的最小外接正矩形提取出来再转成YOLO格式。难点在于一个mask里可能包含多条裂缝也可能同一裂缝断成好几段需要处理好连通域避免生成大量杂乱的小框。import cv2 import numpy as np def mask2yolo(mask_path, class_id0, min_area100, close_kernel5): mask cv2.imread(mask_path, 0) _, mask cv2.threshold(mask, 127, 255, cv2.THRESH_BINARY) mask cv2.morphologyEx(mask, cv2.MORPH_CLOSE, np.ones((close_kernel, close_kernel), np.uint8)) contours, _ cv2.findContours(mask, cv2.RETR_EXTERNAL, cv2.CHAIN_APPROX_SIMPLE) h, w mask.shape lines [] for cnt in contours: area cv2.contourArea(cnt) if area min_area: continue x, y, bw, bh cv2.boundingRect(cnt) xc (x bw / 2.0) / w yc (y bh / 2.0) / h nw bw / w nh bh / h lines.append(f{class_id} {xc:.6f} {yc:.6f} {nw:.6f} {nh:.6f}) return lines这段代码里有一个细节值得展开我加了形态学闭运算作用是把距离很近的裂缝断点“搭桥”连起来避免同一根裂缝被拆成五六个框。闭运算的kernel大小要根据图像分辨率调整我通常先从5x5开始如果发现一根裂缝断框太多就适当加大到7x7或9x9。另外min_area别设太大裂缝区域的面积往往很小设成100像素左右比较稳妥否则细裂缝会被整条过滤掉但也不要设太小否则mask里的噪点会生成大量无效框。转换完成后强烈建议做一次“小框清洗”统计所有标注框的宽高分布把宽度或高度小于5像素的框单独抽出来人工查看。因为YOLO下采样到20x20的特征图后小于5像素的目标几乎不可能被正确学习这些框留着只会增加训练噪声。3. 基于YOLOv8的可运行训练链路3.1 数据目录结构与data.yaml配置统一标注格式后下一步就是整理成YOLO标准目录结构。我推荐的布局是这样crack-dataset/ ├── images/ │ ├── train/ │ ├── val/ │ └── test/ ├── labels/ │ ├── train/ │ ├── val/ │ └── test/ └── data.yaml注意images和labels下对应的子目录名称必须一一对应同一张图的txt文件名必须和图片文件名完全一致包括后缀前的部分。这是新手最容易踩的坑之一图片叫IMG_1024.jpg标签却存成img_1024.txt训练时看着参数没问题实际所有标签全都匹配不上模型就等于在猜。data.yaml是Ultralytics框架读取的配置文件内容很简单path: /path/to/crack-dataset train: images/train val: images/val test: images/test names: 0: crack如果你要扩展成多类别缺陷检测把names对应改成实际类别就行了比如names: 0: crack 1: spalling 2: honeycomb 3: exposed_steel3.2 训练命令与关键超参数推荐安装好Ultralytics之后训练命令非常简洁yolo detect train \ datacrack_data.yaml \ modelyolov8n.pt \ epochs200 \ imgsz640 \ batch16 \ patience30 \ optimizerAdamW \ lr00.001 \ close_mosaic15这套参数是我在裂缝检测任务上反复调过的组合每一项都有它的原因imgsz640是速度和精度的平衡点。裂缝属于极端小目标很多细裂缝在640分辨率下只有几个像素但你直接提到1280训练显存占用会成倍上涨训练速度大幅下降。我建议先用640跑通全流程再看验证集效果决定要不要切到960或1280做二次微调。patience30搭配epochs200很关键。裂缝数据集的样本量通常不大模型往往在80到150轮之间就能收敛没必要死磕完200轮。早停机制能自动帮你找到最佳权重前提是不要把它关掉。close_mosaic15是容易被忽略但对裂缝检测特别重要的参数。Mosaic增强默认在训练末期才会关闭但裂缝是细长结构在拼接图中很容易被切得七零八落模型学到一堆断裂的条状物特征。把close_mosaic设为15就是在最后15轮关闭Mosaic让模型在接近真实分布的数据上做收敛实际效果比不设能高2到3个点的mAP。我还建议在训练时打开简单而有效的颜色扰动和翻转增强Ultralytics默认的fliplr0.5、hsv_h0.015、hsv_s0.7基本够用。垂直翻转flipud要谨慎如果现场数据里裂缝大多是沿行车方向分布垂直翻转会让模型产生方向混淆干脆保持默认的0。3.3 评估指标别光看mAP更要看Recall裂缝检测任务里mAP数值往往看起来很漂亮但真正落地时你会发现漏检才是大问题。原因是公开数据集的背景相对干净模型很容易在验证集上拿到0.9以上的mAP可一旦放到实际巡检图像里地面纹理、水渍、钢筋阴影都会触发误检。所以我评估裂缝模型时会重点看两个维度一是F1曲线找到Precision和Recall的平衡点然后在实际部署时把置信度阈值设在这个平衡点附近二是不同IoU阈值下的Recall尤其是IoU0.5时的小目标Recall。裂缝检测的目标是“不漏”漏掉一条裂缝比多报一个疑似点严重得多。使用Ultralytics自带的评估命令就可以输出这些指标yolo detect val \ modelruns/detect/train/weights/best.pt \ datacrack_data.yaml如果发现Recall偏低通常说明模型对细裂缝的学习还不够我会优先尝试调整类别权重或增大输入分辨率而不是盲目堆模型体积。4. 裂缝检测实战中的四大坑与排查技巧4.1 裂缝太细模型根本学不到特征这是裂缝检测新手遇到最多的报错式困惑训练loss很低但预测时细裂缝就是检测不出来。原因其实很好理解YOLO的特征图经过多次下采样后最小特征图感受野较大只能捕捉到整体的裂缝走向但细裂缝在浅层特征图上的像素点很少特征表达不足。我的解决思路有三个按优先级排序第一提高输入分辨率到960或1280代价是显存占用上升第二使用SAHI切图推理把大图切成互相重叠的小块分别推理再融合结果这个方法对裂缝这种小目标效果极佳几乎能拉回一半漏检第三如果项目对实时性要求不高可以尝试给YOLOv8开启P2检测头专门增强小目标检测能力。4.2 裂缝样本占比太低正负样本严重失衡正常图像里裂缝像素面积通常不到整张图的5%这就导致目标检测器在训练时看到的负样本远多于正样本。虽然YOLO本身有focal loss的变体但实践中我发现数据层面的处理比模型层面更有效。最实用的方法是“切片化训练”将原图切成512x512或640x640的patch保留包含裂缝的patch并从原图中抽一批无裂缝patch作为负样本把正负样本比例控制在1:3到1:5之间。这样做有两个好处一是裂缝在patch中的像素占比显著提升正样本更充分二是变相增加了样本数量让模型看到更多不同位置的裂缝形态。4.3 光照不均和阴影干扰严重误检率高户外采集的裂缝图像光照问题几乎是绕不开的。强光下裂缝阴影会被放大复杂纹理背景中类似裂缝的条状阴影也会被模型误判。我在一个项目中就遇到模型把桥梁伸缩缝旁的黑色水渍识别成裂缝的情况。解决思路有两个方面。数据层面可以在训练时加入亮度、对比度扰动让模型适应不同光照条件预处理层面对输入图像做CLAHE对比度受限自适应直方图均衡增强能有效提升暗部裂缝与背景的对比度减小阴影干扰。需要提醒的是CLAHE处理后的图像必须与训练数据保持一致如果训练时用的是原始图推理时突然加上CLAHE反而会导致性能下降。数据增强和预处理策略一定要在训练阶段就同步应用。4.4 标注不统一导致模型越学越乱裂缝数据集的标注质量参差不齐尤其是不同人标注的标准差别很大。有的人把细微裂纹全部标出有的人只标宽度明显的裂缝还有人把背景纹理误标成裂缝。模型在几十轮训练后就会陷入这些矛盾标注的“内耗”中表现为loss下降缓慢、验证集精度波动大。碰到这种情况我的做法是“两轮补标法”。先用初步标注的数据训练一版模型再用这个模型去预测训练集把预测结果和原始标注不一致的图像全部挑出来。差异有两种一是模型预测出了裂缝但原标注漏标二是原标注存在不合理框。把这两类图像人工过一遍修正标注然后用修正后的数据重新训练。一般做两轮标注质量会有非常明显的提升最终模型收敛速度也会加快。5. 从检测到分割裂缝宽度量化如何实现5.1 检测框无法量宽度分割mask才行很多工程检测需求不只是定位裂缝还要给出裂缝宽度因为宽度是判断裂缝严重程度和结构安全性的核心指标。这里必须泼一盆冷水目标检测框是矩形它只能告诉你有裂缝以及裂缝的大致位置完全无法提供“这条裂缝宽2.3毫米”这种量化信息。要算宽度必须拿到像素级的分割mask。可行的方案有两类一是直接用DeepCrack这类经典裂缝分割网络训练模型输出每张图的像素级mask二是在YOLOv8框架下使用其自带的分割模型也就是把yolov8n-seg.pt换成yolov8n.pt训练命令从detect改成segment标注数据则需要准备成mask图。5.2 宽度测量的核心思路和比例尺标定拿到分割mask之后宽度估算的原理并不复杂先做骨架提取得到裂缝中心线再用距离变换计算每个中心点到裂缝边缘的距离距离的两倍就是该点的裂缝宽度像素值。from skimage.morphology import skeletonize import cv2 import numpy as np mask (cv2.imread(mask.png, 0) 127).astype(np.uint8) dist cv2.distanceTransform(mask, cv2.DIST_L2, 5) skel skeletonize(mask).astype(bool) width_px 2 * dist[skel] mean_width_px float(np.mean(width_px)) max_width_px float(np.max(width_px))但这里有一个关键前提像素宽度必须换算成物理尺寸才有意义。换算需要知道“每毫米对应多少像素”这个值来源于相机标定或现场比例尺。最简单的做法是在拍摄裂缝时在裂缝旁边平行放一把直尺用直尺的实际长度除以它在图像中的像素长度得到mm/pixel的比例系数。固定机位、固定焦距的情况下这个系数可以复用但如果是手持设备近远景变化每次拍摄都得重新标定否则宽度数据毫无参考价值。在实际项目中我个人更推荐使用棋盘格标定板做相机标定虽然前期工作量会大一点但测量误差远小于直尺近似法。如果只是做裂缝严重程度分级比如粗分类为“轻微/中等/严重”那用平均宽度像素值做一个相对阈值也能满足现场快速筛查的需求不必追求精确的毫米级数值。最后分享一个我踩过几次坑后养成的习惯每次跑新数据集之前先花20分钟做一次所有样本的可视化检查把图像和标注框叠在一起生成一张拼接预览图快速扫一眼有没有错标、漏标和格式不匹配。这一步看似简单却能避免后面数小时的训练白费。裂缝检测这个方向模型结构反而不是最大的门槛数据和细节才是真正拉开效果差距的地方希望你也能在这些细节上少走弯路。本文还有配套的精品资源点击获取