铝片表面工业缺陷目标检测数据集:从产线痛点到YOLO可训练方案
发布时间:2026/9/28 14:58:19来源:尧图网络
简介这份数据集面向从事机器视觉与工业质检的研究者、算法工程师及图像处理初学者提供铝片表面缺陷目标检测的标准化训练素材可用于针孔、擦伤、脏污、褶皱四类常见缺陷的自动识别与分类研究。压缩包共402个文件以400张jpg缺陷图像和2个json标注文件为主整体约15.74MB图像用于模型训练与验证json文件按COCO格式记录缺陷位置与类型并划分为train与valid两部分便于参数优化与泛化能力评估。目前已有161人学习下载。借助该数据集读者可快速搭建缺陷检测实验流程完成图像预处理、特征提取与分类器训练并针对样本规模有限的情况开展旋转、缩放、裁剪等数据增强从而提升检测准确率与鲁棒性为生产线自动化质检与质量控制提供可复用的实验基础。1. 铝片表面工业缺陷目标检测数据集从产线痛点到可复现方案铝片在冲压、轧制、搬运环节里出现的划痕、凹坑、脏污、起皮靠人眼在高速产线末端盯屏幕漏检和误检几乎是必然的。我接触过的一个铝片外观检工位三个班次轮换同一批料不同班次判级结果能差出两成这种玄学一致性根本没法交付给下游客户。铝片表面工业缺陷目标检测数据集要解决的就是把「人眼判级」换成「模型框选分类」这件事的原料问题——没有一批标注规范、缺陷分布贴近真实产线、格式能直接喂给 YOLO 系列训练器的图像后面调参、部署、量化全是空中楼阁。这篇面向的是正在做工业质检落地、手里有相机但还没把数据理顺的工程师也适合刚接手铝片缺陷项目、想先跑通一条最小链路再谈精度的人。目标检测、工业缺陷、数据集这三个词在铝片这个具体载体上会变得非常具体缺陷尺度小、对比度低、正负样本极度不均衡这些特性决定了你不能拿 COCO 那套思路直接套。2. 铝片缺陷数据集长什么样类别定义、采集条件与标注规范2.1 铝片表面缺陷的类别体系怎么定铝片表面缺陷的类别划分直接决定后面模型能不能落地。我一般会先把产线质检标准翻出来把判废项和降级项分开再合并视觉特征相近的类别。常见的铝片缺陷大致分这几类划痕线性、方向性强、灰度突变、凹坑局部亮度凹陷、边缘渐变、脏污不规则斑块、纹理杂乱、起皮片状剥离、边缘锐利、辊印周期性条纹。类别不是越多越好我见过有人把「轻微划痕」和「深度划痕」分成两类结果标注员自己都分不清模型学出来两个类别的混淆矩阵一塌糊涂。常见做法是先把类别压到 5 到 7 类保证任意两个类在 200 张抽样图上标注员一致率能到 90% 以上再考虑细分。类别定义还要考虑缺陷的尺度分布。铝片划痕可能横跨整幅图像长度上千像素宽度只有几个像素凹坑可能只有 20×20 像素。这种尺度跨度意味着你后面选 anchor 或者用 anchor-free 结构时要有心理准备。数据集里如果长条划痕占比过高模型会偏向学线性特征对点状凹坑的召回就会掉。我一般会在类别统计表里把每个类的目标框宽高分布也列出来方便后面选模型输入尺寸。缺陷类别典型视觉特征标注难点建议最小框尺寸划痕线性、方向一致、灰度突变端点界定模糊宽≥4px凹坑局部暗区、边缘渐变与光照不均混淆20×20px脏污不规则斑块、纹理杂与背景纹理混淆15×15px起皮片状、边缘锐利与划痕交叉10×10px辊印周期性条纹与正常纹理混淆整幅周期2.2 采集条件光源、角度与产线速度的取舍铝片是金属表面反光强打光方式不对划痕和背景的对比度能差出一个数量级。我一般会用低角度暗场照明来突出划痕和凹坑因为这类缺陷在明场下容易被镜面反射淹没。但暗场会让脏污这类漫反射缺陷对比度下降所以实际产线往往是明场暗场双光源或者用同轴光加低角度环光的组合。采集时还要固定相机与铝片的相对角度铝片在传送带上会有轻微跳动角度一变同一缺陷的成像差异就很大数据集里如果混入这种抖动样本模型会学得莫名其妙。产线速度决定了运动模糊程度。如果相机曝光时间压不到 200 微秒以内划痕会拖尾标注框就得画得比实际缺陷大这会给后面回归带来噪声。我一般会先做一次运动模糊测试在最高产线速度下拍静止铝片和运动铝片对比划痕宽度变化如果模糊导致宽度增加超过 30%就得换全局快门相机或者加频闪光源。采集数量上每个类别至少 300 到 500 个实例总图数 2000 到 5000 张起步缺陷分布要覆盖不同批次、不同轧制方向、不同光照时段。2.3 标注规范从画框到属性字段的落地细节标注工具用 LabelImg、CVAT 或者 X-AnyLabeling 都行关键是规范要统一。我一般会要求标注员遵守这几条框要贴紧缺陷外接矩形划痕类如果断续按连续段分别标凹坑类如果边缘渐变以肉眼可辨的暗区边界为准脏污类如果面积超过图像 5%要拆成多个框还是整框得在规范里写死。属性字段上我建议至少加两个occlusion是否被遮挡和severity严重程度 1-3这两个字段在后期做难例挖掘和分级报警时非常有用。标注一致性检查不能省。我一般会抽 10% 的图让两个标注员交叉标算 IoU 一致率低于 0.7 的类别就要重新培训。还有一个血泪经验铝片缺陷里「疑似缺陷」和「确证缺陷」一定要分开产线初期经常把反光当脏污标进去这种噪声样本超过 5%模型精度就上不去。标注完成后导出 COCO 格式或 YOLO 格式我一般先存 COCO因为字段全后面转 YOLO 就是几行脚本的事。3. 从原始图到 YOLO 可训练格式转换脚本与四个边界坑3.1 COCO 转 YOLO 的脚本与参数说明铝片缺陷数据集常见标注格式是 COCO JSON但 YOLOv5/v8/v11 训练要的是每张图一个 txt每行class_id x_center y_center width height且坐标要归一化到 0-1。下面这个脚本我用了很多次处理铝片这种小目标时要注意浮点精度别用整数除法。import json import os from pathlib import Path # 输入COCO 格式的 annotations.json 和图片目录 # 输出YOLO 格式的 labels 目录每张图对应一个 txt def coco_to_yolo(coco_json, img_dir, out_label_dir, class_map): with open(coco_json, r, encodingutf-8) as f: data json.load(f) # 建立 image_id 到文件名的映射 img_id_to_info {img[id]: img for img in data[images]} # 按 image_id 分组标注 from collections import defaultdict anns_by_img defaultdict(list) for ann in data[annotations]: anns_by_img[ann[image_id]].append(ann) os.makedirs(out_label_dir, exist_okTrue) for img_id, anns in anns_by_img.items(): info img_id_to_info[img_id] w, h info[width], info[height] # 文件名去掉扩展名YOLO 要求 txt 与图片同名 stem Path(info[file_name]).stem lines [] for ann in anns: # COCO bbox 是 [x_min, y_min, width, height] 绝对像素 x_min, y_min, bw, bh ann[bbox] # 转成中心点归一化坐标 x_c (x_min bw / 2.0) / w y_c (y_min bh / 2.0) / h nw bw / w nh bh / h # 裁剪到 [0,1]防止标注越界导致训练报错 x_c min(max(x_c, 0.0), 1.0) y_c min(max(y_c, 0.0), 1.0) nw min(max(nw, 0.0), 1.0) nh min(max(nh, 0.0), 1.0) cls_id class_map[ann[category_id]] lines.append(f{cls_id} {x_c:.6f} {y_c:.6f} {nw:.6f} {nh:.6f}) with open(os.path.join(out_label_dir, stem .txt), w) as f: f.write(\n.join(lines)) # 类别映射COCO category_id 到 YOLO 的 0-based 索引 class_map {1: 0, 2: 1, 3: 2, 4: 3, 5: 4} coco_to_yolo(annotations.json, images, labels, class_map)这段脚本的关键点有三个。第一class_map必须和你的data.yaml里的names顺序严格对应我见过有人 COCO 里 category_id 从 1 开始YOLO 里忘了减一结果所有类别错位训练 loss 正常但推理全乱。第二归一化坐标保留 6 位小数铝片小目标如果只保留 2 位20 像素的框误差能到几个像素。第三裁剪到 [0,1] 是后悔药标注员手抖画出界不裁剪训练时直接报错中断。3.2 四个边界坑空标注、越界框、类别错位与文件名冲突空标注图在铝片数据集里很常见因为负样本也要采。YOLO 训练时如果一张图没有对应 txt或者 txt 是空的默认会当负样本处理但有些版本会直接跳过。我一般会显式生成空 txt 文件并在data.yaml里确认train和val路径下图片和标签一一对应。越界框就是上面说的坐标超出 0-1除了裁剪还要回头查标注工具是不是没限制画框范围。类别错位除了 class_map 问题还有一种情况是 COCO 里同一类别在不同 json 里 category_id 不一致合并数据集时要用类别名重新映射不能直接信 id。文件名冲突是隐蔽坑。铝片产线可能多台相机同时采文件名如果都用时间戳不同相机同一毫秒会撞名。我一般会在文件名里加相机编号前缀转换脚本里用Path(file_name).stem取名字时也要保证全局唯一。还有一个坑是图片格式COCO 里写的是.jpg实际文件是.png脚本按 file_name 找图会找不到转换前先统一扩展名。3.3 数据集划分与 data.yaml 配置划分训练集、验证集、测试集我一般按 7:2:1但铝片缺陷要做分层抽样保证每个类别在三个集合里比例接近。如果某个类别只有 50 个实例测试集里至少留 5 个不然评估指标没意义。划分脚本可以用sklearn.model_selection.train_test_split对 image_id 做 stratified split或者简单点按类别分组后手动分。data.yaml配置示例path: /data/aluminum_defect train: images/train val: images/val test: images/test nc: 5 names: [scratch, dent, stain, peeling, roll_mark]nc必须等于names长度names顺序必须和转换时的class_map值对应。我一般会在训练前跑一个检查脚本统计每个类别的实例数、每张图的平均目标数、宽高分布确认没有类别实例数为 0 或者某类占比超过 80%。铝片数据集里划痕往往占一半以上如果不管模型对凹坑的召回会很低后面要在 loss 里做类别加权或者重采样。4. 训练前必须做的数据体检分布、尺度与难例挖掘4.1 用统计脚本看类别分布和尺度分布数据体检不是可选项。我一般会写一个脚本遍历所有 YOLO txt统计每个类别的实例数、目标框宽高直方图、每图目标数分布。铝片缺陷的尺度分布如果集中在 20 到 50 像素而你的模型输入是 640那下采样 32 倍后目标只剩 1 到 2 个像素检测头根本学不到。这种情况要么提高输入分辨率到 1024 或 1280要么用 P2 小目标检测层。import os import numpy as np from collections import defaultdict def dataset_stats(label_dir, img_size640): cls_counts defaultdict(int) widths [] heights [] per_img_counts [] for txt in os.listdir(label_dir): if not txt.endswith(.txt): continue with open(os.path.join(label_dir, txt)) as f: lines [l.strip() for l in f if l.strip()] per_img_counts.append(len(lines)) for line in lines: parts line.split() cls_id int(parts[0]) w float(parts[3]) * img_size h float(parts[4]) * img_size cls_counts[cls_id] 1 widths.append(w) heights.append(h) print(类别实例数:, dict(cls_counts)) print(每图平均目标数:, np.mean(per_img_counts)) print(宽分布 P10/P50/P90:, np.percentile(widths, [10, 50, 90])) print(高分布 P10/P50/P90:, np.percentile(heights, [10, 50, 90])) dataset_stats(labels/train)这个脚本输出的宽高是换算到模型输入尺寸后的像素值。如果 P10 宽度小于 8 像素就要考虑上采样或者切图训练。铝片划痕如果很长P90 宽度可能超过 300 像素这种极端长宽比目标anchor 聚类时要单独处理或者直接用 anchor-free 的 YOLOv8/v11。4.2 难例挖掘从误检图里反推数据缺口模型训练完第一轮别急着调参先把验证集里的误检和漏检图捞出来看。我一般会按置信度排序看高置信度误检把背景当缺陷和低置信度漏检缺陷没框出来各占多少。铝片数据集里高置信度误检往往是光照不均或者反光被标成了脏污漏检往往是低对比度划痕或者小凹坑。把这些图挑出来重新标注或者补充类似样本比盲目加数据增强有效得多。难例挖掘还有一个技巧用训练好的模型对未标注的产线图做推理把置信度在 0.3 到 0.6 之间的框导出来人工复核后加入训练集。这批样本正好是模型当前决策边界附近的对提升精度最明显。我一般会迭代两到三轮每轮加 200 到 500 张难例验证集 mAP 能涨 3 到 5 个点。4.3 数据增强的边界哪些增强会破坏铝片缺陷特征YOLO 默认的增强里Mosaic、MixUp、HSV 抖动对铝片缺陷不一定都友好。Mosaic 会把四张图拼一起铝片划痕如果跨图拼接模型会学到不存在的长划痕我一般会把 Mosaic 概率从 1.0 降到 0.5 或者关掉。HSV 抖动里色调变化对铝片灰度图没意义饱和度和明度抖动幅度要小不然脏污和背景的对比关系会被破坏。翻转增强里垂直翻转要慎用铝片轧制方向有物理意义垂直翻转后的划痕方向在真实产线不会出现模型学了反而泛化差。我一般只保留水平翻转和 ±10 度旋转缩放范围控制在 0.8 到 1.2。5. 避坑与排查铝片缺陷数据集最常见的五类翻车5.1 标注框贴太松导致回归 loss 不降现象训练时 box loss 降到一定程度就震荡验证集 mAP 上不去可视化发现预测框比实际缺陷大一圈。原因标注时框画松了尤其是划痕和脏污标注员怕漏标把框画大模型学到的是「大框」分布。解决重新抽查 10% 标注算标注框与缺陷实际外接矩形的 IoU低于 0.8 的返工训练时可以把 CIoU 换成 EIoU 或者 SIoU对框的尺度更敏感。5.2 负样本不足导致背景误检高现象模型在产线图上到处框把正常纹理、反光、边缘都当缺陷误检率超过 20%。原因训练集里负样本太少或者负样本多样性不够模型没见过足够多的「正常铝片」形态。解决专门采一批无缺陷铝片图覆盖不同光照、不同批次、不同轧制方向负样本比例至少占总图数 20% 到 30%训练时用 Focal Loss 或者提高背景类权重。5.3 类别不均衡导致小类召回为零现象划痕类 mAP 0.8凹坑类 mAP 0.1混淆矩阵里凹坑全被预测成背景。原因凹坑实例数只有划痕的十分之一模型偏向多数类。解决对少数类做过采样或者用 copy-paste 增强把凹坑贴到更多背景上loss 里用类别权重权重设为实例数反比评估时看每类 AP不要只看 mAP。5.4 训练集和验证集同分布导致指标虚高现象验证集 mAP 0.9上线后实际漏检严重。原因划分数据集时随机分同一批料、同一光照的图同时进了训练和验证模型只是记住了这批数据的特征。解决按批次或时间段划分比如前三天数据做训练第四天做验证第五天做测试如果产线有多个相机按相机划分用 A 相机训练B 相机验证。5.5 图像格式与色彩空间不一致导致推理翻车现象训练时正常部署时推理结果全乱框位置偏移或者类别错。原因训练用 RGB部署时相机输出 BGR 没转或者训练图是 8 位部署时来了 16 位图。解决在数据加载和推理预处理里统一色彩空间和位深写一个preprocess函数训练和部署共用铝片如果用的是灰度相机训练时就转灰度别用 RGB 预训练权重硬套。6. 把数据集用出复利版本管理、主动学习与产线闭环数据集不是一次性的铝片产线换批次、换供应商、换光照数据分布就会漂移。我一般会给数据集打版本号比如aluminum_v1.0是初始 3000 张v1.1加了 500 张难例v1.2换了新批次负样本。每次训练记录用了哪个版本模型评估也按版本对比这样能看出是数据问题还是模型问题。版本管理不用搞复杂一个manifest.json记录每张图的来源、采集时间、标注员、是否难例就够了。主动学习是让数据集滚雪球的关键。我一般会部署一个轻量推理服务对产线新图做推理把置信度在 0.3 到 0.7 之间的图自动推到待标注队列人工复核后加入下一版数据集。这样每轮迭代只标最有价值的样本标注成本能降一半以上。铝片缺陷里低对比度划痕和罕见凹坑形态是最值得主动挖的正常划痕模型已经学得很好了再标就是浪费。最后分享一个我自己的习惯每次训练完我会把验证集里误检和漏检的图各抽 20 张打印出来贴在工位上旁边写「模型为什么错」。是标注错了还是缺陷太暗还是背景太杂写清楚再决定下一步是改数据还是改模型。这个习惯让我少走了很多弯路也让我对铝片缺陷的视觉特性越来越敏感。数据集这件事没有一步到位只有迭代到产线验收通过。希望帮到你。本文还有配套的精品资源点击获取
网站建设高端定制企业官网