
简介这份易拉罐缺陷识别数据集面向工业质检方向的算法工程师、高校学生与视觉项目开发者聚焦罐体表面划痕、罐底异常等缺陷的自动检测任务可用于训练与验证目标检测模型。资源包共1709个文件包含854张jpg实拍图像、854个同名txt标注文件及1个yaml配置文件压缩包约38.27MB标注同时兼容YOLO、COCO JSON与Pascal VOC XML三种主流格式其中yaml文件可直接用于YOLO系列训练配置txt文件对应每张图像的边界框与类别信息。据描述该数据集在YOLO v8上的平均正确识别率可达98.9%已有457人学习下载。借助成对的图像与标注读者可快速完成数据加载、模型训练与精度复现省去自行采集与标注的成本适合作为缺陷检测入门练手或产线质检方案的原型验证素材。1. 易拉罐缺陷识别数据集从产线质检到 YOLOv8 训练的一条龙落地产线质检上有个很尴尬的现实人眼盯罐底划痕盯两小时就开始漏检而客户投诉往往就出在那些漏掉的微小凹坑上。这份易拉罐缺陷识别数据集就是冲着这个场景来的——它把罐底、罐身的划痕、凹坑、变形等缺陷用 YOLO 格式标好官方给出的平均正确识别率能到 98.9%。数据集同时提供 COCO JSON 和 Pascal VOC XML 两种标注格式意味着你不管是用 YOLOv8 直接开训还是想拿 Ultralytics 之外的其他检测框架做对比实验都能少走一道格式转换的弯路。适合谁做工业质检落地的算法工程师、想拿真实缺陷数据跑通检测流程的学生以及需要快速验证产线视觉方案可行性的集成商。下面我按「拿到数据怎么用 → 训练怎么配 → 坑在哪」的顺序拆一遍。2. 数据集结构与 YOLOv8 标注格式拆解先看懂再动手2.1 目录长什么样标注文件怎么对应从项目正文给出的文件名看原始图片是WIN_20240410_20_40_37_Pro_jpg.rf.b46e051eab21da1eebf7cbc6ee892f93.jpg这种带 Roboflow 风格哈希后缀的命名。这种命名不是随便起的.rf.后面那串哈希是数据增强或版本切分时生成的唯一标识好处是同一张原图经过翻转、亮度调整后生成的新图不会重名坏处是你没法直接从文件名看出它属于训练集还是验证集。所以拿到压缩包后第一件事不是急着解压训练而是先确认目录结构。常见做法是解压后看到这样的层级dataset/ ├── images/ │ ├── train/ │ ├── val/ │ └── test/ ├── labels/ │ ├── train/ │ ├── val/ │ └── test/ └── data.yamlimages/train/下放 jpg 原图labels/train/下放同名 txt 标注文件。注意这里有个容易翻车的点图片名是xxx.jpg标注名必须是xxx.txt前缀完全一致只换扩展名。如果你从 COCO JSON 自己转 YOLO 格式转换脚本里忘了去掉.jpg再拼.txt训练时就会报「找不到标签」或者更隐蔽的「标签全为空」模型训出来全是背景。2.2 YOLO 标注格式的五个字段到底怎么读YOLO 格式的每一行是一个目标格式为class_id x_center y_center width height这五个值里后四个都是归一化到 0~1 的浮点数不是像素坐标。很多新手第一次看标注文件会懵明明图片是 1920×1080怎么坐标是 0.53 这种小数因为 YOLO 训练时会把图片 resize 到固定输入尺寸比如 640×640用归一化坐标可以避免 resize 后坐标错位。x_center和y_center是目标框中心点相对整图宽高的比例width和height是框宽高相对整图宽高的比例。假设一张罐底图里有一个划痕标注文件WIN_20240410_20_40_37_Pro_jpg.rf.b46e051eab21da1eebf7cbc6ee892f93.txt内容可能是0 0.512 0.487 0.231 0.156 1 0.734 0.622 0.089 0.112第一行class_id0代表划痕第二行class_id1代表凹坑。类别 id 从 0 开始连续编号具体哪个 id 对应哪个缺陷得看data.yaml里的names列表。这里有个血泪经验如果你自己合并了多个来源的数据集两个来源的class_id含义不一样比如 A 数据集 0 是划痕B 数据集 0 是凹坑直接混在一起训模型会学出一个「薛定谔的类别」验证集精度看着还行一上产线就乱报。合并前必须统一类别映射表。2.3 data.yaml 的四个关键字段data.yaml是 YOLOv8 训练的入口配置文件典型内容如下path: /home/user/dataset train: images/train val: images/val test: images/test nc: 3 names: 0: scratch 1: dent 2: deformationpath是数据集根目录train/val/test是相对path的子路径。nc是类别数names是类别名列表。这里最容易踩的坑是path用了相对路径而你在不同目录下执行训练命令导致找不到数据。我一般会强制写成绝对路径或者用os.path.abspath在脚本里动态生成。另外names的缩进必须是两个空格用 Tab 会报 YAML 解析错误这个错误信息往往只提示「mapping values are not allowed here」不告诉你是 Tab 的问题排查起来很费时间。提示拿到数据集后先跑一遍ls labels/train | wc -l和ls images/train | wc -l两个数字必须相等。不相等说明有图片没标或者标注文件多余直接开训会在 dataloader 阶段报错。3. 用 YOLOv8 训练易拉罐缺陷检测模型从环境到推理的完整链路3.1 环境准备与 ultralytics 安装训练环境我一般用 Python 3.10 PyTorch 2.1 CUDA 11.8 这套组合兼容性最稳。安装 ultralytics 不要直接pip install ultralytics就完事因为默认会拉最新版而最新版可能和你本地的 PyTorch 版本打架。常见做法是先把 PyTorch 装好再装 ultralytics# 先装 PyTorch以 CUDA 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())最后一行输出True才算环境通了。如果输出False先别急着改代码大概率是 CUDA 版本和 PyTorch 版本不匹配。用nvidia-smi看驱动支持的 CUDA 版本再去 PyTorch 官网查对应关系。这一步没通就开训YOLOv8 会静默回退到 CPU训练速度从每轮几分钟变成几小时很多人以为是自己参数设错了其实是 GPU 根本没吃上。3.2 训练命令与关键参数含义YOLOv8 的训练入口是yolo detect train最简命令如下yolo detect train \ data/home/user/dataset/data.yaml \ modelyolov8n.pt \ epochs100 \ imgsz640 \ batch16 \ device0 \ projectruns/can_defect \ nameexp1逐项说参数。data指向data.yaml必须绝对路径。model选yolov8n.pt是最小的 nano 模型适合先跑通流程如果精度不够再换yolov8s.pt或yolov8m.pt。epochs100是训练轮数缺陷检测这种任务一般 100~300 轮能看到收敛但要看验证集 mAP 曲线不是越多越好。imgsz640是输入尺寸罐底划痕如果很细可以提到 1280但显存占用会翻倍。batch16是批大小显存不够就降到 8 或 4。device0指定第一块 GPU多卡用device0,1。训练过程中重点看三个指标box_loss应该持续下降mAP50应该持续上升mAP50-95上升速度会比mAP50慢。如果box_loss降到某个值就不动了而mAP50还在涨说明模型在细化框的位置是正常现象。如果box_loss震荡不降先检查学习率YOLOv8 默认用余弦退火初始 lr 是 0.01小数据集可以降到 0.001。3.3 推理验证与置信度阈值调整训练完在runs/can_defect/exp1/weights/best.pt拿到最优权重推理命令yolo detect predict \ modelruns/can_defect/exp1/weights/best.pt \ source/home/user/test_images \ conf0.25 \ iou0.45 \ saveTrueconf0.25是置信度阈值低于这个值的检测框直接丢弃。iou0.45是 NMS 的 IoU 阈值控制重叠框的合并程度。这两个参数对最终效果影响极大。产线质检场景下如果漏检代价高把conf降到 0.15宁可多报几个假阳性也不能漏如果误报会导致频繁停机把conf提到 0.4 以上。iou一般保持 0.45~0.5除非你的缺陷目标特别密集才需要调低到 0.3 避免框被误合并。推理结果会保存到runs/detect/predict/下每张图带检测框和类别标签。我一般会再写个小脚本统计每类的检出数量和人工抽检结果对比算一下实际产线上的召回率和准确率。官方说的 98.9% 是在特定测试集上的平均正确识别率你自己的产线光照、相机角度、罐体型号一变这个数字就得重新验证。4. 多格式标注互转与数据增强COCO、VOC 和 YOLO 之间怎么不丢信息4.1 三种格式的核心差异这份数据集同时提供 YOLO、COCO JSON、Pascal VOC XML 三种标注不是凑数是因为不同框架吃不同格式。YOLO 用归一化 txtCOCO 用单个 JSON 存所有图片的标注VOC 用每张图一个 XML。核心差异在坐标表示和类别存储方式格式坐标类型类别存储典型用途YOLO归一化中心点宽高独立 txtclass_id 数字Ultralytics 系列COCO绝对像素左上角宽高单个 JSONcategory_idDetectron2、MMDetectionVOC绝对像素左上角右下角独立 XML类别名文本老版 TensorFlow、部分工业软件转换时最容易丢信息的是类别名。YOLO 只存数字 idCOCO 存 id 和 name 的映射VOC 直接存 name。从 YOLO 转 VOC 时你得自己维护一份 id 到 name 的映射表否则转出来的 XML 里类别全是0、1、2下游工具不认。4.2 用 Python 做 YOLO 转 COCO 的实操下面这段脚本把 YOLO 格式转成 COCO JSON关键步骤都加了注释import json import os from PIL import Image # 类别映射必须和 data.yaml 里的 names 一致 class_names {0: scratch, 1: dent, 2: deformation} def yolo_to_coco(image_dir, label_dir, output_json): coco { images: [], annotations: [], categories: [] } # 构建 categories for cid, cname in class_names.items(): coco[categories].append({ id: cid, name: cname, supercategory: defect }) ann_id 1 img_id 1 for fname in os.listdir(image_dir): if not fname.lower().endswith((.jpg, .png)): continue img_path os.path.join(image_dir, fname) w, h Image.open(img_path).size coco[images].append({ id: img_id, file_name: fname, width: w, height: h }) label_path os.path.join(label_dir, fname.rsplit(., 1)[0] .txt) if os.path.exists(label_path): with open(label_path) as f: for line in f: parts line.strip().split() if len(parts) ! 5: continue cid, xc, yc, bw, bh map(float, parts) # YOLO 归一化坐标转 COCO 绝对像素 x (xc - bw / 2) * w y (yc - bh / 2) * h abs_w bw * w abs_h bh * h coco[annotations].append({ id: ann_id, image_id: img_id, category_id: int(cid), bbox: [x, y, abs_w, abs_h], area: abs_w * abs_h, iscrowd: 0 }) ann_id 1 img_id 1 with open(output_json, w) as f: json.dump(coco, f, indent2) yolo_to_coco(dataset/images/train, dataset/labels/train, train_coco.json)逻辑说明先遍历图片目录拿到每张图的宽高这是反归一化的前提。然后读同名 txt把归一化中心点坐标转成左上角绝对坐标。area字段是 COCO 评估时必须的等于框面积。iscrowd0表示不是密集人群那种难例缺陷检测一般都用 0。参数上唯一需要你改的是class_names必须和data.yaml完全一致否则 COCO 评估时类别对不上mAP 算出来是错的。4.3 数据增强的边界什么时候该增强什么时候不该YOLOv8 默认开启 mosaic、HSV 抖动、随机翻转等增强。对易拉罐缺陷检测来说mosaic 增强要谨慎。mosaic 会把四张图拼成一张罐底划痕这种细长目标被拼到边缘时可能被裁掉一半模型学到的就是残缺特征。我一般会在data.yaml同级加一个augment.yaml把mosaic概率从默认的 1.0 降到 0.5degrees旋转角度从 0 提到 10因为产线上罐体摆放角度确实有偏差。但flipud上下翻转要关掉罐底缺陷上下翻转后不符合物理规律模型学了反而干扰。注意数据增强不是越多越好。缺陷检测的核心是让模型学到缺陷的纹理和形状特征过度增强会让模型把增强噪声当成缺陷特征。验证集 mAP 涨了但产线实测降了往往就是增强过头。5. 避坑与排查易拉罐缺陷数据集训练中最容易翻车的五个点5.1 现象训练 loss 正常下降但验证集 mAP 始终为 0原因标注文件里的class_id超出了data.yaml里nc定义的范围。比如nc3但某个标注文件里出现了3或更大的 idYOLOv8 在计算损失时会把这类目标忽略验证时也匹配不上任何类别mAP 自然为 0。解决写个脚本扫一遍所有 label 文件统计出现的 class_id 集合和data.yaml的names键做差集。有超出范围的要么改标注要么扩nc。import os ids set() for f in os.listdir(dataset/labels/train): with open(os.path.join(dataset/labels/train, f)) as fp: for line in fp: ids.add(int(line.split()[0])) print(出现的类别 id:, sorted(ids))5.2 现象训练报错「No labels found in ...」原因图片和标注的目录结构不匹配或者文件名前缀不一致。YOLOv8 默认在images/train同级找labels/train如果你把 labels 放到了别的地方或者图片是a.jpg而标注是a.JPG.txt都会报这个错。解决确认data.yaml里train和val指向的是 images 目录YOLOv8 会自动把路径里的images替换成labels去找标注。如果目录结构特殊用path字段显式指定根目录。文件名大小写敏感的问题在 Linux 上尤其常见Windows 上跑通不代表 Linux 上没问题。5.3 现象推理时框的位置整体偏移原因训练时用了rectTrue矩形推理但推理时没开或者反过来。YOLOv8 默认训练用矩形推理减少 padding推理时如果输入尺寸和训练不一致框的归一化坐标反算回原图时就会偏。解决训练和推理的imgsz保持一致推理时加rectTrue参数。如果还是偏检查原图是否被 EXIF 旋转信息影响PIL 读图和 OpenCV 读图对 EXIF 的处理不一样会导致宽高互换。5.4 现象小目标划痕漏检严重原因输入尺寸 640 时一条只占原图 2% 宽度的划痕resize 后只剩十几个像素特征在 backbone 下采样几次后就消失了。解决把imgsz提到 1280或者在模型里加 P2 小目标检测层。YOLOv8 官方没有直接暴露 P2 配置常见做法是改用yolov8-p2.yaml这种社区配置但要注意预训练权重不匹配得从头训或者只加载 backbone。另一个思路是把大图切patch训练推理时再拼回去适合罐底这种固定视野的场景。5.5 现象模型在测试集上 98%产线上只有 80%原因测试集和产线的光照、相机、罐体批次不一致。数据集里的图片是特定条件下采集的产线换一批罐子、换个光源分布就变了。解决这不是模型问题是数据问题。在产线上采集一批新图人工标 50~100 张用训练好的模型做预标注人工修正后加入训练集做增量训练。YOLOv8 支持resume继续训练但增量训练建议用低学习率0.0001微调避免灾难性遗忘。6. 进阶技巧用验证集反推标注质量与置信度校准训练完不是终点验证集除了算 mAP还能反推标注质量。我一般会跑一遍val模式把预测结果和真实标注叠在一起看yolo detect val \ modelruns/can_defect/exp1/weights/best.pt \ data/home/user/dataset/data.yaml \ conf0.001 \ iou0.6 \ plotsTrue注意这里conf故意设成 0.001是为了让模型输出所有可能的框包括低置信度的。plotsTrue会在输出目录生成val_batch0_pred.jpg和val_batch0_labels.jpg前者是预测结果后者是真实标注。把两张图并排看如果某个缺陷在 labels 图里有框但 pred 图里没有说明模型漏检如果 pred 图里框的位置和 labels 图差很多说明标注本身可能就不准。置信度校准是另一个实用技巧。YOLOv8 输出的置信度不是概率不能直接当「有缺陷的概率」用。我一般会统计验证集上不同conf阈值下的精确率和召回率画一条 P-R 曲线然后根据产线能接受的误报率反推阈值。比如产线要求误报率低于 5%那就找精确率 95% 对应的conf值而不是拍脑袋定 0.25。还有一个容易被忽略的点类别不平衡。如果划痕样本远多于凹坑模型会偏向划痕凹坑的召回率上不去。常见做法是在data.yaml里给每个类别加权重但 YOLOv8 不直接支持类别权重得改损失函数。更简单的办法是对凹坑样本做过采样或者用copy_paste增强把凹坑贴到更多背景上。从那以后我每次拿到新数据集都强制先跑一遍标注 id 扫描和图片-标注数量对齐检查再开训。这两个检查花不了五分钟但能省掉后面几小时的无效训练。希望帮到你。本文还有配套的精品资源点击获取