尧图网络科技YAOTU DIGITAL 获取报价
获取报价
首页 / 资讯中心 / 文章详情

混凝土缺陷检测数据集VOC+YOLO 7513张7类别:从格式解析到YOLOv8训练全流程

发布时间:2026/9/26 11:21:25

资讯中心
01
ARTICLE

混凝土缺陷检测数据集VOC+YOLO 7513张7类别:从格式解析到YOLOv8训练全流程

混凝土缺陷检测数据集VOC+YOLO 7513张7类别:从格式解析到YOLOv8训练全流程
简介本资源为混凝土缺陷检测数据集面向从事建筑结构健康监测、工业质检与计算机视觉算法研发的人员尤其适合需要训练目标检测模型识别混凝土表面病害的工程师与研究者。数据集同时提供Pascal VOC与YOLO两种标注格式包含7513张jpg图片及一一对应的xml与txt标注文件标注类别共7类涵盖可见裂斑、分层、风化、缝隙、剥落、脱落与锈迹总标注框数达40324个均使用labelImg以矩形框方式完成标注。压缩包为7z格式共约2000个文件以1999个xml标注文件和1个说明txt为主整体大小约397MB目录结构清晰便于直接接入主流检测框架进行训练与验证。目前已有713人学习下载适合作为混凝土缺陷识别课题的基准数据帮助读者省去繁琐的标注环节快速开展模型训练、类别分布分析与算法对比实验。1. 混凝土缺陷检测数据集 VOCYOLO 7513 张 7 类别这套数据到底能干什么拿到「混凝土缺陷检测数据集 VOCYOLO 格式 7513 张 7 类别」这个标题很多人第一反应是去搜数据集下载但真正决定项目成败的不是下载速度而是你清不清楚这 7513 张图里标注了什么、7 个类别怎么分布、VOC 和 YOLO 两套格式各自适合喂给哪个训练框架。混凝土缺陷检测属于典型的工业视觉落地场景——桥梁、隧道、大坝、建筑外墙的裂缝、剥落、露筋、蜂窝麻面靠人眼巡检效率低且漏检率高用 YOLO 系列做目标检测是目前最主流的方案。这套数据集同时提供 VOC 的 XML 标注和 YOLO 的 TXT 标注意味着你既能用 PyTorch 系的 ultralytics 直接开训也能接 MMDetection、PaddleDetection 这类支持 VOC 的框架。适合谁适合手上有巡检图像但标注量不够的算法工程师、做土木工程智能检测方向的研究生以及想拿一个真实工业数据集练 YOLOv8 训练全流程的开发者。下面从格式差异、环境搭建、训练参数到踩坑排查把这条路走通。2. VOC 与 YOLO 双格式拆解7513 张图怎么读、怎么转、怎么校验2.1 两套标注格式的本质差异VOC 格式的核心是每张图对应一个 XML 文件里面用object节点记录类别名和bndbox的 xmin、ymin、xmax、ymax 四个绝对像素坐标。YOLO 格式则是每张图对应一个 TXT 文件每行是class_id x_center y_center width height后四个值全部是相对图像宽高的归一化浮点数范围 0 到 1。这个差异决定了你在做数据增强、坐标变换、可视化验证时用的解析逻辑完全不同。VOC 的坐标是整数像素直接画框就能看YOLO 的坐标必须先乘以图像宽高还原成像素否则你画出来的框会全部挤在左上角一个像素范围内这是新手最常见的翻车点。7 类别意味着 class_id 从 0 到 6具体类别名需要你打开classes.txt或data.yaml确认常见混凝土缺陷类别包括裂缝crack、剥落spalling、露筋exposed rebar、蜂窝honeycomb、麻面void、渗水seepage、孔洞hole之类。不要假设类别顺序一定要读配置文件因为 VOC 的 XML 里存的是类别名字符串YOLO 的 TXT 里存的是数字 id两者映射错一位训练出来的模型就会把裂缝识别成剥落。2.2 用脚本校验 7513 张图的标注完整性拿到数据集第一件事不是开训是校验。7513 张图如果混进了空标注、越界框、类别名拼写不一致训练 loss 会莫名其妙震荡。下面这段 Python 脚本同时检查 VOC XML 和 YOLO TXT 的配对情况与坐标合法性。import os import xml.etree.ElementTree as ET from pathlib import Path from PIL import Image def check_voc(xml_dir, img_dir): 校验 VOC 格式XML 与图片配对、坐标越界、类别名 issues [] xml_files list(Path(xml_dir).glob(*.xml)) for xml_path in xml_files: tree ET.parse(xml_path) root tree.getroot() # 找对应图片 img_name root.find(filename).text img_path Path(img_dir) / img_name if not img_path.exists(): issues.append(f缺图: {xml_path.name} - {img_name}) continue img Image.open(img_path) W, H img.size for obj in root.findall(object): cls_name obj.find(name).text.strip() bbox obj.find(bndbox) xmin int(float(bbox.find(xmin).text)) ymin int(float(bbox.find(ymin).text)) xmax int(float(bbox.find(xmax).text)) ymax int(float(bbox.find(ymax).text)) # 坐标越界检查 if xmin 0 or ymin 0 or xmax W or ymax H: issues.append(f越界: {xml_path.name} {cls_name} ({xmin},{ymin},{xmax},{ymax}) 图尺寸 {W}x{H}) if xmax xmin or ymax ymin: issues.append(f零面积框: {xml_path.name} {cls_name}) return issues def check_yolo(txt_dir, img_dir, num_classes7): 校验 YOLO 格式归一化范围、class_id 合法性 issues [] txt_files list(Path(txt_dir).glob(*.txt)) for txt_path in txt_files: img_path Path(img_dir) / (txt_path.stem .jpg) if not img_path.exists(): # 尝试其他后缀 for ext in [.png, .jpeg, .bmp]: if (Path(img_dir) / (txt_path.stem ext)).exists(): img_path Path(img_dir) / (txt_path.stem ext) break else: issues.append(f缺图: {txt_path.name}) continue with open(txt_path) as f: for line_no, line in enumerate(f, 1): parts line.strip().split() if len(parts) ! 5: issues.append(f字段数错: {txt_path.name} 第{line_no}行) continue cid int(parts[0]) vals [float(v) for v in parts[1:]] if cid 0 or cid num_classes: issues.append(fclass_id越界: {txt_path.name} 第{line_no}行 id{cid}) if any(v 0 or v 1 for v in vals): issues.append(f归一化越界: {txt_path.name} 第{line_no}行 {vals}) return issues if __name__ __main__: voc_issues check_voc(VOC/Annotations, VOC/JPEGImages) yolo_issues check_yolo(YOLO/labels, YOLO/images) print(fVOC 问题数: {len(voc_issues)}) for i in voc_issues[:20]: print( , i) print(fYOLO 问题数: {len(yolo_issues)}) for i in yolo_issues[:20]: print( , i)这段脚本的逻辑分三块VOC 校验先通过 XML 里的 filename 找图确认配对再逐 object 检查坐标是否越界或零面积YOLO 校验检查每行是否 5 个字段、class_id 是否在 0 到 6 之间、四个归一化值是否落在 0 到 1。参数num_classes7对应标题里的 7 类别如果你的 classes.txt 实际类别数不同改这个值。跑完如果问题数不为零先修数据再训练别带着脏数据硬训否则后面调参全是玄学。2.3 VOC 转 YOLO 的转换脚本与四个边界坑虽然数据集号称双格式但实际拿到手经常只有 VOC 完整、YOLO 需要自己转或者反过来。下面这个转换脚本处理了四个容易翻车的边界图片尺寸读取失败、类别名到 id 的映射顺序、坐标归一化后的精度截断、以及空标注图是否保留。import xml.etree.ElementTree as ET from pathlib import Path from PIL import Image # 类别名到 id 的映射顺序必须和训练时 data.yaml 一致 CLASS_MAP { crack: 0, spalling: 1, exposed_rebar: 2, honeycomb: 3, void: 4, seepage: 5, hole: 6 } def voc_to_yolo(xml_dir, img_dir, out_dir): out_dir Path(out_dir) out_dir.mkdir(parentsTrue, exist_okTrue) for xml_path in Path(xml_dir).glob(*.xml): tree ET.parse(xml_path) root tree.getroot() img_name root.find(filename).text img_path Path(img_dir) / img_name try: W, H Image.open(img_path).size except Exception as e: print(f跳过无法读取的图: {img_path}, {e}) continue lines [] for obj in root.findall(object): cls_name obj.find(name).text.strip() if cls_name not in CLASS_MAP: print(f未知类别 {cls_name} in {xml_path.name}跳过该框) continue cid CLASS_MAP[cls_name] 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) # 裁剪到图像边界内防止越界框产生负值 xmin, ymin max(0, xmin), max(0, ymin) xmax, ymax min(W, xmax), min(H, ymax) if xmax xmin or ymax ymin: continue xc (xmin xmax) / 2 / W yc (ymin ymax) / 2 / H bw (xmax - xmin) / W bh (ymax - ymin) / H # 保留 6 位小数避免精度损失导致框偏移 lines.append(f{cid} {xc:.6f} {yc:.6f} {bw:.6f} {bh:.6f}) # 空标注图也写空文件保持图片与标签一一对应 out_file out_dir / (xml_path.stem .txt) out_file.write_text(\n.join(lines)) if __name__ __main__: voc_to_yolo(VOC/Annotations, VOC/JPEGImages, YOLO/labels)四个边界坑分别是第一Image.open可能因为图片损坏抛异常必须 try 掉否则整个转换中断第二CLASS_MAP 的顺序就是最终 class_id一旦和 data.yaml 里的 names 列表顺序不一致训练标签全错第三坐标裁剪到[0, W]和[0, H]内因为有些 VOC 标注的 xmax 会等于 W1 这种越界值不裁会产生大于 1 的归一化值第四空标注图写空 TXT 而不是跳过因为 YOLO 训练时如果某张图没有对应 label 文件部分版本会直接报错或静默忽略写空文件最稳妥。3. 用 YOLOv8 在本地跑通 7513 张混凝土缺陷训练环境、配置、首轮结果3.1 Anaconda 环境配置与 ultralytics 安装混凝土缺陷检测数据集要跑 YOLOv8环境这块最常见的翻车是 CUDA 版本和 PyTorch 不匹配导致训练时 GPU 用不上、速度慢十倍。我一般用 Anaconda 建独立环境避免和系统里的其他 PyTorch 项目打架。# 创建 Python 3.10 环境3.10 对 ultralytics 兼容性最稳 conda create -n concrete_yolo python3.10 -y conda activate concrete_yolo # 安装 PyTorchCUDA 11.8 版本按自己显卡驱动选 pip install torch2.1.0 torchvision0.16.0 --index-url https://download.pytorch.org/whl/cu118 # 安装 ultralytics pip install ultralytics8.1.0 # 验证 GPU 是否可用 python -c import torch; print(torch.cuda.is_available(), torch.cuda.get_device_name(0))参数说明Python 3.10 是当前 ultralytics 8.x 测试最充分的版本CUDA 11.8 对应驱动版本 520 以上如果你的驱动是 470 系列改用 cu117 的 index-urltorch.cuda.is_available()返回 True 才算环境通了。如果返回 False先nvidia-smi看驱动再nvcc -V看 CUDA toolkit两者版本要对得上。这一步不通后面训练全在 CPU 上跑7513 张图一个 epoch 可能要几小时。3.2 data.yaml 配置与 7 类别映射YOLOv8 训练靠一个 data.yaml 指定数据路径和类别名这个文件写错训练直接报KeyError或者类别数不匹配。# concrete_defect.yaml path: /home/user/concrete_dataset # 数据集根目录 train: images/train # 训练集图片相对路径 val: images/val # 验证集图片相对路径 test: images/test # 测试集可选 nc: 7 # 类别数必须和标题的 7 类别一致 names: 0: crack 1: spalling 2: exposed_rebar 3: honeycomb 4: void 5: seepage 6: hole关键点nc必须等于 names 列表长度且 names 的顺序必须和 YOLO TXT 里 class_id 的映射完全一致。如果你是从 VOC 转过来的CLASS_MAP 里 crack 是 0这里 names 的 0 也必须是 crack。路径用绝对路径最稳相对路径容易因为工作目录不同找不到文件。7513 张图按 8:1:1 划分训练集约 6000 张验证集 750 张测试集 750 张这个比例对小数据集够用。3.3 首轮训练命令与关键参数环境通了、yaml 写好了用下面这条命令开训。我一般先用 yolov8n 小模型跑一轮确认流程通了再换 yolov8m 或 yolov8l 提精度。yolo detect train \ dataconcrete_defect.yaml \ modelyolov8n.pt \ epochs100 \ imgsz640 \ batch16 \ lr00.01 \ lrf0.01 \ patience20 \ device0 \ workers8 \ projectconcrete_runs \ nameexp1参数逐个说modelyolov8n.pt是预训练权重会自动下载小模型适合先验证流程epochs100配合patience2020 轮验证指标不涨就早停省时间imgsz640是 YOLOv8 默认输入尺寸混凝土缺陷目标通常不大640 够用如果裂缝特别细可以提到 1024但显存翻倍batch16在 8G 显存上跑 640 尺寸比较稳显存不够降到 8lr00.01是初始学习率lrf0.01是最终学习率系数余弦退火到 0.0001device0指定第一块 GPUworkers8是数据加载线程数按 CPU 核数调太多反而拖慢。训练开始后看第一屏输出重点确认三件事nc7是否显示正确、训练集和验证集图片数是否和你划分的一致、AMP是否开启混合精度能省显存。如果nc显示的不是 7回去查 data.yaml。如果图片数是 0查路径。3.4 训练过程指标解读与首轮结果判断YOLOv8 训练时终端会打印每轮的 box_loss、cls_loss、dfl_loss 和 mAP50、mAP50-95。混凝土缺陷检测首轮训练box_loss 从 1.5 左右开始降cls_loss 从 3 左右开始降正常情况 30 轮内 mAP50 能到 0.5 以上。如果 box_loss 一直不降检查标注框是否归一化正确如果 cls_loss 震荡剧烈可能是类别不平衡7 个类别里某些类别样本太少。训练完在concrete_runs/exp1/weights/下会有best.pt和last.ptbest.pt 是验证集指标最好的权重部署用这个。results.png里有完整的 loss 和 mAP 曲线confusion_matrix.png看类别混淆情况如果裂缝和剥落互相误检严重说明这两个类别视觉特征接近需要加样本或做针对性增强。4. 混凝土缺陷检测训练避坑5 个血泪踩坑记录4.1 坑一mAP 虚高但实际检测全是误检现象验证集 mAP50 跑到 0.85但拿真实巡检图测试满屏都是框背景墙面被识别成缺陷。原因训练集和验证集来自同一批图像分布一致但真实场景的光照、角度、纹理差异大。另外验证集里负样本无缺陷图太少模型没学会抑制背景。解决从 7513 张里挑出无缺陷的纯背景图按 10% 到 20% 比例混进训练集作为负样本验证集也要包含真实场景图不能只用数据集自带的。训练时开mosaic1.0和mixup0.1增强背景多样性。4.2 坑二小目标裂缝漏检严重现象大块剥落、孔洞检测很准但细长裂缝几乎检不到mAP 里裂缝类别垫底。原因裂缝在 640 尺寸下可能只有几个像素宽YOLOv8 的 P3 特征图下采样 8 倍后细裂缝特征丢失。解决把imgsz提到 1024 或 1280让裂缝占据更多像素或者改用 yolov8m 以上模型特征提取能力更强还可以在 data.yaml 里对裂缝类别做过采样复制裂缝样本多的图进训练集。如果显存不够用batch4配合imgsz1024。4.3 坑三类别 id 错位导致训练标签全错现象训练 loss 正常下降但推理时把裂缝识别成渗水类别完全对不上。原因VOC 转 YOLO 时 CLASS_MAP 的顺序和 data.yaml 里 names 的顺序不一致比如转换时 crack 是 0但 yaml 里 0 写成了 spalling。解决转换脚本和 data.yaml 用同一份类别定义最好把类别列表抽成一个单独的classes.txt两边都读这个文件。转换完抽 10 张图用yolo detect predict可视化人工核对框和类别对不对。4.4 坑四训练中断后 resume 报错现象训练到第 50 轮断电想用resumeTrue接着训结果报FileNotFoundError或直接从头开始。原因YOLOv8 的 resume 依赖last.pt和优化器状态如果last.pt没保存完整或者 project/name 路径变了resume 找不到。解决训练时加save_period10每 10 轮存一次检查点resume 时用yolo detect train resume modelconcrete_runs/exp1/weights/last.pt显式指定 last.pt 路径不要只写resumeTrue。4.5 坑五验证集指标波动大同一模型两次评估结果不同现象同一个 best.pt跑两次yolo detect valmAP50 差了 0.05。原因验证时数据加载有随机性特别是开了augmentTrue的话每次验证的增强不同。另外batch大小影响 BN 层统计。解决验证时固定augmentFalsebatch1或固定值seed42。如果还波动说明验证集太小750 张里某些类别只有几十张统计噪声大考虑扩大验证集或做交叉验证。5. 从 7513 张到产线可用提升混凝土缺陷检测精度的三个进阶技巧5.1 用 SAHI 切片推理救回小目标YOLOv8 在 640 尺寸下对细裂缝漏检除了提输入尺寸还有一个更省显存的方案SAHISlicing Aided Hyper Inference切片推理。原理是把大图切成重叠的小块分别推理再合并结果小目标在切片里相对变大检测率明显提升。安装pip install sahi推理代码如下。from sahi import AutoDetectionModel from sahi.predict import get_sliced_prediction # 加载训练好的 YOLOv8 权重 detection_model AutoDetectionModel.from_pretrained( model_typeyolov8, model_pathconcrete_runs/exp1/weights/best.pt, confidence_threshold0.25, devicecuda:0 ) # 切片推理slice 尺寸 640重叠 20% result get_sliced_prediction( test_wall.jpg, detection_model, slice_height640, slice_width640, overlap_height_ratio0.2, overlap_width_ratio0.2 ) result.export_visuals(export_dirsahi_output/)参数说明slice_height和slice_width设成和训练 imgsz 一致640 或 1024overlap比例 0.2 是经验值太小会漏掉跨切片的裂缝太大推理变慢confidence_threshold先设 0.25产线再按误检率调。SAHI 的代价是推理时间增加 3 到 5 倍适合离线巡检图批量处理实时视频流要权衡。5.2 置信度门限与 NMS 参数的产线调法训练完的模型直接部署误检率通常偏高。产线调优主要动两个参数置信度门限conf和 NMS 的 IoU 阈值iou。混凝土缺陷检测里裂缝细长两个裂缝框的 IoU 容易超过 0.5 被 NMS 误合并所以iou要调高到 0.6 到 0.7而背景误检多的话conf从 0.25 提到 0.4 到 0.5。yolo detect predict \ modelconcrete_runs/exp1/weights/best.pt \ sourcetest_images/ \ conf0.4 \ iou0.65 \ imgsz1024 \ saveTrue调参方法准备 50 张有代表性的测试图人工标好真实缺陷然后网格搜索 conf 从 0.2 到 0.6、iou 从 0.5 到 0.75算 F1 分数取最高的组合。别凭感觉设不同数据集最优值差很多。5.3 用混淆矩阵定位类别混淆针对性补数据训练完的confusion_matrix.png是最有价值的诊断工具。如果裂缝和渗水互相混淆严重说明这两个类别在灰度纹理上接近模型分不开。解决办法不是调参是补数据专门找裂缝和渗水同时出现的图让模型学到区分特征或者在 data.yaml 里给这两个类别加权但 YOLOv8 不直接支持类别权重得改损失函数或用采样策略。我一般会做一轮错误分析把验证集里误检的图挑出来按类别分组看是标注错误、特征接近还是样本太少。7513 张里如果某个类别只有 200 张而其他类别有 2000 张这个类别 mAP 低是必然的补到 800 张以上再训。这套流程走下来混凝土缺陷检测从数据集到产线可用的模型大概两到三周迭代。希望帮到你。本文还有配套的精品资源点击获取
02
RELATED NEWS

相关资讯

更多网站建设与数字化升级内容

03
WHY YAOTU

想打造同款高转化官网?

懂行业、懂生意,从建站到增长一站式陪跑

◈

场景化定制

不做模板站,围绕你的业务场景量身设计,小众不撞款。

◐

营销型架构

以转化目标组织内容与路径,让官网真正带来询盘。

▲

全周期服务

设计、开发、运营、运维一体,上线只是开始。

免费获取你的建站方案

留下需求,专属顾问 24 小时内为你输出方案建议。