做路面病害检测这大半年,我踩过最深的坑不是模型训练不出来,而是数据集根本找不到。网上能搜到的道路裂缝坑洼图像开源数据集,要么链接失效,要么论文里语焉不详,要么下载下来发现标注格式和你想的完全不对。后来我把市面上主流的数据集基本都过了一遍——CFD、Crack500、DeepCrack、SDNET2018、RDD2022、GAPs、Pothole-600这些,有的训过模型,有的跑了基线,这篇文章就把它们的关键信息、选型逻辑和实际体验一次性整理清楚。想找道路裂缝坑洼图像开源数据集的同行,可以先从这里入手,省掉大量调研时间。
1. 挑数据集之前,先想清楚裂缝/坑洼任务的三种输出和两种路面
1.1 分类、检测、分割,三种任务对应三种标注格式
很多人是反着来的:先随便下个数据集,再看能做什么任务。正确顺序应该是先定义清楚你的输出是什么。
- 图像分类:输出这张图里有没有裂缝或坑洼。标注是一个标签,典型代表是SDNET2018这类按图标注的数据集。
- 目标检测:输出病害的位置框,告诉维护人员"这里裂了、那里有个坑"。标注是bounding box,典型代表是RDD2022。
- 语义分割:输出像素级掩码,把裂缝的精准轮廓抠出来,甚至可以用来反推裂缝宽度。标注是mask,典型代表是CFD、Crack500、DeepCrack。
这个选择直接决定你后面所有pipeline。我见过有人拿RDD2022这种检测数据集强行做分割,最后只能自己补标注掩码,工作量瞬间失控。如果是实际工程项目,建议优先做检测,因为裂缝的像素级标注成本极高,一条裂缝弯弯曲曲几百个像素,画一个mask比画一个框慢十倍不止。如果是做学术研究或者裂缝宽度分析,再考虑分割。
1.2 沥青路面与混凝土路面:材质差异决定泛化宽度
路面材质看起来只是场景差异,实际对模型的影响很大。
- 沥青路面:纹理粗、颜色深,裂缝经常被油污、修补带和水渍掩盖。很多公开的裂缝数据集都是在沥青路面上拍的,但不同国家的沥青配方和施工工艺不一样,纹理差异很明显。
- 混凝土/水泥路面:颜色浅、有伸缩缝和模板缝,模型很容易把正常的接缝误判为裂缝。
- 桥梁、隧道内部:光照不均匀,阴影重,还有各种复杂背景。
如果你的模型只是在某一个数据集上跑通,那无所谓;如果要做产品化,最后一定要混入实际场景的数据。公开数据集只能帮你把模型从"完全不能用"拉到"基本能用",从"基本能用"到"真正能用"之间的距离,是靠现场数据补的。
1.3 拍摄视角:手持、车载、无人机是三种完全不同的分布
同一个病害,换个拍摄角度,模型就可能失效。
- 手持近景:裂缝占比高、背景干净、病害细节清楚。CFD、Crack500这类很多是手持或手机拍的,优点是标注可靠,缺点是跟实际车载场景差距大。
- 车载俯视:拍摄距离远、速度快、存在运动模糊,路面纹理和光照变化剧烈。RDD2022和GAPs是这类。
- 无人机俯拍:视野大、尺度变化大、分辨率相对有限,适合做桥梁、大范围路面巡检,但公开数据集非常少。
我实际测试过,在手持近景数据集上训练的分割模型,拿到车载俯视图上推理,IoU直接掉一半以上。所以选数据集之前,务必先确认你的部署场景,尽量找同视角的数据。
2. 裂缝分割数据集盘点:CFD、Crack500、DeepCrack、SDNET2018谁最顺手
2.1 CFD:118张图就能跑通baseline的经典入门数据集
CFD(CrackForest Dataset)在学术界是绕不开的名字,几乎成了国内路面裂缝分割算法的默认验证集。它包含118张城市道路裂缝图像,其中带裂缝的正样本大概60多张,剩下的是没有裂缝的负样本,图像分辨率在480×320量级,属于相对小的图像。
CFD最典型的特征是标注方式是"弱标注"——掩码覆盖的是裂缝的主干区域,标注粒度比较粗,边缘细节并不精细。这既是缺点也是优点。缺点是你的模型学到的裂缝边界不会太锐利,掩码训练出来也偏粗;优点是它反而让模型对裂缝宽度的变化不敏感,不容易过拟合到某一种宽度。
我的建议是把CFD当作"冒烟测试集":模型结构搭好、loss调好之后,先在CFD上训练并可视化结果,确认pipeline没问题,再切换到Crack500或自己的真实数据。另外要注意,CFD图像数量少,直接训练深度模型很容易过拟合,更常见的用法是迁移学习或者作为测试集而不是训练集。
2.2 Crack500:室外手机拍摄的主力分割数据
Crack500是费城坦普尔大学团队发布的,核心卖点是"真实室外场景+像素级标注"。原始数据是500张用手机拍摄的道路裂缝图像,每张原始图大约有2000万像素,然后被切割成512×512的子图用于训练,实际得到约一千多张至两千张标注子图,具体数量以官方发布为准。
这套数据的质量在公开裂缝数据集中算比较高的:有大量真实路面细节,比如树叶阴影、轮胎印、油污、修补痕迹。这些噪声并不会让训练更轻松,但会让模型更接近实际部署环境。Crack500的标注是像素级,而且裂缝主干和分支都标得比较完整。
使用Crack500时最大的坑是数据泄漏:官方给的是切割后的子图,如果你随手把子图按比例随机分成训练集和测试集,同一个原始大图的多个子图会同时出现在训练集和测试集中,导致评估指标虚高。正确做法是按原始图像ID分组划分,同一个原始图的子图只能进同一侧。我一开始没注意这个细节,F1虚高了3到4个点,后来重新划分才看到真实水平。
2.3 DeepCrack:层级特征基准与跨场景验证
DeepCrack是论文《DeepCrack: A Deep Hierarchical Feature Learning Architecture for Crack Segmentation》附带发布的数据集,包含537张图像,标注为像素级分割掩码,其中约300张用于训练、200多张用于测试。
这个数据集的特点是场景更杂,不仅有道路,还包括墙面、地面等多种裂纹场景。图像来源比较多,分辨率差异大,光照条件也不统一,所以用它单独训练模型往往不如Crack500稳定。但它有个巨大价值:因为场景多样性足够,拿来验证模型的泛化能力非常合适。我在实际项目中习惯先用Crack500训练,再在DeepCrack上做二次验证,如果两个数据集上的指标都在合理范围,模型才敢往真实场景推。
另外,DeepCrack的测试集划分是官方固定好的,这一点很方便,不同论文之间的指标可以直接对比。缺点是测试集里有一些墙面图像,并不是纯道路场景,如果你的目标就是路面裂缝,看指标时最好单独过滤掉非道路样本。
2.4 SDNET2018:切块分类思路与混凝土场景补充
SDNET2018是犹他州立大学发布的混凝土结构裂缝数据集,和前面几个不太一样:它做的是图像级二分类而不是像素级分割。数据集由200多张混凝土结构原始图像切割成超过5万张64×64的小图块,每个图块被标注为"有裂缝"或"无裂缝"。
SDNET2018覆盖桥梁、道路、墙体三类混凝土结构,裂缝形态非常细,很多是只有几个像素宽的微裂缝。它的价值在于两点:
- 帮你训练一个快速筛查模型,率先过滤掉大量无病害图块,减少后续精细检测的计算压力。这是实际工程里很常用的级联思路。
- 补充混凝土路面的场景多样性,避免模型只在沥青路面上有效。
不过要提醒一句,SDNET2018的图像级标签并不精确到像素,所有"有裂缝"的图块都只是包含裂缝,并没有给出裂缝的位置和轮廓。所以它不能用来做分割训练,只能做分类。64×64的分辨率也很低,不能用它来训练检测模型。
2.5 CrackSeg9k:大规模合并数据集的正确打开方式
CrackSeg9k是近几年出现的大规模裂缝分割数据集,包含九千多张图像,标注是统一的裂缝/背景二类掩码。它的做法是把多个已有裂缝分割数据集合并起来,重新统一标注格式和标签体系。
这类"合并型数据集"的好处是规模大、来源广,裂缝形态覆盖面宽,适合做预训练或通用裂缝分割模型的基础训练集。有了它,你就不用一个个去搞定CFD、Crack500、DeepCrack等数据集的下载和格式转换,一次到位。
但要注意,合并型数据集会继承原始数据集的全部缺点:标注粒度不一致、不同来源图像分辨率差异大、场景分布不均衡。如果直接用CrackSeg9k训练,模型在单一场景测试时可能表现不如用特定数据集微调的模型。我建议把CrackSeg9k当作"预训练池",在这个基础上用你自己的小道数据做微调,效果会明显好于直接用ImageNet预训练。
下面用一张表汇总这几个主要分割数据集的关键参数,方便快速对比:
| 数据集 | 图像量级 | 标注类型 | 主要场景 | 适用任务 | 主要注意点 |
|---|---|---|---|---|---|
| CFD | 118张 | 像素级(粒度较粗) | 城市道路沥青路面 | 分割、快速验证 | 数量少,易过拟合 |
| Crack500 | 500原始/约千余张子图 | 像素级 | 室外手机拍摄道路 | 分割、真实场景训练 | 注意按原始图划分,防止数据泄漏 |
| DeepCrack | 537张 | 像素级 | 道路+墙面混合 | 分割、泛化测试 | 测试集混入非道路场景,需过滤 |
| SDNET2018 | 约5万+切块 | 图像级二分类 | 混凝土桥梁/道路/墙体 | 分类筛查 | 不是像素级,无法做分割 |
| CrackSeg9k | 9000+张 | 像素级二分类 | 多源合并 | 分割预训练、通用模型 | 标注一致性差,需微调 |
3. 坑洼与多国路况数据集:RDD2022、GAPs、Pothole-600的取舍
3.1 RDD2022:四类病害检测和跨国域泛化的主力
如果只让我推荐一个"下载下来就能训练目标检测模型"的数据集,我一定选RDD2022(Road Damage Dataset 2022)。它由日本宫崎大学等机构主导,收集了日本、印度、捷克、挪威四个国家/地区的道路图像,总计超过4.7万张,标注统一为四类病害:
- D00:纵向裂缝
- D10:横向裂缝
- D20:龟裂/网状裂缝
- D40:坑洼
这个四分类体系来自日本的道路病害调查标准,覆盖了最常见的路面破损类型,实际工程里也基本够用。标注格式是PASCAL VOC的XML文件,也就是每个病害一个bbox框,这个格式可以直接转成YOLO或者COCO格式,生态成熟,几乎不需要额外处理。
RDD2022对我帮助最大的是"跨国域"属性。四个国家的道路纹理、标线风格、光照条件差异明显,模型在这个数据集上训练完,跨场景鲁棒性明显好于只用单一国家数据。如果你想做更严格的跨域泛化实验,官方还提供按国家划分的train/validation协议,可以清晰评估模型在不同国家的表现。
有一点要注意:超过4.7万张图像的文件体积不小,下载后建议先做一轮数据清洗,去除重复帧、模糊帧和标注明显错误的图像。数据集中存在一部分夜间或弱光图像,如果你的部署场景是白天巡检,可以先把这些挑出来单独评估,看是否纳入训练。
3.2 GAPs:覆盖多病害类别的德国沥青路面数据集
GAPs(German Asphalt Pavement Distress dataset)是德国研究机构发布的沥青路面病害数据集,图像全部来自德国实际道路环境,覆盖的病害类别比RDD2022更丰富,除了裂缝和坑洼,还包括修补、边缘破损、表面老化等类型,具体类别数建议以官方发布说明为准。
GAPs最大的价值在于"多类别病害"和"精细标注"。RDD2022只有四类,而且用bbox框;GAPs除了检测框,还提供更细的病害类别定义,对做精细化巡检系统的团队很有用。它的数据量没有RDD2022那么大规模,属于"小而精"的类型,适合做多分类研究的补充数据。
但德系路况和国内路况差异很大:德国道路整体养护水平高,裂缝形态相对规整,病害密度低;国内很多路面的裂缝和修补混合情况更复杂。所以GAPs训练出来的模型不能直接拿到国内道路上用,至少需要用本地数据做微调。另外,GAPs的License我印象中偏向非商业科研用途,商业落地前一定要联系作者确认授权,这一点很容易被忽略。
3.3 Pothole-600和Kaggle混杂数据集:小数据集的边界
除了上面这些知名数据集,坑洼方向还有一些小规模数据集,比如Pothole-600,是600张坑洼图像配目标检测标注。这类数据集适合做数据补充,不适合做唯一训练来源。
Kaggle上也能搜到不少pothole相关的图像集,但质量参差不齐。有的数据集只是把网上图片打包成zip,标注格式混乱,有的连标注都没有,只是图片文件夹。我的经验是:Kaggle上的坑洼数据集可以用,但必须做严格清洗,最好的用法是作为RDD2022的补充数据,用来增加坑洼样本的多样性。
另外,如果你做的坑洼检测不是四个轮子的乘用车视角,而是电动自行车或者步行巡检视角,公开数据集基本没有现成的,只能靠自己采集。这一点要有心理准备,坑洼和裂缝不一样,坑洼数据集本身就要少一个数量级。
3.4 容易被忽略的辅助数据源:AigleRN/ESAR与BDD100K的边界
还有一些容易被忽略的数据源,虽然不能直接当主力训练集,但很有价值:
- AigleRN和ESAR:法国交通研究机构发布的道路裂缝数据库,图像量级不大,以裂缝分割和分类为主,学术上常用作方法验证。适合做跨国家、跨路面的泛化测试集。
- BDD100K:伯克利发布的自动驾驶视频数据集,总计10万张图像,主要标注是驾驶场景目标(车辆、行人、可行驶区域等),并没有专门做路面裂缝和坑洼的标注。但它的可行驶区域分割标注可以帮你做道路区域过滤:先提取道路区域,再在道路区域内做病害识别,能大幅减少背景干扰,提升推理精度。
- 百度飞桨、华为ModelArts等平台上有一些间接相关的路面数据,但很多是从上述开源数据集二次整理的,使用时要注意追溯原始来源和授权。
4. 比选数据集更重要的避坑点:标注一致性、类不平衡和跨域失效
4.1 裂缝标注粗细差异带来的"伪精度"
这是几乎每个人都会踩的坑。裂缝的像素级标注非常依赖标注人员的主观判断:同样一条裂缝,A标注员可能只标1像素宽的主线,B标注员会把周围模糊区域也标进去,变成5像素宽。不同数据集的标注风格差别很大,CFD偏粗,Crack500相对精细,CrackSeg9k因为是合并数据集,内部粗细差异更大。
如果你把多个数据集混合训练而不做处理,模型会学到一个"平均宽度"标准,实际问题不大。但如果你用A数据集训练、B数据集测试,会发现分割结果在B数据上总是差口气,这不是模型能力问题,而是标注风格差异。
我建议在训练前对mask做一个预处理:统一用形态学腐蚀或膨胀把标注宽度对齐到某个目标范围。实际操作中,我会先统计训练集mask裂缝的宽度分布,然后对过细的标注做一次膨胀,对过粗的标注做一次腐蚀,让裂缝宽度先验基本一致。这个操作能明显提升跨数据集的迁移结果。
4.2 类不平衡:裂缝像素占比可能不到1%
裂缝分割是典型的极度类不平衡问题。一张1024×1024的道路图里,裂缝像素往往只占整体像素的0.5%到2%。如果直接用普通的交叉熵损失训练,模型很快会收敛到"所有像素都预测为背景",因为这样的准确率已经超过98%了。
实际处理有几个办法:
- 使用Dice Loss、Focal Loss或者Dice+CE组合损失,让模型更关注困难样本。
- 对mask做加权采样,让包含裂缝的图像块在batch中占更高比例。
- 后处理时用连通域分析和形态学开闭运算,去掉面积过小的孤立预测区域,减少背景噪声误报。
对于检测任务,坑洼和裂缝的bbox数量在RDD2022中也远小于背景图像数量,但检测任务通常用mAP评估,对类不平衡的敏感度低于分割,实际训练时问题不大,主要靠调整anchor比例和类别权重。
4.3 数据泄漏:patch划分导致的幻觉分数
前面提过Crack500的数据泄漏问题,这里值得展开。很多道路语义分割数据集都是先拍大图再切patch,如果随机按patch划分train/test,同一个大图的不同patch会被分到两侧,模型其实已经"见过"目标场景了,测试分数会显著虚高。
判断方法很简单:训练完成后,把测试集里预测效果最好的一批图像找出来,看它们的原始大图ID是否和训练集有重叠。如果有,你的模型评估就是无效的。
正确做法是:先确定原始图像ID,再按ID划分数据集,保证同一个原始图像的所有patch只出现在训练集或测试集之一。如果你用的数据集没有提供原始ID(比如某些二次整理版本),就按文件名前缀来聚类,尽量还原原始分组关系。
4.4 跨域失效:在德国数据上训完,回到自己城市道路上为什么翻车
我做过一个实验:用RDD2022里的德国数据训练YOLOv8,然后直接拿到国内一条城市道路上测试,效果惨不忍睹——漏检率很高,而且把路面的新旧沥青接缝误检成裂缝。这就是典型的跨域问题。
原因有几方面:路面材料不同,德国和国内的道路纹理差异很大;标线不同,虚线实线颜色宽度都不一样;光照条件不同,训练数据大多是白天晴朗天气,实际巡检时阴天、逆光、阴影纷纷出现;相机安装高度和角度不同,病害在图像里的尺度和视角都变了。
应对跨域失效的办法:
- 采集一部分目标场景数据做微调,这是最有效的方法,几百张图往往就能救回来。
- 使用图像风格增强,比如随机调整色彩、对比度、亮度,模拟不同天气和光照。
- 对车载部署场景,训练时增加随机透视变换和模糊增强,模拟车身振动和拍摄角度变化。
- 条件允许的话,用不同国家的数据混合训练,模型见过足够多风格后,对新场景的适应性会好很多。
4.5 授权与合规:非商用限制不是小事
很多开源数据集并不是完全"自由使用"的。我见过不少团队直接把数据集下载下来训练商业模型,结果上线前法务审查发现数据集只限科研使用,整个技术方案都要推翻重做。
使用前务必确认每个数据集的License或者作者声明:
- RDD2022在IEEE DataPort上发布,下载和使用通常要求引用原始论文,部分用途可能需要按平台条款执行。
- GAPs我记得有明确的使用条款,偏科研导向,商用必须联系作者。
- CFD在GitHub上公开,但具体授权要看仓库的License文件。
- SDNET2018通常在大学机构网站上发布,也要求非商业用途或者引用论文。
最稳妥的做法是:建一个数据集清单表格,记录数据集的来源、下载日期、License类型、是否允许商用、是否需要引用论文。这个习惯能帮你避免很多后续麻烦。
5. 数据集拿到手后的处理流水线:体检、格式转换、划分与训练建议
5.1 先做数据体检,不要急着开训
任何一个数据集下载下来,第一件事不是解压开训,而是写个脚本做全面体检。需要用几段脚本分别统计:
- 图像总数、尺寸分布、通道数、格式。
- 标注文件是否与图像一一对应,是否有缺失或多余文件。
- 标注框是否有坐标越界、宽高为0、重复框等问题。
- 分割mask的类别分布,以及掩码是否对齐到对应图像。
这一步能拦下大量脏数据。我曾经拿到一个数据集,发现其中几十张图像的mask是从别的图上复制过来的,位置完全对不上,这要是直接训练,模型会被带偏。体检代码不需要很复杂,用Python跑一遍就能发现问题。
5.2 标注格式统一:XML、JSON、mask互转的注意点
公开数据集的标注格式五花八门:RDD2022是XML(VOC格式),Crack500是mask图片,SDNET2018是文件名或csv标签,GAPs标注格式可能需要从官方文档确认。训练前必须统一格式。
建议统一到一个标准流程:
- 所有检测标注统一转成COCO JSON或者YOLO txt。转YOLO时要注意坐标是归一化的中心点格式,用bbox中心坐标除以图像宽高,容易出现除以0或者坐标越界的问题,建议先做校验。
- 所有分割mask统一转成PNG格式的二值图,背景为0,前景为1或255。多类别分割时,类别ID要从1开始,0保留给背景。
- 图像统一命名,建议格式为
datasetname_originalid_patchid.jpg,这样后续按原始ID划分时一目了然。
格式转换阶段最容易出的错是图像resize后mask没有跟着resize,导致mask和图像错位。如果训练时输入尺寸固定为512×512,记得用同样的插值方式处理图像,用最近邻插值处理mask,避免类别边缘被平滑模糊。
5.3 训练/验证/测试划分的正确姿势
数据划分直接决定你的指标有没有说服力。建议按照"原始场景分组"和"国家/路段分组"两个维度来划分。
- 如果是Crack500这类patch数据集,按原始图像ID分组。
- 如果是RDD2022这类多国数据集,可以考虑按国家划分,训练集用日本+印度,验证集用捷克,测试集用挪威,这样做出来的泛化性指标更有参考价值。
- 建议测试集保持10%-20%的比例,且保证测试集中的病害类别分布与训练集接近。
划分完成后,检查一下每张测试图像与训练图像是否存在高度相似。比如有些数据集存在同一路段连续拍摄的帧,相邻帧视觉上几乎一样,这类相似图像如果出现在两侧,同样会导致指标虚高。
5.4 针对裂缝和坑洼的数据增强策略
数据增强不能盲目套用通用方案,针对路面病害的特点,我有几个相对有效的组合:
- 几何增强:随机旋转±15度、水平翻转、垂直翻转、随机缩放0.5到2.0。垂直翻转在车载场景下可以不用,因为车辆不会倒着开。
- 彩色增强:亮度随机调整±30%、对比度±20%、HSV色相微调。这能模拟阴天、晴天、逆光和不同相机白平衡。
- 模糊和噪声:高斯模糊、运动模糊、高斯噪声,模拟车载运动中拍摄到的模糊帧和低照度噪声。
- 弹性形变:对分割任务,弹性形变能模拟路面形变和拍摄角度扭曲,效果很好,但对检测任务不建议用,会让bbox和图像内容产生错位。
- CutMix/拼接增强:把真实裂缝patch贴到干净路面上,生成新的训练样本。这个方法对坑洼和裂缝都有效,能显著增加阳性样本数量和场景多样性。
训练时还有一个小技巧:对裂缝分割模型,可以在mask上随机做1到2个像素的膨胀,让模型不要过于执着于"全世界最精细的裂缝边界",这能提升真实场景下的鲁棒性,代价是理论IoU会稍微下降。但对实用来讲,鲁棒性比漂亮的理论指标值钱。
5.5 模型选型建议:检测用YOLO系,分割用UNet/DeepLabV3+
基于这些数据集的实际使用体验,模型选型我给出相对保守的建议:
- 目标检测:RDD2022直接配YOLOv8或YOLOv5就能获得不错的baseline。输入分辨率建议640×640以上,patch中裂缝占比小,分辨率太低小目标会漏检。
- 语义分割:UNet++、DeepLabV3+、PSPNet是稳定选择,backbone用ResNet50或ResNet101,ImageNet预训练是标配。裂缝分割对小裂缝细节要求高,可以考虑增加注意力模块或者空洞卷积在Decoder中的应用。
- 分类筛查:MobileNetV3、EfficientNet系列适合做"有无病害"的二分类筛查,速度快、体积小,方便部署到边缘设备。
关于训练轮数,公开数据集规模不算大,一般100到200个epoch就能收敛,重点放在早停和学习率调度上。如果发现训练loss下降正常但验证指标波动大,优先检查数据泄漏和标注噪声,而不是疯狂调模型。
最后分享一点个人体会:公开数据集的意义是帮你把问题定义清楚、把流程跑通、把baseline立起来,但它替代不了现场数据。真正上线的系统,至少要留出总体数据的20%做实地采集,并且持续回流那些模型预测失败的硬样本。道路病害场景的分布太散了,每个城市的路面材料、施工工艺、养护水平都不一样,没有一个公开数据集能覆盖所有情况。把这篇提到的数据集用好,你的项目已经赢在起跑线上了,剩下的路,得靠自己的数据和迭代跑出来。