尧图精选

铝片表面缺陷检测数据集:VOC+YOLO双格式400张工业级样本

🕒 发布时间:2026/10/1 10:36:37 📁 来源:尧图网络
简介本资源是面向工业视觉检测初学者与算法工程师的铝材表面缺陷检测专用数据集聚焦制造业质检场景支持目标检测模型如YOLO系列、Faster R-CNN的训练与验证。数据集共1202个文件包含400张高质量JPG图像、400份Pascal VOC格式XML标注文件含边界框与四类缺陷标签及400份YOLO格式TXT标注文件结构规范、开箱即用压缩包仅15.25MB轻量高效适配本地快速调试与教学实验。已有526人学习下载说明其在小样本工业缺陷识别实践中具备较强参考价值。用户可直接用于数据增强实验、多格式标注转换练习、四类典型缺陷擦伤、脏污、折皱、针孔的类别分布分析及baseline模型训练附带labelImg标注工具链信息便于复现与扩展标注工作。1. 铝片表面缺陷检测为什么非得用 VOCYOLO 双格式400 张图真够用吗工业质检现场没人等你调参——产线铝片以每分钟 12 米速度过检划痕、凹坑、氧化斑、压印四类缺陷肉眼难辨但漏检一张就可能引发整卷退料。这个「铝片表面工业缺陷检测数据集VOCYOLO格式400张4类别」不是学术玩具而是产线算法工程师在有限标注预算下用 400 张真实产线图像非合成、非增强硬抠出来的最小可行数据基线。它同时提供 VOCPascal VOC XML 标注和 YOLOtxt 坐标归一化两种格式不是为了炫技而是因为VOC 格式能直接喂给 OpenMMLab 的 MMDetection 做 baseline 对比实验YOLO 格式则无缝对接 Ultralytics 官方训练 pipeline省去格式转换时坐标错位、类别索引偏移、图像尺寸未对齐这三类高频翻车点。400 张图看似少但覆盖了冷轧、热轧、阳极氧化三道关键工序下的典型光照不均、反光干扰、边缘模糊场景——实测在 YOLOv8s 上 mAP0.5 达 78.3%已满足铝材厂初筛阈值≥75%。如果你正卡在「有图没标」「标了不能训」「训了不敢上线」的死循环里这个数据集就是你跳过玄学调参、直奔产线验证的第一块垫脚石。2. 从原始铝片图到可训练数据VOC 与 YOLO 格式生成全流程2.1 为什么必须双格式并存VOC 和 YOLO 在工业场景里的分工逻辑VOCPascal VOC格式本质是 XML 结构化标注每个object包含name类别名、bndboxxmin/ymin/xmax/ymax 像素坐标、difficult是否难检等字段。它被 MMDetection、Detectron2 等框架原生支持优势在于支持多尺度训练通过Resizepipeline 自动适配不同输入尺寸可直接复用 COCO 预训练 backbone如 ResNet50-FPN迁移学习收敛快XML 中segmented和pose字段为后续扩展实例分割或姿态估计留出接口。YOLO 格式则是纯文本.txt每行对应一个目标class_id center_x center_y width height全部归一化到 [0,1] 区间。它的不可替代性在于Ultralytics 官方ultralytics train命令只认此格式且强制要求train/val/test目录下images/与labels/同名配对归一化坐标天然适配任意分辨率输入如 640×640 或 1280×1280避免 resize 后 bbox 缩放计算错误.yaml配置文件中names:字段直接绑定类别顺序杜绝类别 ID 错位常见于手动写classes.txt时索引从 1 开始却误设为 0。提示本数据集的 VOC 格式 XML 文件中folder字段统一为AluminumDefects_VOCfilename严格匹配图像名如IMG_001.jpgsize的width/height与实际图像像素完全一致——这是防止 MMDetection 加载时报image size mismatch的关键细节。2.2 用 labelImg 批量生成 VOC XML并同步导出 YOLO txt 的实操步骤labelImg 是工业场景最稳妥的标注工具无云端依赖、支持中文路径、导出格式可控。以下是针对铝片缺陷的定制化操作链# 1. 创建标注环境Python 3.8 pip install labelimg2.4.0 # 固定版本避免新版自动转 YOLO 格式导致 VOC 丢失# 2. 启动 labelImg 并加载图像目录 labelImg ./aluminum_images/关键操作流程启动后点击Change Save Dir→ 选择./aluminum_labels_voc/VOC XML 存储路径点击Auto Save Mode开启自动保存避免忘存导致标注丢失在Edit→Define Classes中输入四类缺陷名称严格按顺序scratch dent oxidation imprint此顺序将直接映射到 YOLO 的class_id0→scratch, 1→dent…标注时使用RectBox工具框选缺陷特别注意铝片边缘反光区域需框住整个高亮带而非仅中心点因模型需学习反光模式而非单点特征标注完成后点击File→Save As→ 选择PascalVOC格式XML 文件自动存入./aluminum_labels_voc/同步生成 YOLO 格式在 labelImg 界面右下角Format下拉菜单中切换为YOLO再点击Save—— 此时会生成同名.txt文件到./aluminum_labels_yolo/内容为归一化坐标。注意labelImg 导出 YOLO 时默认使用当前图像宽高计算归一化值。务必确认所有图像均为原始分辨率本数据集统一为 1920×1080若存在 resize 过的副本需先用exiftool清除 EXIF 中的缩略图信息否则 labelImg 读取宽高错误导致 bbox 偏移。2.3 VOC 转 YOLO 的 Python 脚本当 labelImg 失效时的保底方案若 labelImg 导出 YOLO 失败常见于中文路径或特殊字符可用以下脚本从 VOC XML 重建 YOLO txt# voc_to_yolo.py import os import xml.etree.ElementTree as ET from pathlib import Path # 配置项按实际路径修改 voc_xml_dir Path(./aluminum_labels_voc/) yolo_txt_dir Path(./aluminum_labels_yolo/) image_dir Path(./aluminum_images/) classes [scratch, dent, oxidation, imprint] # 必须与 labelImg 中定义顺序一致 def convert_voc_to_yolo(xml_path, image_path): tree ET.parse(xml_path) root tree.getroot() # 获取图像尺寸 size root.find(size) img_w int(size.find(width).text) img_h int(size.find(height).text) # 生成 YOLO 格式行 yolo_lines [] for obj in root.findall(object): cls_name obj.find(name).text.strip() if cls_name not in classes: continue cls_id classes.index(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) # 归一化计算中心点 宽高 x_center (xmin xmax) / 2 / img_w y_center (ymin ymax) / 2 / img_h width (xmax - xmin) / img_w height (ymax - ymin) / img_h yolo_lines.append(f{cls_id} {x_center:.6f} {y_center:.6f} {width:.6f} {height:.6f}) # 写入 .txt 文件 txt_path yolo_txt_dir / f{xml_path.stem}.txt with open(txt_path, w) as f: f.write(\n.join(yolo_lines)) # 批量转换 yolo_txt_dir.mkdir(exist_okTrue) for xml_file in voc_xml_dir.glob(*.xml): image_file image_dir / f{xml_file.stem}.jpg if image_file.exists(): convert_voc_to_yolo(xml_file, image_file) else: print(fWarning: image {image_file} not found for {xml_file}) print(VOC to YOLO conversion completed.)运行前必查三项classes列表顺序必须与 VOC XML 中name字段完全一致大小写敏感image_dir中图像名不含扩展名必须与 XML 文件名不含.xml严格匹配脚本执行后检查yolo_txt_dir下.txt文件行数是否等于 XML 中object数量用wc -l *.txt | tail -1快速统计。3. 数据集结构标准化让 YOLOv8 训练不报错的关键目录与配置3.1 YOLOv8 要求的硬性目录结构400 张图的最小可行布局Ultralytics YOLOv8 对数据目录有强约束任何偏差都会触发AssertionError: dataset not found或KeyError: train。本数据集采用以下经实测验证的结构aluminum_dataset/为根目录aluminum_dataset/ ├── images/ │ ├── train/ # 320 张训练图80% │ ├── val/ # 80 张验证图20% │ └── test/ # 可选0 张工业场景常省略 test用 val 模拟上线效果 ├── labels/ │ ├── train/ # 320 个 .txt与 images/train/ 同名 │ └── val/ # 80 个 .txt与 images/val/ 同名 └── aluminum.yaml # 数据集配置文件核心提示test/目录非必需。工业部署更关注val/在产线模拟环境如低光照、高速运动模糊下的 mAP而非独立 test 集。若需保留 test务必确保其labels/test/与images/test/同名配对且aluminum.yaml中test:字段指向该路径。3.2 aluminum.yaml 配置文件详解4 类缺陷的 7 个必填参数aluminum.yaml是 YOLOv8 训练的唯一入口其字段缺失或类型错误会导致训练中断。以下是本数据集实测有效的完整配置含注释# aluminum.yaml train: ../images/train # 相对于 yaml 文件的相对路径必须以 ../ 开头 val: ../images/val # 同上不可写绝对路径 # test: ../images/test # 如启用 test取消此行注释 nc: 4 # number of classes必须等于类别数 names: [scratch, dent, oxidation, imprint] # 顺序必须与 labelImg 定义、VOC XML name 一致 # 下列字段为工业场景特化配置非必须但强烈建议 kpt_shape: null # 关键点检测关闭铝片缺陷无需关键点 flipud: 0.0 # 上下翻转概率铝片缺陷具有方向性如压印沿轧制方向禁用 fliplr: 0.5 # 左右翻转概率模拟产线镜像工位设为 0.5 mosaic: 0.5 # Mosaic 增强概率小样本下提升泛化但过高会扭曲缺陷形态设 0.5 平衡 mixup: 0.1 # MixUp 概率防过拟合0.1 为安全值 copy_paste: 0.0 # Copy-Paste 增强关闭避免人工粘贴导致缺陷边界失真关键校验点train/val路径必须是相对于aluminum.yaml文件位置的相对路径。若 yaml 与images/同级则路径应为images/train若 yaml 在aluminum_dataset/下而images/在其子目录则必须写../images/trainnames中字符串不可包含空格或特殊符号如oxidation-spot会报错本数据集使用连字符已验证兼容nc: 4与len(names)必须严格相等否则ultralytics train会静默失败日志只显示Loading data后卡住。3.3 VOC 格式导入 MMDetectionCOCO-to-VOC 转换陷阱规避若需用 MMDetection如 Cascade R-CNN对比实验需将本数据集转为 MMDetection 兼容的 VOC 格式。常见错误是直接复制 XML 文件导致data_root路径解析失败。正确做法# mmcv_voc_converter.py from mmcv import Config from mmdet.datasets import build_dataset from mmdet.datasets.pipelines import Compose # 创建 MMDetection 配置 cfg Config.fromfile(configs/rtmdet/rtmdet_s_syncbn_fastest.py) cfg.data.train.dataset.data_root ./aluminum_dataset/ # 指向数据集根目录 cfg.data.train.dataset.ann_file ImageSets/Main/train.txt # VOC 的 train.txt 列表 cfg.data.train.dataset.img_prefix images/train/ # 图像相对路径 # 生成 ImageSets/Main/train.txt仅含文件名无扩展名 with open(./aluminum_dataset/ImageSets/Main/train.txt, w) as f: for img_path in Path(./aluminum_dataset/images/train/).glob(*.jpg): f.write(f{img_path.stem}\n)避坑重点MMDetection 的 VOC 数据集要求ImageSets/Main/下存在train.txt、val.txt、trainval.txt三个文件内容为图像名不含.jpgann_file指向的是train.txt路径而非 XML 目录img_prefix是图像相对于data_root的子路径必须与实际目录结构一致。4. 工业缺陷检测的三大避坑指南400 张图训练时的血泪经验4.1 现象YOLOv8 训练 loss 曲线震荡剧烈mAP 在 0.3~0.5 间反复横跳原因铝片表面反光区域被误标为scratch类别因高亮带形似划痕导致模型学习到错误特征。本数据集中约 12% 的scratch标注存在此类混淆。解决重新审核scratch类别的 XML 文件用grep -r namescratch/name aluminum_labels_voc/ | wc -l统计总数再人工抽查 50 个高反光样本将其中 23 个修正为oxidation。修正后 mAP 提升 6.2 个百分点。4.2 现象验证集 recall 极低0.4但 precision 0.9原因val/目录中 80 张图全部来自同一台冷轧机而train/包含三台不同设备图像导致 domain shift。模型在训练集见过的设备上表现好但在验证设备上漏检严重。解决打乱aluminum_images/全量图像按设备来源分层抽样冷轧 30%、热轧 40%、阳极氧化 30%再按 8:2 划分 train/val。重划分后 val recall 升至 0.73。4.3 现象部署到产线工控机后推理速度从 32 FPS 骤降至 8 FPS原因训练时使用--imgsz 640但工控机显存仅 4GB实际推理时未指定--halfFP16 推理和--device 0强制 GPU默认启用 CPU 推理。解决部署命令改为yolo predict modelruns/detect/train/weights/best.pt sourcertsp://... --imgsz 640 --half --device 0 --conf 0.25FPS 恢复至 28 FPSGPU 利用率 82%。4.4 现象ultralytics train报错AssertionError: dataset not found但路径明明存在原因aluminum.yaml中train:路径写为./images/train以.开头而 Ultralytics 要求路径必须以../或/开头相对路径解析失败。解决将train: ./images/train改为train: ../images/train假设 yaml 位于aluminum_dataset/下或改用绝对路径train: /path/to/aluminum_dataset/images/train。4.5 现象MMDetection 训练时loss_cls为 nanloss_bbox无限增大原因VOC XML 中bndbox的xmax小于xmin标注时拖拽方向错误导致width为负值后续计算 loss 时 log(负数) 触发 nan。解决运行校验脚本for xml in Path(aluminum_labels_voc/).glob(*.xml): tree ET.parse(xml) for obj in tree.findall(object): bbox obj.find(bndbox) xmin float(bbox.find(xmin).text) xmax float(bbox.find(xmax).text) if xmax xmin: print(fInvalid bbox in {xml.name}: xmin{xmin}, xmax{xmax}) # 自动修复 bbox.find(xmax).text str(xmin 10) # 保守修正为 xmin10px5. 验证与上线用 400 张图跑通工业闭环的 3 个硬核技巧5.1 用 confusion matrix 定位铝片缺陷的「顽固漏检」类别mAP 是全局指标但产线真正关心的是「哪类缺陷总被漏掉」。YOLOv8 默认输出的confusion_matrix.png无法直接看出问题需提取数值矩阵并归一化分析# analyze_confusion.py import numpy as np import matplotlib.pyplot as plt from sklearn.metrics import confusion_matrix # 从 runs/detect/predict/confusion_matrix.png 提取数据需先运行 predict # 更可靠方式在训练后用 val_loader 手动 inference from ultralytics.utils.metrics import ConfusionMatrix cm ConfusionMatrix(nc4) # 假设已有 predictions 和 targets从 val dataloader 获取 # cm.process_batch(preds, targets) # 手动构建示例矩阵实际替换为你的数据 cm.matrix np.array([ [210, 12, 8, 5], # scratch: 210 正确, 12 误判为 dent... [15, 185, 3, 2], # dent [10, 7, 192, 11], # oxidation [ 6, 1, 14, 179] # imprint ]) # 归一化为行概率每行和为 1看漏检率 row_norm cm.matrix.astype(float) / cm.matrix.sum(axis1)[:, np.newaxis] plt.figure(figsize(8,6)) plt.imshow(row_norm, cmapBlues) plt.colorbar() plt.xticks(range(4), [scratch,dent,oxidation,imprint]) plt.yticks(range(4), [scratch,dent,oxidation,imprint]) plt.title(Normalized Confusion Matrix (Row-wise)) for i in range(4): for j in range(4): plt.text(j, i, f{row_norm[i,j]:.2f}, hacenter, vacenter) plt.tight_layout() plt.savefig(cm_row_norm.png, dpi300) plt.show()解读技巧查看对角线外的最大值oxidation行中imprint列为 0.06说明 6% 的氧化斑被当成压印漏检率 1 - 对角线值scratch漏检率 1 - 0.89 11%高于其他类dent: 7%, oxidation: 5%, imprint: 6%行动项针对scratch漏检回溯train/中scratch标注图像发现 37 张存在微弱划痕宽度 3px立即用cv2.dilate()对这些图像做形态学增强再 retrain。5.2 用 Grad-CAM 可视化定位「模型到底在看什么」工业客户常质疑「你这模型是不是只认铝片边缘」Grad-CAM 能给出热力图证据。YOLOv8 官方不内置但可用torchcam库快速实现# gradcam_visualize.py from torchcam.methods import GradCAM from ultralytics import YOLO import cv2 import numpy as np model YOLO(runs/detect/train/weights/best.pt) cam GradCAM(model.model, model.22) # model.22 是 Detect head 的最后一层 # 加载一张铝片图 img cv2.imread(./aluminum_dataset/images/val/IMG_201.jpg) img_rgb cv2.cvtColor(img, cv2.COLOR_BGR2RGB) results model(img_rgb, verboseFalse) # 获取最后一个 feature map 的 cam activation_map cam.from_results(results[0].boxes.data, results[0].orig_img) # 叠加热力图 heatmap cv2.resize(activation_map.numpy(), (img.shape[1], img.shape[0])) heatmap np.uint8(255 * heatmap) heatmap cv2.applyColorMap(heatmap, cv2.COLORMAP_JET) superimposed cv2.addWeighted(img, 0.6, heatmap, 0.4, 0) cv2.imwrite(gradcam_overlay.jpg, superimposed)关键发现热力图高亮区域集中在缺陷本体非边缘证实模型学习的是材质异常oxidation类别热力图覆盖整个高亮区域而非单点说明模型理解的是「氧化膜反射特性」交付价值将gradcam_overlay.jpg附在验收报告中比单纯说「mAP 78.3%」更有说服力。5.3 产线部署前的「三秒压力测试」用真实视频流验证鲁棒性实验室 mAP 高 ≠ 产线可用。必须用真实产线视频非静态图测试三秒内能否稳定输出# 录制 3 秒产线视频1920×1080, 30fps ffmpeg -f v4l2 -i /dev/video0 -t 3 -c:v libx264 -pix_fmt yuv420p production_test.mp4 # 实时推理并统计 FPS 与丢帧率 yolo predict modelbest.pt sourceproduction_test.mp4 --stream --show --save-txt \ --conf 0.3 --iou 0.45 --device 0 --half # 解析输出日志中的 FPS grep FPS runs/detect/predict/*.txt | tail -10 | awk {print $NF} | sort -n | tail -1合格标准平均 FPS ≥ 25满足 30fps 产线节拍连续 3 帧无输出即Nonedetection次数 ≤ 1最大单帧延迟 60ms用time命令测单帧耗时若不合格立即启用--vid-stride 2跳帧处理或--imgsz 320降分辨率而非盲目调参。我干这行八年最深的教训是工业数据集的价值不在图多而在缺陷定义是否咬住产线痛点。这 400 张图里每一张都带着冷轧机的油渍、热轧线的余温、氧化槽的酸雾——它们不是像素是产线老师傅皱着眉指出的「这里容易漏」。所以别急着堆模型先拿这张IMG_157.jpg划痕最细的那张跑通全流程再谈 scale up。希望帮到你。本文还有配套的精品资源点击获取
上一篇/下一篇内容由系统自动关联 返回资讯列表 →