简介:本资源为铝片表面工业缺陷检测数据集,面向从事工业质检、表面缺陷识别方向的算法工程师与深度学习学习者,可用于目标检测模型的训练、验证与算法对比实验。数据集同时提供Pascal VOC与YOLO两种标注格式,包含jpg图片及对应的xml、txt标注文件,标注工具为labelImg,共4个类别:擦伤、脏污、折皱与针孔,各类别框数分别为270、456、124、212,总框数达1062,类别分布较为均衡,便于直接投入训练。压缩包为7z格式,共1202个文件,其中402个txt、400个xml、400个jpg,整体约15.25MB,体积轻量、结构清晰,适合快速下载与本地部署。目前已有526人学习下载,可作为工业缺陷检测入门练手或小样本实验的实用数据支撑。
1. 铝片表面缺陷检测数据集:400 张 VOC+YOLO 双格式到底能干什么
产线上铝片表面缺陷检测,最卡脖子的往往不是模型选型,而是手里没有一份能直接开训的标注数据。这份「铝片表面工业缺陷检测数据集 VOC+YOLO 格式 400 张 4 类别」解决的正是这个起点问题:400 张实拍铝片表面图,覆盖 4 类典型工业缺陷,同时给出 VOC 的 XML 标注和 YOLO 的 TXT 标注两套格式。它适合三类人——想快速跑通 YOLO 训练闭环的算法新手、需要做缺陷检测方案验证的机器视觉工程师、以及拿它当打标模板做数据扩充的产线技术人员。400 张不算大,但胜在类别清晰、双格式齐全,能让你在一个下午内把「数据→训练→推理→看结果」整条链路走通,而不是把时间耗在格式转换和标注清洗上。下面按「先看清数据、再跑通训练、最后避坑调优」的顺序讲透。
2. 拆开这份铝片缺陷数据集:4 类别、双格式与目录结构
2.1 400 张 4 类别意味着什么
先给一个不绕弯的判断:400 张、4 类别,平均每类 100 张左右,这是一个「验证流程够用、直接上产线不够」的规模。它的正确用法是拿来跑通 pipeline、验证标注规范、做 baseline 对比,而不是指望训出一个能直接部署的高精度模型。铝片表面缺陷的常见 4 分类一般是划痕、凹坑、脏污、氧化色差这一类(具体类别名以数据集内classes.txt或 XML 里的name字段为准,拿到手第一件事就是打开确认,别凭猜)。
为什么强调「先确认类别名」?因为 VOC 和 YOLO 两套标注里,类别顺序和拼写必须完全一致,否则训练时会出现「标签对不上、loss 不降」的玄学问题。我一般拿到数据集先跑一段统计脚本,把每类数量、图片尺寸分布、标注框大小分布一次性看清楚,心里有底再动手。
import os, glob import xml.etree.ElementTree as ET from collections import Counter # 统计 VOC 标注里每个类别的框数量 xml_dir = "Annotations" # VOC 的 XML 目录 counter = Counter() for xml_path in glob.glob(os.path.join(xml_dir, "*.xml")): tree = ET.parse(xml_path) root = tree.getroot() for obj in root.findall("object"): name = obj.find("name").text.strip() counter[name] += 1 print("类别分布:", dict(counter)) print("总框数:", sum(counter.values()))这段脚本做三件事:遍历所有 XML、提取每个object的name、用 Counter 汇总。跑完你会得到类似{'scratch': 120, 'pit': 95, ...}的结果。参数说明:xml_dir换成你实际的标注目录;如果某类数量明显偏少(比如低于 50),后面训练时就要考虑过采样或加权。这一步花两分钟,能省掉后面几小时的排查。
2.2 VOC 与 YOLO 格式的差异与转换
VOC 和 YOLO 的核心差异就一句话:VOC 存的是绝对像素坐标(xmin, ymin, xmax, ymax),YOLO 存的是归一化中心点加宽高(cx, cy, w, h),且都是 0~1 之间的小数。很多人转换后训练不收敛,八成是归一化时用错了图片尺寸——XML 里的size字段才是准的,别用你后来 resize 的尺寸去算。
import os from xml.etree import ElementTree as ET classes = ["scratch", "pit", "stain", "discolor"] # 必须与标注一致 xml_dir, out_dir = "Annotations", "labels" os.makedirs(out_dir, exist_ok=True) for xml_file in os.listdir(xml_dir): if not xml_file.endswith(".xml"): continue root = ET.parse(os.path.join(xml_dir, xml_file)).getroot() w = int(root.find("size/width").text) h = int(root.find("size/height").text) lines = [] for obj in root.findall("object"): cls = obj.find("name").text.strip() if cls not in classes: continue b = obj.find("bndbox") xmin, ymin = float(b.find("xmin").text), float(b.find("ymin").text) xmax, ymax = float(b.find("xmax").text), float(b.find("ymax").text) # 归一化:中心点 + 宽高,全部除以原图尺寸 cx, cy = (xmin + xmax) / 2 / w, (ymin + ymax) / 2 / h bw, bh = (xmax - xmin) / w, (ymax - ymin) / h lines.append(f"{classes.index(cls)} {cx:.6f} {cy:.6f} {bw:.6f} {bh:.6f}") with open(os.path.join(out_dir, xml_file.replace(".xml", ".txt")), "w") as f: f.write("\n".join(lines))逻辑说明:先读原图宽高,再对每个框做归一化,类别名映射成索引。参数说明:classes列表顺序决定 YOLO 标签里的数字,训练时的data.yaml必须用同样顺序;:.6f保留 6 位小数是 YOLO 官方推荐精度,别省。转换完随手抽查几个 TXT,确认数值都在 0~1 之间,出现大于 1 的就是坐标越界,多半是标注框超出了图片边界。
2.3 目录该怎么摆
标准 YOLO 训练目录长这样,照着摆不会错:
dataset/ ├── images/ │ ├── train/ # 约 320 张 │ └── val/ # 约 80 张 ├── labels/ │ ├── train/ │ └── val/ └── data.yamldata.yaml内容:
path: ./dataset train: images/train val: images/val nc: 4 names: ["scratch", "pit", "stain", "discolor"]注意:nc必须等于类别数,names顺序必须和转换脚本里的classes完全一致。图片和标签文件名要一一对应(a.jpg对a.txt),少一个标签文件,训练时那张图会被当成负样本,白白污染数据。
3. 用这份数据集跑通 YOLO 训练:从环境到第一个权重
3.1 环境配置与最小可跑命令
环境这块,YOLOv8 用 Anaconda 建个干净环境最省心,别在 base 里折腾。核心就三样:Python 3.9+、PyTorch(带 CUDA 版本按你显卡选)、ultralytics。
conda create -n alu_defect python=3.10 -y conda activate alu_defect pip install torch torchvision --index-url https://download.pytorch.org/whl/cu118 pip install ultralytics参数说明:cu118对应 CUDA 11.8,你的驱动版本低就换cu117或纯 CPU 版;ultralytics装完自带yolo命令行。验证是否装好:
yolo checks能打印出环境信息、检测到 GPU 就说明通了。这一步翻车的典型是 PyTorch 和 CUDA 版本对不上,torch.cuda.is_available()返回 False,训练时默默跑在 CPU 上,慢到你以为卡死了。
3.2 训练参数怎么设
400 张的小数据集,直接上大模型容易过拟合,我一般从yolov8n(nano)起步,先看流程通不通,再考虑换s或m。
yolo detect train \ data=dataset/data.yaml \ model=yolov8n.pt \ epochs=100 \ imgsz=640 \ batch=16 \ lr0=0.01 \ patience=20 \ project=runs/alu \ name=exp1参数说明:epochs=100对小数据集够用,配合patience=20早停,验证集 20 轮不涨就停,省时间;imgsz=640是默认输入尺寸,铝片缺陷如果很小(比如细划痕),可以提到 1024,但显存和速度要权衡;batch=16显存不够就降到 8 或 4;lr0=0.01是初始学习率,小数据集别设太大,否则 loss 震荡。训练日志里重点盯mAP50和mAP50-95两个指标,前者宽松后者严格,两个都在涨才健康。
3.3 推理与结果查看
训练完权重在runs/alu/exp1/weights/best.pt,拿它跑推理:
yolo detect predict \ model=runs/alu/exp1/weights/best.pt \ source=dataset/images/val \ conf=0.25 \ save=True参数说明:conf=0.25是置信度门限,漏检多就降到 0.15,误检多就提到 0.4,这个值没有标准答案,得看你的业务更怕漏还是更怕误;save=True把画框结果存到runs/detect/predict。跑完打开图看,重点看三类问题:框歪了(标注问题)、同类缺陷框大小差异巨大(数据分布问题)、背景被误检(负样本不足)。这一步是判断数据集质量最直接的方式,比看任何指标都直观。
4. 铝片缺陷检测的避坑清单:5 个我踩过的坑
4.1 坑一:类别名大小写不一致导致标签全丢
现象:训练能跑,但 loss 一直不降,mAP接近 0。原因:XML 里写的是Scratch,data.yaml里写的是scratch,转换脚本按小写匹配,结果所有框被if cls not in classes过滤掉,标签文件全是空的。解决:转换前先print(set(所有name))看真实拼写,统一成一种写法再转。空标签文件是隐形杀手,训练时不会报错,只会让你怀疑人生。
4.2 坑二:图片和标签没对齐
现象:训练报No labels found,或者某张图明明有缺陷却检测不出。原因:images/train里有a.jpg,但labels/train里没有对应的a.txt,或者文件名大小写、后缀不一致。解决:写个校验脚本,遍历图片目录,检查每个图是否有同名 TXT,缺的列出来补上或删图。这个检查我每次训练前必跑,两行代码的事。
4.3 坑三:小目标缺陷被 resize 吃掉
现象:大缺陷检得挺好,细划痕、小凹坑全漏。原因:原图可能是 2000+ 像素,训练时统一 resize 到 640,小缺陷缩到几个像素,特征直接没了。解决:要么提高imgsz到 1024/1280,要么用切片推理(把大图切小块分别检测再合并)。铝片细划痕这类小目标,imgsz提到 1024 通常有明显改善,代价是显存翻倍。
4.4 坑四:验证集和训练集分布不一致
现象:训练集指标很高,验证集一塌糊涂。原因:随机划分时,某类缺陷恰好全被分到训练集,验证集里没有这类样本。解决:按类别分层划分,保证每类在训练集和验证集里都有合理比例。400 张的规模,验证集留 20%(约 80 张),每类至少留 15~20 张。
4.5 坑五:拿 400 张直接上产线
现象:实验室 mAP 0.9,产线上误检漏检一堆。原因:400 张覆盖不了真实产线的光照变化、铝片批次差异、相机角度变化。解决:把这份数据集当 baseline 和标注模板,产线部署前用现场数据做增量训练,至少补到每类几百张、覆盖不同光照和批次。400 张能证明方案可行,证明不了能上线。
5. 把 400 张用出 4000 张的效果:数据增强与增量迭代
小数据集的出路不是硬训,而是「增强 + 迭代」。YOLO 训练时自带在线增强(mosaic、hsv、flip等),默认就开着,但针对铝片缺陷,我一般会手动调几个参数。hsv_h、hsv_s、hsv_v控制色调、饱和度、亮度扰动,铝片表面反光敏感,hsv_v可以适当调大让模型适应不同光照;degrees旋转角度别开太大,工业缺陷有方向性,转 180 度可能把划痕方向语义搞乱;mosaic对小数据集提升明显,但训练后期建议关掉(close_mosaic),让模型在真实分布上收敛。
离线增强也值得做:用imgaug或albumentations对训练集做翻转、亮度调整、加噪声,把 320 张扩到 1000+ 张再训。但要注意,增强出来的图不能进验证集,否则指标虚高。
更关键的是增量迭代闭环:第一版模型训完,拿它去推理一批没标注的现场图,把高置信度的预测当预标注,人工修正后加入训练集,再训第二版。这个循环跑两三轮,效果提升往往比换更大模型还明显。我自己的习惯是每轮迭代都固定验证集不变,这样指标才可比。
最后说个验证技巧:别只看mAP,把混淆矩阵调出来看(训练完自动生成confusion_matrix.png),哪两类互相误判一目了然。铝片缺陷里「脏污」和「氧化色差」经常混,看到混淆矩阵里这两个数高,就知道该补这两类的区分性样本了。
这套流程我跑过不止一次,最深的教训是:数据集小不可怕,可怕的是标注不规范还硬训。拿到任何一份 VOC+YOLO 数据集,先花半小时做统计和校验,比急着敲训练命令值钱得多。希望帮到你。
本文还有配套的精品资源,点击获取