news 2026/10/7 9:46:32

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

作者头像

张小明

前端开发工程师

1.2k 24
文章封面图
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> <name>can</name> <bndbox> <xmin>245</xmin> <ymin>180</ymin> <xmax>510</xmax> <ymax>520</ymax> </bndbox> </object>

对应的YOLO txt一行是:

0 0.567708 0.486111 0.368056 0.472222

转换逻辑很固定:x_center = (xmin + xmax) / 2 / img_w,width = (xmax - xmin) / img_w。自己在脚本里做转换时要注意除法结果需要保留足够精度,建议用浮点数计算结果并写入文件,不要四舍五入到整数。这份数据集同时提供了两种格式,意味着你可以直接用VOC格式做其他检测框架的验证,不用再写转换脚本。但如果你要新增标注,建议只维护其中一种格式,然后通过脚本批量生成另一种,避免两边手动改导致不一致。

3. 把数据集接进YOLOv5/YOLOv8/YOLOv9/YOLOv10/YOLO11:data.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: milk
  • path字段可以是绝对路径,也可以是相对于当前运行目录的路径。最省事的方式是写成绝对路径,省得每次换相对位置都要调。
  • 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 data=dataset/data.yaml model=yolov8n.pt epochs=100 imgsz=640 batch=16 device=0

参数说明:

  • 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就写device=cpu,但训练速度会慢很多。

如果是yolov5,命令风格是train.py:

cd 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 data=dataset/data.yaml model=runs/detect/train/weights/best.pt

predict则是对单张图像或整个文件夹做推理:

yolo predict model=runs/detect/train/weights/best.pt source=test_images/

跑predict时要注意,source可以是图像、视频或文件夹。推理结果会存到runs/detect/predict目录下,打开看检测框和置信度。这一步能直观看出模型在真实的罐头和瓶子场景里表现如何,是漏检、误检还是框偏。

提示:训练时epochs不要一次拉太高,先跑一个最小配置比如epochs=5验证流程能走通,再跑正式轮数。流程不通时高轮数只会浪费时间和显卡。

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, f"fields={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, f"out_of_range:{line}")) break if vals[2] <= 0 or vals[3] <= 0: bad_files.append((fname, f"zero_size:{line}")) break for item in bad_files[:20]: print(item[0], item[1]) print(f"total 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结果,远距离的瓶子或小罐头完全没有被框出来,大目标都检测到了,小目标全漏。

原因:数据集里存在不少小目标,imgsz=640时,小目标在特征图上只占几个像素,模型难学。YOLO本身对小目标就不是强项,这不算数据集错误。

解决:先提高输入分辨率imgsz=960或1280,看小目标召回率是否上升。如果显存不够,再考虑用SAHI这类切片推理工具,把图像切块后再预测。这个技巧在接下来一章展开说。

6. 进阶:小目标与不均衡类别的处理,以及标注文件的管理习惯

到了这一步,你的YOLO模型已经能跑通,验证效果也够用了。但如果想在公众号、实验报告或者实际项目里把模型做得更稳,下面几个技巧值得一试。

第一个技巧是处理小目标。用这份数据集训练时,如果发现瓶子在图像里占比很小,直接加大训练输入分辨率是最快解法。yolo train命令里把imgsz从640改成1024,再看验证mAP。前提是显存够用,batch适当降低。更稳的做法是切片推理:把原始图像切成四个象限,每个子图再调整为640,然后推理、把框坐标映射回原图,最后做NMS合并。你不需要自己写,ultralytics的文档里有SAHI集成说明,直接pip install sahi就能用。

第二个技巧解决类别不均衡。假设统计发现罐头数量是瓶子的好几倍,可以在YOLO的训练配置里给少样本类提高损失权重,或者用简单的过采样:在每次epoch前,对含瓶子的图像做随机翻转、亮度变化、随机缩放,生成额外的训练副本。注意只在训练集做增强,验证集保持原样,否则验证结果会被增强图像污染。

第三个技巧是目前很多工程师忽略的习惯:给标注文件建立“双重校验”流程。我现在拿到任何数据集,第一件事是用脚本检查标签文件是否全部对应,第二件事是把随机抽样的标注框可视化保存到一个checkout目录。这个习惯坚持下来,几乎从来没有在训练中途因为数据问题停下来过。特别是像这份数据集同时有txt和xml,每次新增图像后我都强制刷新一遍统计信息,列出图像数、标签数、类别数三者的对照表,哪位同事把漏标的图像混进来,一眼就能看到。

从那以后,我每次拿到新数据集,都会强制走一遍“解压→路径规范化→标签校验→可视化抽样→类别统计”五步流程,再开始训练。这套习惯看着多花十分钟,实际省掉了后面调参数、查原因的大把时间。希望帮到你。

本文还有配套的精品资源,点击获取

版权声明: 本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若内容造成侵权/违法违规/事实不符,请联系邮箱:809451989@qq.com进行投诉反馈,一经查实,立即删除!
网站建设 2026/10/7 9:45:39

RGB-Mini LED三色直出,1.2亿色彩背后的画质革命

RGB-Mini LED这个名词&#xff0c;我盯了差不多两年。从最初实验室里的样机&#xff0c;到展会上的工程机&#xff0c;再到今天海信把UX2026款正式端到台前&#xff0c;这条路走得比很多人想象中更久。这次发布最抓眼球的是两件事&#xff1a;一个是“7大全球首创”&#xff0c…

作者头像 李华
网站建设 2026/10/7 9:43:57

Slidev:用 Markdown 快速做出可交互的开发者幻灯片

Slidev:用 Markdown 快速做出可交互的开发者幻灯片 【免费下载链接】slidev Presentation Slides for Developers 项目地址: https://gitcode.com/GitHub_Trending/sl/slidev 技术分享前最常见的两个麻烦:代码贴在 PPT 里又丑又难改,演讲时既没有备注也没有计时,全靠硬撑…

作者头像 李华
网站建设 2026/10/7 9:42:12

同城跑腿系统开发实战:Fastadmin+ThinkPHP与Uniapp三端搭建与避坑指南

简介&#xff1a;基于Fastadmin后台框架、ThinkPHP开发框架与Uniapp跨端工具开发的优创同城跑腿系统&#xff0c;是一套面向跑腿团队、可私有化部署的全栈源码&#xff0c;完整覆盖用户端、骑手端和运营后台&#xff0c;适配帮取、帮送与同城配送场景。系统内置按距离、重量分类…

作者头像 李华
网站建设 2026/10/7 9:42:01

汽车电子电气架构演进:从分布式ECU到中央计算

这两年参加技术交流&#xff0c;只要聊到智能汽车&#xff0c;耳朵里全是“汽车电子电气架构”“域融合”“中央计算”这几个词。我经手过好几款量产项目&#xff0c;从早期的分布式车身控制器&#xff0c;一路做到区域控制器和中央网关&#xff0c;最大的感受是&#xff1a;这…

作者头像 李华