首页 / 资讯中心 / 文章详情

YOLO室内家具目标检测数据集使用指南:从标签解析到训练避坑

YOLO室内家具目标检测数据集使用指南:从标签解析到训练避坑 ★ FEATURED ARTICLE
简介这是YOLO系列算法适用的室内家具目标检测数据集包含2416张图像及对应TXT标签已按训练、验证和测试划分完毕适合研究人员、开发者及入门学习者直接用于目标检测模型的训练与评估。压缩包内文件总数2000个主要由1999个TXT标签文件和1个YAML配置文件组成整体大小约50.04MBTXT标签采用标准YOLO格式逐行记录类别索引、归一化中心坐标与宽高便于直接迁移至YOLOv3、YOLOv4、YOLOv5等不同版本。目前已有165人学习该数据集标注规范且划分明确可立即开展训练与验证也可作为不同检测算法性能对比的基准。对室内家具识别、智能家居及视觉巡检等场景这份资源能大幅省去数据采集与标注耗时加速模型迭代同时标准的标签格式与划分方式也便于后续扩展与结果复现。1. 这份室内家具数据集能帮你省下最耗时的环节yolo 系列算法用的室内家具目标检测数据集2416 张图像全部带标签解压后就能进入训练流程这是它和网上散装图片最大的区别。自己收集两千多张室内家具图、逐张画框标注按一张两分钟算也接近八十个小时这套资源把这些时间直接省掉了。标签是 YOLO 标准归一化格式class、x_center、y_center、width、height 五列训练集、验证集、测试集已经按常规比例划分好不用自己再拆。适合两类人做毕业设计或论文实验的学生以及想快速跑通 YOLO 训练流程但不想从零标注的新手。需要提醒的是数据集只给了类别索引没有附带类别名称清单训练前要按索引顺序把 names 补上这一步我会在第 3 章讲清楚。它的价值不在图像本身有多精美而在于「能直接喂给 YOLOv5/v8 训练」这一件事剩下的时间可以全部花在调参和排查上。2. 拆解数据集2416 张图像与标签文件的对应关系拿到压缩包之后先别急着配环境第一步是打开目录看到底有什么。网上很多数据集打包时目录结构五花八门有的把标签和图像混在一起有的 train 里有标签却没有对应图像先用几分钟把结构摸清楚能避开后面一大半问题。2.1 目录结构train、val、test 的常见组织方式这类按 YOLO 格式整理的数据集最常见的组织方式是 images 和 labels 两个根目录下面再按 train、val、test 分子目录。图像与标签文件名完全一致只是扩展名不同比如图像是000535_187.jpg标签就是000535_187.txt。先解压再数一数各目录下的文件数unzip skripsi-new-j1bmb.zip -d furniture_dataset cd furniture_dataset find . -type f | sed s/.*\.// | sort | uniq -c echo --- images/train --- ls images/train | wc -l echo --- labels/train --- ls labels/train | wc -l这段命令先统计压缩包里所有文件的扩展名分布确认标签与图像的文件类型再分别查看训练集图像和标签的数量。如果 images/train 的文件数比 labels/train 多说明有图像没有被标注反过来则说明存在空的标签文件需要重点检查。数量对得上之后再看 val 和 test 目录。该数据集说明里提到已经做好划分通常会有一个 test 目录用来做最终评估。如果只有 train 和 val就把 val 当验证集用测试集自己从 val 里再留一部分出来。我一般会把文件名按顺序排好然后手动抽查几个子目录确认没有出现嵌套的文件夹因为 YOLO 训练时路径越简单越不容易出错。2.2 标签文件逐行解析五列归一化坐标的读法打开任意一个 txt 标签文件每行都是五个数字。以000535_187.txt为例假设某一行是0 0.483 0.412 0.215 0.267含义是第一个 0 是类别索引从 0 开始后面四个数字分别是目标框中心点的 x、y 坐标和框的宽度、高度它们都是相对于图像宽度和高度的比例值范围在 0 到 1 之间。这种归一化格式与图像实际分辨率解耦所以同一份标签既可以跑 YOLOv5也可以跑 YOLOv8甚至换成 Faster R-CNN 时只需要做格式转换。我习惯用一个 Python 脚本先把所有标签统计一遍看类别索引分布和坐标是否越界这样能提前发现标注文件里的脏数据import os label_dir furniture_dataset/labels/train class_count {} out_of_range [] for txt_name in os.listdir(label_dir): if not txt_name.endswith(.txt): continue path os.path.join(label_dir, txt_name) with open(path, r) as f: for line in f: parts line.strip().split() if len(parts) ! 5: out_of_range.append((txt_name, 字段数不是5)) continue cls int(parts[0]) x_center, y_center, w, h map(float, parts[1:]) class_count[cls] class_count.get(cls, 0) 1 # 归一化坐标的范围必须都在0到1之间 if not (0.0 x_center 1.0 and 0.0 y_center 1.0): out_of_range.append((txt_name, f中心点越界: {parts[1:]})) print(类别分布:, dict(sorted(class_count.items()))) print(异常记录:, out_of_range[:10])这段脚本做了三件事统计每个类别索引出现多少次、检查每行是否正好五列、检查中心点坐标是否落在合法区间。参数说明class_count字典用于记录类别分布如果你看到索引 0 有几千条而索引 1 只有几十条说明类别严重不均衡训练时就要考虑要不要做类别加权。out_of_range列表收集越界记录只要出现一条就应该回到标注工具里检查原始标注而不是强行训练。2.3 图像与标签的配对校验不匹配时训练会很难看标签格式正确还不够还得确认每张图都有标签、每个标签都有对应的图。YOLO 训练时如果一张训练图找不到标签文件会直接报错或者跳过该样本最终导致实际参与训练的图片数量比预期少一截而你自己根本察觉不到。写个配对脚本import os images_dir furniture_dataset/images/train labels_dir furniture_dataset/labels/train img_names {os.path.splitext(f)[0] for f in os.listdir(images_dir)} label_names {os.path.splitext(f)[0] for f in os.listdir(labels_dir)} missing_labels img_names - label_names # 有图但没有标签 missing_images label_names - img_names # 有标签但没有图 print(图像总数:, len(img_names)) print(标签总数:, len(label_names)) print(缺标签的图像:, list(missing_labels)[:10]) print(缺图像的标签:, list(missing_images)[:10])这段代码的原理是把 images 和 labels 目录里的文件名去掉扩展名后分别放进两个集合集合相减就能找出缺失项。missing_labels表示哪些图像没有对应的 txt 文件missing_images表示哪些标签文件找不到原图。如果缺失数量超过个位数建议直接放弃这批样本因为补标注的时间可能比重下数据集还久。提示校验一定要在训练之前做不要在跑完几十个 epoch 之后才发现某个类别的标签全丢了。3. 拿来即训data.yaml 与 YOLOv5/v8 训练命令目录结构确认无误后就可以进入训练阶段。这一章的核心不是让你背命令而是理解 data.yaml 的配置逻辑以及 YOLOv5 和 YOLOv8 两条训练路径的差异。很多人在这一步翻车原因不是命令记错了而是类别索引和配置文件没对齐。3.1 配置 data.yaml类别数先看标签再填名字前面提过这份数据集只给了类别索引没有提供类别名称。所以第一步是确认最大索引值是多少类别数就是最大索引加一。因为索引从 0 开始最大索引是 4 就代表有 5 个类别。用上一章的统计脚本跑一遍假设输出最大索引为 4那么nc: 5。类别名称列表names需要按索引顺序填写你可以先用占位名跑通流程等检测结果出来再对照图像补上真实名称。# furniture.yaml path: ../furniture_dataset # 相对于data.yaml所在目录的路径 train: images/train val: images/val test: images/test nc: 5 names: 0: chair 1: table 2: sofa 3: bed 4: cabinet配置里有几个容易忽略的点。path最好写相对路径这样把整个项目目录拷贝到另一台机器上只要相对结构不变就能直接训练。train和val的值是相对于path的路径不要再加一层furniture_dataset。names的键值对应的是标签文件里的第一个数字这个顺序决定了最后可视化时显示的类别名如果顺序反了检测结果里会把椅子叫成沙发。3.2 训练命令YOLOv5 和 YOLOv8 各给一套YOLOv5 目前最常用的是 v7.0 分支clone 下来之后直接用train.py。YOLOv8 则整合成了yolo命令行工具配置方式略有不同。两套命令分别如下# YOLOv5 方式 git clone -b v7.0 https://github.com/ultralytics/yolov5.git cd yolov5 pip install -r requirements.txt python train.py --data ../furniture.yaml --weights yolov5s.pt --img 640 --batch 16 --epochs 100 --cache # YOLOv8 方式 pip install ultralytics yolo detect train data../furniture.yaml modelyolov8n.pt epochs100 imgsz640 batch16两套命令的参数逻辑基本一致。--img 640表示输入图像会被 letterbox 缩放为 640x640这是检测速度和精度的折中点--batch 16在 2416 张图像的规模下比较合适显存不足就降到 8--epochs 100对这个量级的数据集够用配合早停机制通常在第 60 到 80 个 epoch 就能收敛。--cache参数会把图像加载到内存里能显著缩短训练时间代价是占用较多内存如果内存只有 16G 就把它去掉。YOLOv8 的modelyolov8n.pt用的是 nano 版本比 YOLOv5 的yolov5s.pt更轻量适合先跑通流程。如果追求更高精度可以换成yolov8m.pt但训练时间会明显变长。初次训练建议用预训练权重而不是从零开始室内家具和 COCO 数据集的部分类别有重叠迁移学习能让你用更少的 epoch 达到可用的效果。3.3 验证与推理看指标之前先看检测结果训练结束后模型权重会保存在runs/train/exp/weights/best.pt。先用验证集跑一次评估拿到 mAP 指标# YOLOv5 python val.py --data ../furniture.yaml --weights runs/train/exp/weights/best.pt # YOLOv8 yolo detect val data../furniture.yaml modelruns/train/exp/weights/best.pt输出里会包含每个类别的 precision、recall 和 mAP50。这个阶段我建议不要只盯 mAP而是先跑一次推理随便挑几张验证集图像看看效果yolo detect predict modelruns/train/exp/weights/best.pt source../furniture_dataset/images/val/000535_187.jpg conf0.25conf0.25表示置信度阈值低于这个值的检测框会被过滤掉。如果看到图像上框的位置偏了先别怀疑模型回到标签可视化这一步排查如果框的位置正确但类别标签错乱那就是前面 data.yaml 里 names 的顺序填错了。这两类问题在指标上都不容易看出来只有直接看检测结果才能定位。4. 避坑五个容易翻车的家具数据集训练问题数据集已经标注好不代表没有坑。以下五个问题是我处理类似资源时遇到过的典型情况每一条都按现象、原因、解决的思路整理你在复现时可以直接对照排查。4.1 类别索引越界训练时直接报错或 mAP 始终很低现象训练到一半报错Label class xx exceeds nc in data或者训练全程 mAP 不超过 0.3。原因data.yaml 里配置的 nc 值小于标签文件中的最大类别索引最常见的情况是只数了类别数却忘了索引从 0 开始导致 nc 少填了一个。也有可能是某些标签文件里混入了错误类别编号。解决在训练前跑一遍第二章的统计脚本打印出最大索引值nc 必须大于等于最大索引值加一。我自己习惯把这条统计写进训练前置脚本每次换数据集都强制跑一遍。4.2 EXIF 旋转手机拍的室内图全变歪现象训练前用图片查看器看图像内容完全正常但训练出的模型检测框整体偏移尤其竖屏拍摄的衣柜、门这类长方形物体最明显。原因手机和部分相机拍摄的 JPEG 图像会写入 EXIF 方向信息OpenCV 的imread默认不处理这个字段读取出来的图像像素还是旋转前的状态而标注工具的预览却自动转正了最终导致框与像素错位。解决训练前统一用 PIL 的ImageOps.exif_transpose()把图像转正并覆盖保存from PIL import Image, ImageOps import os src_dir furniture_dataset/images/train for name in os.listdir(src_dir): path os.path.join(src_dir, name) img Image.open(path) img ImageOps.exif_transpose(img) # 根据EXIF旋转信息转正 img.save(path, quality95)这段脚本会把目录下所有图像按 EXIF 信息转正后写回原文件。quality95只对 JPEG 格式生效如果原图是 PNG 可以去掉这个参数。转正之后标签坐标不需要改动因为 YOLO 坐标是归一化比例只要图像内容旋转到与标注时一致的方向就行。4.3 长宽比差异大letterbox 填充导致的视觉偏移现象检测结果里宽屏长图的检测框上下偏移或者柜子这类细长物体只框住了一部分。原因YOLO 会把输入图缩放到 640x640长宽比大的图会被填充黑边这个过程本身不影响归一化坐标。但如果你在标注阶段先把图像拖到了标注工具的可视化窗口里导出时工具按缩放后的坐标计算坐标就会错位。解决训练前用可视化脚本把几个样本画出来对比标注框和图像内容是否吻合。只要原始标签是正确的letterbox 不会造成问题真正要排查的是标注阶段是否发生过分辨率不一致。4.4 训练中断后 resume续训变成了新实验现象训练到一半因为断电或显存不足中断重启后执行相同的训练命令发现 loss 从头开始之前的训练白跑了。原因YOLOv5 的默认行为是重新开始训练只有显式指定--resume才会读取上次的权重继续训练。YOLOv8 则把 resume 做成了独立的子命令。解决YOLOv5 中断后执行python train.py --resume runs/train/exp/weights/last.ptYOLOv8 执行yolo detect train resumeTrue。需要注意resume会沿用上次的 data.yaml 路径如果你移动过数据集位置需要先改回去再续训。4.5 mAP 很高但现场不准室内场景的泛化落差现象验证集 mAP 达到 0.9 以上但拿自己手机拍的客厅视频测试检测框开始乱飘甚至把盆栽当成人。原因数据集里的图像来自特定房间和角度标注场景的背景、光照都相对一致。验证集与训练集来自同一分布所以指标虚高但真实环境光照和视角一变模型就不认识了。解决收集 50 到 100 张真实场景图做增量训练或者至少留一部分作为测试集单独评估。复用数据集做实验没问题但把它当成生产级模型的唯一数据来源风险要自己承担。5. 训练前先画框把 YOLO 标签还原回图像核对很多人在训练前会看一眼标签文件觉得坐标范围没问题就开始了但数字层面的合法性并不能保证框的位置正确。YOLO 归一化坐标的可读性很差0.483 0.412 0.215 0.267这样的数字你很难直观判断它是否准确框住了椅子。我的习惯是先把标签画回图像上用眼睛确认一遍再训练这一步能筛掉大部分标注质量问题。5.1 单张可视化把归一化坐标转成像素坐标画框的原理很简单归一化坐标乘上图像的宽高就得到像素坐标。中心点坐标加减一半宽高就能得到矩形左上角和右下角的坐标。需要注意宽度和高度同样是归一化比例所以要乘图像宽、图像高不要搞混哪个乘哪个。import cv2 img_path furniture_dataset/images/val/000535_187.jpg txt_path furniture_dataset/labels/val/000535_187.txt img cv2.imread(img_path) h, w img.shape[:2] with open(txt_path, r) as f: for line in f: cls, x_c, y_c, bw, bh line.strip().split() cls, x_c, y_c, bw, bh int(cls), float(x_c), float(y_c), float(bw), float(bh) x1 int((x_c - bw / 2) * w) y1 int((y_c - bh / 2) * h) x2 int((x_c bw / 2) * w) y2 int((y_c bh / 2) * h) cv2.rectangle(img, (x1, y1), (x2, y2), (0, 255, 0), 2) cv2.putText(img, fcls_{cls}, (x1, y1 - 5), cv2.FONT_HERSHEY_SIMPLEX, 0.6, (0, 255, 0), 1) cv2.imwrite(check_000535.jpg, img) print(f图像尺寸: {w}x{h}, 检测到 {len(open(txt_path).readlines())} 个目标)这段脚本读取图像和对应的标签文件逐个把归一化坐标换算成像素坐标并画框。cv2.rectangle里的绿色框线粗细设为 2 像素在 640 宽度的缩略图上刚好可见。cv2.putText的文本内容用cls_{cls}占位如果你已经知道类别名称可以改成真实名称。运行后打开check_000535.jpg重点看两个点框是否紧贴物体边缘、类别编号是否和物体类型对得上。5.2 批量核对一次跑完整个验证集单张核对只能排除个例真正的检查方式是批量生成所有验证集图像的标注框然后随机抽取几十张快速浏览。写一个循环脚本import cv2 import os base furniture_dataset for split in [train, val, test]: img_dir os.path.join(base, images, split) txt_dir os.path.join(base, labels, split) out_dir os.path.join(check_output, split) os.makedirs(out_dir, exist_okTrue) for name in os.listdir(txt_dir): if not name.endswith(.txt): continue img_path os.path.join(img_dir, name.replace(.txt, .jpg)) if not os.path.exists(img_path): continue img cv2.imread(img_path) h, w img.shape[:2] with open(os.path.join(txt_dir, name)) as f: for line in f: if len(line.strip().split()) ! 5: continue cls, x_c, y_c, bw, bh line.strip().split() cls, x_c, y_c, bw, bh int(cls), float(x_c), float(y_c), float(bw), float(bh) x1 int((x_c - bw / 2) * w) y1 int((y_c - bh / 2) * h) x2 int((x_c bw / 2) * w) y2 int((y_c bh / 2) * h) cv2.rectangle(img, (x1, y1), (x2, y2), (0, 255, 0), 2) cv2.imwrite(os.path.join(out_dir, name.replace(.txt, .jpg)), img)这个脚本遍历 train、val、test 三个目录把每张图对应的标签框画好并保存到check_output目录。代码里做了一个容错如果某行字段数不是五个就直接跳过避免脏数据让整个脚本崩溃。批量输出之后用图片查看器按文件名排序浏览我一般会每隔十张抽取一张仔细看检查是否存在框完全偏离目标的情况比如框住了背景墙面或者半个物体。5.3 指标解读评估结果里哪些数值得信训练结束后验证输出里会出现 precision、recall 和 mAP50 这几个指标。在室内家具这类单类别或少量类别的数据集上mAP50 达到 0.9 以上说明基础目标基本都能框住但这个指标对边缘框位置不敏感框偏移一点不会显著降低分数。如果 mAP50 高但 mAP50-95 低通常意味着框的定位精度不够如果 recall 明显低于 precision说明不少目标被漏检了重点去看遮挡和暗光条件下的样本。6. 再进一步轻量模型、数据增强与 ONNX 导出模型跑通只是第一步。2416 张图像的规模决定了它比较适合做实验和验证真要用到实际场景还有三个方向值得投入时间。第一个方向是模型体积与速度的取舍。先用 YOLOv5s 或 YOLOv8n 跑通后如果目的是部署到 CPU 或边缘设备可以换成 YOLOv8n 并用yolo export modelbest.pt formatonnx导出 ONNX 格式。ONNX 导出后配合 ONNX Runtime 推理比直接跑 PyTorch 模型内存占用更小速度也更快。导出命令很简单yolo export modelruns/train/exp/weights/best.pt formatonnx dynamicTrue其中dynamicTrue允许动态输入尺寸这样推理时不用强制缩放到训练用的 640可以根据实际图像长宽比做 letterbox 后送入模型对小目标检测有微弱提升。导出完成后用onnxruntime加载模型输入输出张量的形状可以先打印确认再写推理脚本。第二个方向是数据增强的针对性调整。YOLOv5 和 YOLOv8 默认开启 mosaic 增强把四张图拼成一张训练对提升小目标检测有帮助。但室内家具场景里mosaic 拼出来的图像和真实场景差异较大如果训练后期发现验证集 mAP 上不去可以尝试关闭一部分增强或降低增强强度比如把mosaic关掉让模型专注学单张图像里的家具形状。第三个方向是针对类别不均衡做处理。如果统计脚本发现某个类别样本数量很少训练时给这个小类别适当增加权重或者用小类别样本做复制粘贴增强避免模型为了刷整体精度而忽略稀有类别。从那以后我每拿到一个数据集第一件事永远是画框核对再加类别统计这两步跑完才会去改训练命令。做室内家具检测这类任务数据质量决定上限训练调参只是逼近这个上限的手段。这套数据集省掉了你最费力的标注环节但验证和排查的功夫省不得。希望帮到你。本文还有配套的精品资源点击获取
阅读完成 · 觉得有帮助?
咨询建站