YOLO目标检测数据集实战:罐头与瓶子双格式标注与训练指南

发布时间:2026/10/7 9:46:34
YOLO目标检测数据集实战:罐头与瓶子双格式标注与训练指南
简介面向YOLO系列算法目标检测任务这份罐头与瓶子数据集包含1531张带标注图像覆盖鲜奶瓶、罐头等常见物体适用于训练YOLOv5、YOLOv8、YOLOv9、YOLOv7、YOLOv10、YOLO11等主流检测模型。压缩包内共2000个文件包含1073个xml标注和927个txt标注分别对应VOC格式与YOLO格式标签txt文件按“类别 中心点x 中心点y 宽度 高度”归一化存储方便直接接入Darknet及Ultralytics系训练流程。标签文件名末尾带有类别标识便于过滤与检索图像源丰富可适配不同光照与摆放角度的检测场景。数据集已划分训练集与验证集并提供data.yaml配置文件下载解压后即可开始训练或测试。目前已有54人浏览学习适合需要快速获得高质量标注数据的目标检测初学者、论文复现者及项目开发者可大幅节省图像采集与手工标注时间。1. YOLO算法目标检测的数据集长什么样一份罐头和瓶子数据集能省多少事在YOLO算法落地时最耽误进度的不是模型调参而是数据集的准备和标注。今天拆的这份“罐头和瓶子数据集”包含1531张真实场景图像标签分YOLO格式和VOC格式两份train/valid已经划分好还带了一份可直接被yolov5、yolov8、yolov9、yolov7、yolov10、yolo11读取的data.yaml配置文件。也就是说你下载解压后改两行路径就能开始训练省掉从零采集、清洗、标注、转换格式的整整一个环节。对正在入门YOLO目标检测、或者要在工业场景里快速验证“罐头分类/瓶子识别”效果的工程师来说这份数据比纯跑官方coco数据集更有价值——它是带业务语义的真实数据能直接看出模型的短板。2. 数据集结构与双标签格式先看懂再训练才不会把格式坑进模型拿到zip包第一件事不是解压后就直接丢给YOLO而是把目录结构和两种标签格式搞清楚。很多人在这一步翻车标签文件格式理解错了后面训练出来的模型mAP永远上不去。这里把文件夹的分布、txt和xml各自的意义拆开讲透。2.1 目录划分与文件清单train/valid与labels/images怎么对应解压之后常见的数据集结构是images和labels两大目录底下各自再按train、valid切分。这份资源的组织方式是YOLO系的标准布局dataset/ ├── data.yaml ├── images/ │ ├── train/ │ │ ├── img_0769_104.jpg │ │ └── ... │ └── valid/ │ └── ... ├── labels/ │ ├── train/ │ │ └── img_0769_104.txt │ └── valid/ │ └── ... └── voc_labels/ ├── train/ │ └── img_0769_104.xml └── valid/ └── ...对应规则很简单images/train下面每一张jpg在labels/train里都有一个同名txt文件在voc_labels/train里有一个同名xml文件。文件名一致是YOLO能正常加载的关键。如果你发现某些图像没有对应标签比如img_0769_921.txt只有txt没有xml说明该图在某种格式下是漏标或空图训练前需要单独清理。提示训练前先统计一下每个目录下的图像数量和标签数量是否一致。不一致时优先处理空标签文件不要直接训练。2.2 yolo格式txt坐标为什么是0到1的归一化值YOLO格式的txt文件每一行代表一个目标框五个字段依次是class、x_center、y_center、width、height。打开一个txt文件典型内容如下0 0.569444 0.284722 0.174222 0.173500 1 0.316944 0.640722 0.122400 0.201110第一列class是类别索引从0开始。如果data.yaml里写的类别顺序是[can, bottle, milk]那0代表罐头1代表瓶子2代表鲜奶。x_center和y_center是目标框中心点相对整张图宽高的比例值范围0到1。比如0.569444就是中心点在图像宽度方向的56.9%处。width和height是目标框相对整张图的宽高比例而不是像素绝对值。这种归一化是YOLO每幅图像大小不一致时采用的统一坐标方式。训练时模型内部会把坐标乘回图片实际尺寸所以你在txt里看到一个小数不要怀疑是标注错了先换算成像素看合不合理。换算公式是# 假设图片宽为img_w高为img_h x_pixel x_center * img_w y_pixel y_center * img_h w_pixel width * img_w h_pixel height * img_h正常的目标框像素宽高应该大于0且中心点落在图像范围内。如果某个框的width或height等于0或超过1那大概率是标注工具导出时出了问题训练前要剔除。2.3 voc格式xml如何与txt互相转换VOC格式用的是xml文件框的坐标是像素绝对值而且用xmin、ymin、xmax、ymax四个字段表示和YOLO的归一化中心点表达方式完全不同。同样的一个目标两种格式长这样object namecan/name bndbox xmin245/xmin ymin180/ymin xmax510/xmax ymax520/ymax /bndbox /object对应的YOLO txt一行是0 0.567708 0.486111 0.368056 0.472222转换逻辑很固定x_center (xmin xmax) / 2 / img_wwidth (xmax - xmin) / img_w。自己在脚本里做转换时要注意除法结果需要保留足够精度建议用浮点数计算结果并写入文件不要四舍五入到整数。这份数据集同时提供了两种格式意味着你可以直接用VOC格式做其他检测框架的验证不用再写转换脚本。但如果你要新增标注建议只维护其中一种格式然后通过脚本批量生成另一种避免两边手动改导致不一致。3. 把数据集接进YOLOv5/YOLOv8/YOLOv9/YOLOv10/YOLO11data.yaml与训练命令数据格式看懂了接下来就是让YOLO能真正跑起来。yolov5到yolo11这几代框架虽然网络结构变了但数据集入口几乎都依赖data.yaml文件。这一章带你过一遍配置和训练流程保证你照着做就能把模型训起来。3.1 data.yaml配置解读路径、类别名、类别数data.yaml是YOLO系框架读取数据集的入口文件内容一般是path: /your/abs/path/dataset train: images/train val: images/valid names: 0: can 1: bottle 2: milkpath字段可以是绝对路径也可以是相对于当前运行目录的路径。最省事的方式是写成绝对路径省得每次换相对位置都要调。train和val是相对path的相对路径指向images下面的train和valid文件夹而不是labels文件夹。框架会自动在同级labels目录里找标签。names列表的顺序和txt第一列的class索引严格对应。这里最容易犯的错是类别顺序写错导致所有标签的语义错位。建议打开一个txt文件把每个标签的第一列和names里对一下确认0到底代表罐头还是瓶子。如果项目里同时存在names.txt文件要以data.yaml为准。yolov5在旧版本里还支持用names.txt指定类别新框架统一用yaml。这份资源已经为你写好了data.yaml你要做的只是把path改成自己解压后的实际路径然后检查names是否和你的意图一致。3.2 用yolo命令启动训练一次标准流程YOLOv8及之后版本用ultralytics包训练命令统一为pip install ultralytics yolo train datadataset/data.yaml modelyolov8n.pt epochs100 imgsz640 batch16 device0参数说明data 指定你的数据集yaml路径。model 指定预训练权重yolov8n.pt是轻量版显存不够就换n显存充足可换yolov8s.pt或yolov8m.pt。YOLOv9、yolov10、yolo11同样可以指定对应的预训练权重比如yolo11n.pt。epochs 训练轮数100是入门配置罐头和瓶子这种少量类别可以先用100轮跑通流程再根据曲线调整。imgsz 输入图像缩放尺寸默认640。这份数据集的图像如果原始分辨率较大比如超过1280可以先用640跑看训练样本的object大小分布再决定要不要调大。batch 每批图像数量显存不够时从16降到8或4。device 指定GPU编号没有GPU就写devicecpu但训练速度会慢很多。如果是yolov5命令风格是train.pycd yolov5 pip install -r requirements.txt python train.py --data dataset/data.yaml --weights yolov5s.pt --epochs 100 --batch-size 16 --img 640两者的核心差异只是命令行参数写法不同底层的训练逻辑一致。这份数据集对yolov5到yolo11都兼容主要原因是标签目录和data.yaml的命名方式没有随框架版本变化。3.3 验证测试用训练好的模型跑val与predict训练完成后验证集效果可以用框架自带的验证命令看yolo val datadataset/data.yaml modelruns/detect/train/weights/best.ptpredict则是对单张图像或整个文件夹做推理yolo predict modelruns/detect/train/weights/best.pt sourcetest_images/跑predict时要注意source可以是图像、视频或文件夹。推理结果会存到runs/detect/predict目录下打开看检测框和置信度。这一步能直观看出模型在真实的罐头和瓶子场景里表现如何是漏检、误检还是框偏。提示训练时epochs不要一次拉太高先跑一个最小配置比如epochs5验证流程能走通再跑正式轮数。流程不通时高轮数只会浪费时间和显卡。4. 标签质量检查与可视化训练前必须做的三件事好多新手把数据喂进去训练完发现mAP不到0.5第一反应是换模型实际上多数原因是标签质量不过关。训练前花十分钟做三件事能省下后面几天的调参时间。4.1 用代码检查txt坐标越界与空标签批量检查所有txt文件里的坐标值是否在0到1范围以及是否存在空文件import os label_root dataset/labels/train bad_files [] for fname in os.listdir(label_root): if not fname.endswith(.txt): continue path os.path.join(label_root, fname) with open(path) as f: lines [line.strip() for line in f if line.strip()] # 空文件或者没有有效目标 if not lines: bad_files.append((fname, empty)) continue for line in lines: parts line.split() if len(parts) ! 5: bad_files.append((fname, ffields{len(parts)})) continue vals [float(p) for p in parts[1:]] # 坐标范围必须在0~1之间且width/height必须大于0 if any(v 0 or v 1 for v in vals): bad_files.append((fname, fout_of_range:{line})) break if vals[2] 0 or vals[3] 0: bad_files.append((fname, fzero_size:{line})) break for item in bad_files[:20]: print(item[0], item[1]) print(ftotal bad: {len(bad_files)})这段脚本遍历标签目录检查每个txt字段数量和坐标范围。空标签文件会导致训练时该图像被跳过最终有效样本数减少坐标越界则会让损失函数计算出错模型学出奇怪的结果。看到bad_files数量为0再放心进入下一步。如果发现少量空文件可以直接删除对应的图像和标签或者把图像归类到剪枝列表。4.2 可视化标签框是否贴合目标数值检查只能看坐标合不合法看不到框到底准不准。用OpenCV把txt标签画回原图import cv2 import os img_path dataset/images/train/img_0769_104.jpg txt_path dataset/labels/train/img_0769_104.txt img cv2.imread(img_path) h, w img.shape[:2] with open(txt_path) as f: for line in f: cls, xc, yc, bw, bh line.split() cls, xc, yc, bw, bh int(cls), float(xc), float(yc), float(bw), float(bh) x1 int((xc - bw / 2) * w) y1 int((yc - bh / 2) * h) x2 int((xc bw / 2) * w) y2 int((yc bh / 2) * h) cv2.rectangle(img, (x1, y1), (x2, y2), (0, 255, 0), 2) cv2.putText(img, str(cls), (x1, y1 - 5), cv2.FONT_HERSHEY_SIMPLEX, 0.6, (0, 0, 255), 2) cv2.imwrite(check_visual.jpg, img)这段代码把归一化坐标还原成像素框并画出类别索引。打开输出图检查框是否包住整个罐头或瓶子是否存在框只盖住一半、偏移明显、包含背景的情况。这份数据集带的是人工标注标签大概率是贴合的但一旦你后续自己追加图片这一步无论如何都要做。画框时注意坐标换算顺序先把中心点和宽高换算成x1、y1、x2、y2再画矩形不要直接用归一化值绘图。4.3 检查train/valid类别分布均衡性类别分布不均衡会让模型倾向预测多数类。统计每个类别在训练集和验证集里的目标数量from collections import Counter def count_classes(label_dir): counter Counter() for fname in os.listdir(label_dir): if not fname.endswith(.txt): continue with open(os.path.join(label_dir, fname)) as f: for line in f: if line.strip(): counter[int(line.split()[0])] 1 return counter print(train:, count_classes(dataset/labels/train)) print(valid:, count_classes(dataset/labels/valid))如果train里的罐头有3000个目标瓶子只有500个模型会严重偏向罐头。对应的处理办法可以是给少样本类别增加权重或者对瓶子类做数据增强这些进阶内容在最后一章展开。现在你只需要确认train和valid的分布比例大致接近。如果两份集合的类别比例差异过大说明随机划分时没有按类别分层验证结果就会失真。5. 常见问题排查训练跑飞、map低、标签漏检的避坑指南这个数据集本身质量没问题但把它跑起来的过程中遇到的坑大多来自框架版本、路径、标签索引这些非常规操作。把下面几个最容易踩的坑列出来每个都是我实际见过的翻车现场。5.1 类别索引错位看起来是“标签全错”实际是names顺序没对上现象训练时loss正常下降但验证mAP始终在0.1到0.2徘徊。打开预测结果发现罐头被识别成瓶子瓶子被识别成罐头类别整体偏移一位。原因data.yaml里names的顺序和txt里的class索引不一致。比如原数据集的data.yaml是names: [0: can, 1: bottle]而你为了便于理解改成[0: bottle, 1: can]导致所有标签的类别全部对调。解决严格以labels/train下的txt文件内容为准检查class数字在data.yaml中对应的名称。如果txt第一列全是0和1而你的names恰好有3个类别更要警惕是类别数不匹配还是索引错位。修好之后可以重跑可视化脚本在每个框上打印类别名称而不是数字。5.2 xml和txt不同步新增标注后忘记生成另一种格式现象用yolov8训练没有问题但想用VOC格式跑一次更稳定的对比实验时发现部分图像没有xml文件或者xml里的框和txt对不上。原因这份资源是双格式但你之后手动新增了标注只生成了txt没有同步更新xml。yolo训练只找txt没问题一旦切到VOC或其他框架就报错。解决无论何时新增标注都要以同一种格式为唯一数据源比如只维护txt然后写脚本批量生成xml或者只维护xml生成txt。不要手动双份维护。我自己现在连新增一张图都会跑一遍同步脚本确保两个格式目录的文件名一一对应。5.3 中文路径或特殊字符导致训练中断现象Windows下把数据集解压到“D:\我的数据集\罐头瓶子\”目录运行yolo train时进程直接退出报错包含路径解析失败。原因部分YOLO版本依赖的底层库对中文路径支持不好路径中的空格、中文、特殊符号会被错误处理。解决把数据集放到纯英文目录比如“D:\datasets\can_bottle”路径里不要有空格和标点符号。data.yaml的path字段也一定改成这个纯英文路径。虽然新版ultralytics对中文路径的支持好一些但为了不折腾直接用英文路径是最省心的。5.4 空标签文件被当负样本导致训练意外中断现象训练日志里出现“WARNING: No labels found in dataset/labels/train/img_0769_921.txt”然后该图像被跳过或者验证时出现维度报错。原因某些图像没有标注目标但txt文件依然存在内容为空。YOLO框架会把空文件视为“无目标图”数量多了会影响采样效率个别版本甚至会因为空标签找不到对应的类别而报错。解决训练前用4.1节的脚本找出空标签把空标签文件和对应图像一起挪到ignore文件夹不要直接删掉原图万一以后想重新标注还能找回。空标签文件保留在labels目录里只会增加排查成本。5.5 小目标漏检罐头小、瓶子多导致的“漏检没商量”现象验证集loss不高但看predict结果远距离的瓶子或小罐头完全没有被框出来大目标都检测到了小目标全漏。原因数据集里存在不少小目标imgsz640时小目标在特征图上只占几个像素模型难学。YOLO本身对小目标就不是强项这不算数据集错误。解决先提高输入分辨率imgsz960或1280看小目标召回率是否上升。如果显存不够再考虑用SAHI这类切片推理工具把图像切块后再预测。这个技巧在接下来一章展开说。6. 进阶小目标与不均衡类别的处理以及标注文件的管理习惯到了这一步你的YOLO模型已经能跑通验证效果也够用了。但如果想在公众号、实验报告或者实际项目里把模型做得更稳下面几个技巧值得一试。第一个技巧是处理小目标。用这份数据集训练时如果发现瓶子在图像里占比很小直接加大训练输入分辨率是最快解法。yolo train命令里把imgsz从640改成1024再看验证mAP。前提是显存够用batch适当降低。更稳的做法是切片推理把原始图像切成四个象限每个子图再调整为640然后推理、把框坐标映射回原图最后做NMS合并。你不需要自己写ultralytics的文档里有SAHI集成说明直接pip install sahi就能用。第二个技巧解决类别不均衡。假设统计发现罐头数量是瓶子的好几倍可以在YOLO的训练配置里给少样本类提高损失权重或者用简单的过采样在每次epoch前对含瓶子的图像做随机翻转、亮度变化、随机缩放生成额外的训练副本。注意只在训练集做增强验证集保持原样否则验证结果会被增强图像污染。第三个技巧是目前很多工程师忽略的习惯给标注文件建立“双重校验”流程。我现在拿到任何数据集第一件事是用脚本检查标签文件是否全部对应第二件事是把随机抽样的标注框可视化保存到一个checkout目录。这个习惯坚持下来几乎从来没有在训练中途因为数据问题停下来过。特别是像这份数据集同时有txt和xml每次新增图像后我都强制刷新一遍统计信息列出图像数、标签数、类别数三者的对照表哪位同事把漏标的图像混进来一眼就能看到。从那以后我每次拿到新数据集都会强制走一遍“解压→路径规范化→标签校验→可视化抽样→类别统计”五步流程再开始训练。这套习惯看着多花十分钟实际省掉了后面调参数、查原因的大把时间。希望帮到你。本文还有配套的精品资源点击获取