ARTICLE DETAIL

资讯详情

深耕郑州网站建设与运营推广的一线实战洞察。

电瓶车进电梯检测:200张VOC+YOLO双格式数据集实战指南

电瓶车进电梯检测:200张VOC+YOLO双格式数据集实战指南 简介这份电瓶车进入电梯检测数据集面向计算机视觉初学者与目标检测开发者用于训练和验证电梯场景下的电瓶车识别模型可服务于社区安全监控、智能楼宇管理等实际应用。资源包共602个文件包含200张jpg原图、200个Pascal VOC格式xml标注文件、200个YOLO格式txt标注文件另有少量说明文件压缩包约11.07MB两种标注格式可分别适配不同训练框架省去格式转换步骤。全部图片由labelImg手工画框标注仅设electric scooter一个类别共210个标注框标注准确合理可直接投入训练使用。目前已有205人学习下载适合需要快速验证算法或搭建电梯禁入电瓶车预警原型的读者参考能帮助节省数据采集与标注时间将精力集中在模型调优与部署上。1. 电瓶车进电梯检测200 张 VOCYOLO 双格式数据集能落地到什么程度电瓶车进电梯这个场景做目标检测的人多半都碰过——物业要告警、电梯要联动停梯、摄像头要抓拍需求方张口就是识别到电动车就报警。真上手才发现公开数据集里找electric scooter这个类别的少得可怜COCO 里没有独立类别自己从监控里截图标框又费时费力。这份 200 张、VOC 与 YOLO 双格式、单类别electric scooter、共 210 个标注框的数据集正好卡在这个缺口上规模不大但胜在格式齐全、标注工具统一labelImg、拿来就能跑通训练链路。它适合两类人——想快速验证电梯轿厢内电瓶车检测可行性的算法工程师以及需要一个小而干净的单类别数据集练手 YOLO 全流程的新手。需要先说明的是数据集只提供标注不对任何模型精度作保证能不能用出效果取决于你的增广策略和场景匹配度。2. 拆开压缩包VOC 与 YOLO 双格式到底怎么对应2.1 目录结构与文件命名规律解压后你会看到图片和标注是分开组织的典型结构是这样dataset/ ├── JPEGImages/ # 200 张 jpg 原图 │ ├── dianpingche_xyxr_43.jpg │ ├── dianpingche_xyxr_46.jpg │ └── ... ├── Annotations/ # 200 个 VOC xml │ ├── dianpingche_xyxr_43.xml │ └── ... └── labels/ # 200 个 YOLO txt ├── dianpingche_xyxr_43.txt └── ...文件名dianpingche_xyxr_数字是统一前缀加序号图片、xml、txt 三者同名这是最省心的组织方式——转换脚本、训练配置都靠文件名对齐不用额外维护映射表。200 张图对应 200 个 xml 和 200 个 txt数量一一对应说明标注是完整覆盖的没有漏标文件。实际用之前建议先跑一遍数量核对避免解压丢文件这种低级翻车。2.2 VOC xml 里到底存了什么VOC 格式的 xml 是人类可读的那一份用文本编辑器打开任意一个就能看到全部信息annotation folderJPEGImages/folder filenamedianpingche_xyxr_43.jpg/filename size width640/width height480/height depth3/depth /size object nameelectric scooter/name poseUnspecified/pose truncated0/truncated difficult0/difficult bndbox xmin112/xmin ymin88/ymin xmax430/xmax ymax402/ymax /bndbox /object /annotation关键字段就几个size记录原图宽高object/name是类别名bndbox是左上角和右下角坐标。注意name写的是electric scooter中间带空格——这一点后面训练配置里要特别处理YOLO 的类别名如果直接照搬空格在某些版本的 data.yaml 解析里会出问题稳妥做法是改成下划线electric_scooter或者干脆用scooter。truncated和difficult这里都是 0说明标注时没有标记截断和难例训练时不用做特殊过滤。2.3 YOLO txt 的归一化坐标逻辑YOLO 格式的 txt 每行一个目标格式是类别索引 中心x 中心y 宽 高且全部归一化到 0~10 0.4234 0.5104 0.4969 0.6542这行对应上面那个框中心 x (112430)/2/640 ≈ 0.4234中心 y (88402)/2/480 ≈ 0.5104宽 (430-112)/640 ≈ 0.4969高 (402-88)/480 ≈ 0.6542。因为只有一个类别类别索引恒为 0。这里有个容易忽略的点归一化用的是每张图自己的宽高不是统一尺寸所以如果你的图尺寸不一致YOLO 这边是天然支持的但 VOC 那边读框时一定要按各自size还原不能拿一个固定分辨率去套。2.4 两种格式的取舍什么时候用哪个维度VOC xmlYOLO txt可读性高含尺寸和类别名低纯数字训练框架Faster R-CNN、SSD、MMDetectionYOLO 系列、Ultralytics坐标形式绝对像素归一化中心点增广兼容需同步改 xml直接缩放即可本数据集用途复核标注、转其他格式直接喂 YOLO 训练我一般会保留 VOC 作为母版因为改类别名、查漏标都方便YOLO txt 作为训练输入。两者同源转换方向是单向的——从 VOC 生成 YOLO 容易反过来还原类别名和尺寸就麻烦。所以别删 xml。3. 从零跑通 YOLO 训练配置、命令与参数3.1 环境与目录准备先按 Ultralytics 的标准布局整理数据这是最不容易出错的方案mkdir -p datasets/scooter/images/train datasets/scooter/images/val mkdir -p datasets/scooter/labels/train datasets/scooter/labels/val # 假设解压后图片在 JPEGImages标注在 labels # 按 8:2 划分这里用简单脚本实际可用 splitfolders python - PY import os, random, shutil random.seed(42) img_dir JPEGImages lbl_dir labels imgs [f for f in os.listdir(img_dir) if f.endswith(.jpg)] random.shuffle(imgs) n_val int(len(imgs) * 0.2) val_set set(imgs[:n_val]) for f in imgs: stem os.path.splitext(f)[0] split val if f in val_set else train shutil.copy(os.path.join(img_dir, f), fdatasets/scooter/images/{split}/{f}) shutil.copy(os.path.join(lbl_dir, stem .txt), fdatasets/scooter/labels/{split}/{stem}.txt) print(done, len(imgs)) PY这段脚本做三件事建标准目录、固定随机种子打乱、按 8:2 把图片和同名 txt 一起搬到 train/val。固定seed42是为了可复现换机器跑结果一致。200 张的规模验证集 40 张够看 loss 曲线和 mAP 趋势但别指望验证集指标有多稳——小数据集的 mAP 波动是常态这点后面避坑章节会细说。3.2 data.yaml 的写法与类别名坑path: ./datasets/scooter train: images/train val: images/val names: 0: electric_scooternames这里我把原来的electric scooter改成了下划线。原因是 YAML 里带空格的值虽然加引号能解析但部分训练脚本在读取类别名做可视化时会按空格切分导致标签显示错乱。统一成下划线或驼峰是省后悔药的做法。nc字段在新版 Ultralytics 里可以省略它会从names长度自动推断写不写都行但显式写nc: 1更保险。3.3 训练命令与关键参数yolo detect train \ datadatasets/scooter/data.yaml \ modelyolov8n.pt \ epochs100 \ imgsz640 \ batch16 \ lr00.01 \ patience30 \ projectruns/scooter \ nameexp1逐项说modelyolov8n.pt用 nano 版200 张图用大模型纯属浪费n 版足够epochs100配合patience3030 轮没提升就早停避免过拟合imgsz640是通用起点如果你的原图分辨率远高于 640可以试 960但小数据集上高分辨率容易过拟合batch16在 8G 显存上跑 640 分辨率基本稳显存小就降到 8。lr00.01是默认值小数据集不建议调大容易震荡。3.4 训练过程该盯什么启动后重点看三样box_loss是否稳定下降、mAP50是否在 20 轮后开始抬头、验证集 loss 有没有和训练集背离。200 张图、单类别正常情况 50 轮内 mAP50 能到 0.8 以上如果 30 轮还趴在地上八成是标签路径没对上或者类别索引错了。训练完在runs/scooter/exp1/weights/下拿best.pt用yolo detect predict modelbest.pt source你的测试图跑几张电梯场景图看效果比看指标直观。4. 小数据集训练的避坑清单五个真实翻车点4.1 现象训练 loss 不降mAP 恒为 0原因最常见的是 labels 路径和 images 路径没对齐YOLO 找不到标注文件把全部图当负样本训。也可能是 txt 里的类别索引不是 0比如误写成 1而 names 只有 0 一个类别越界被丢弃。解决先跑一句核对脚本确认每张图都有同名 txt且 txt 首列全是 0# 检查图片与标注是否一一对应 for f in datasets/scooter/images/train/*.jpg; do stem$(basename $f .jpg) [ -f datasets/scooter/labels/train/$stem.txt ] || echo 缺失: $stem done # 检查类别索引 awk {print $1} datasets/scooter/labels/train/*.txt | sort -u第二条命令输出应该只有0出现别的数字就是标注有问题。4.2 现象验证集 mAP 忽高忽低两次训练差很多原因200 张图、40 张验证集样本量太小随机划分一变验证集分布就变指标自然抖。这不是模型的问题是数据规模决定的。解决固定划分种子上面脚本里的seed42并且用 K 折或者多次不同种子取平均来看真实水平。别拿单次 mAP 当结论更别为了刷高验证集指标去反复调划分——那是自欺欺人。4.3 现象模型在训练集上很好实际电梯监控里漏检严重原因数据集里的电瓶车大概率是特定角度、特定光照拍的和真实电梯轿厢的俯视/斜视视角、夜间补光差异大。单类别 210 个框覆盖不了姿态多样性。解决训练时开强增广mosaic、hsv_h、hsv_v、degrees都拉起来模拟光照和角度变化yolo detect train datadatasets/scooter/data.yaml modelyolov8n.pt \ epochs100 imgsz640 mosaic1.0 degrees15.0 \ hsv_h0.015 hsv_s0.7 hsv_v0.4 translate0.1 scale0.5degrees15允许旋转增广hsv_v0.4模拟明暗变化scale0.5应对远近。但增广不是万能药真要落地还是得补真实场景的图。4.4 现象VOC 转 YOLO 后框位置整体偏移原因转换时把归一化分母写成了固定尺寸比如统一按 640×480而实际图片尺寸不一。或者坐标算的是左上右下却按中心点格式写。解决转换脚本必须逐图读size字段用各自的宽高归一化。下面这段是可靠的转换核心import xml.etree.ElementTree as ET import os def voc_to_yolo(xml_path, out_path, class_map): tree ET.parse(xml_path) root tree.getroot() size root.find(size) w int(size.find(width).text) h int(size.find(height).text) lines [] for obj in root.iter(object): name obj.find(name).text if name not in class_map: continue cls_id class_map[name] bnd obj.find(bndbox) xmin float(bnd.find(xmin).text) ymin float(bnd.find(ymin).text) xmax float(bnd.find(xmax).text) ymax float(bnd.find(ymax).text) # 归一化中心点格式 cx (xmin xmax) / 2.0 / w cy (ymin ymax) / 2.0 / h bw (xmax - xmin) / w bh (ymax - ymin) / h lines.append(f{cls_id} {cx:.6f} {cy:.6f} {bw:.6f} {bh:.6f}) with open(out_path, w) as f: f.write(\n.join(lines))class_map传{electric scooter: 0}注意这里用的是 xml 里的原始类别名带空格映射到索引 0。归一化分母用每张图自己的w、h这是不偏移的关键。4.5 现象data.yaml 报类别数不匹配原因names 里写了 1 个类别但某个 txt 里出现了索引 1 甚至更大或者反过来 names 写了多个但数据只有 0。解决训练前统一扫一遍所有 txt 的最大类别索引和 names 长度对齐。上面 4.1 的awk命令就能查出来。养成训练前先扫标签的习惯能省掉大量对着 loss 曲线发呆的时间。5. 把 200 张用出 2000 张的效果增广、验证与迭代技巧小数据集的出路不在模型在数据工程。200 张、210 个框直接训能出个能看的模型但要真上电梯得靠增广和迭代把覆盖面撑起来。我一般会分三步走。第一步是离线增广扩样本。除了训练时开在线增广还可以用 albumentations 做一批离线增强图重点补三类变化亮度模拟白天/夜间补光、透视模拟摄像头安装角度差异、遮挡模拟电梯里有人或杂物挡着。离线增广的好处是能人工筛掉明显不合理的样本比如把电瓶车旋转到倒立的图直接扔掉。下面是个最小示例import albumentations as A import cv2, os transform A.Compose([ A.RandomBrightnessContrast(brightness_limit0.3, contrast_limit0.3, p0.8), A.Perspective(scale(0.05, 0.1), p0.5), A.HorizontalFlip(p0.5), ], bbox_paramsA.BboxParams(formatyolo, label_fields[cls])) # 读图、读 yolo 标签转成 albumentations 需要的格式后 transform # 再写回图片和 txt。注意 bbox 要过滤越界和过小的框。formatyolo让 albumentations 直接吃归一化坐标省去手动换算。Perspective的scale别开太大0.1 以上框会变形到不真实。增广后记得过滤掉宽或高小于 0.01 的框那是噪声。第二步是拿真实场景图做伪标注迭代。找几段电梯监控视频抽帧后用训好的best.pt跑推理把置信度高的检测结果当伪标签人工快速过一遍修正再混进训练集。这是小数据集滚雪球的标准打法一轮下来往往能补几十张真实分布图比纯增广管用得多。伪标签的置信度阈值我一般设 0.6太低会引入大量错标。第三步是验证要分场景。别只看整体 mAP把测试图按白天/夜间有人/无人正视/斜视分组分别算召回。电梯场景最怕的是漏检——漏一辆电瓶车进电梯告警就失效了。所以宁可牺牲一点精确率也要把召回拉高推理时conf阈值可以设低到 0.25 再配合后处理去误报。迭代轮次数据构成预期 mAP50重点基线200 张原始0.80~0.88跑通链路一轮增广500 张离线增强0.85~0.90补光照角度伪标签迭代真实监控帧0.88~0.93对齐真实分布这张表里的数字是我在类似规模单类别数据集上的经验区间不是这份数据集的承诺值——数据集本身不保证精度实际以你自己的验证为准。从那以后我每次拿到这种小规模单类别数据集都强制先跑一遍标签体检数量对齐、类别索引、坐标范围三样查完再开训省得对着不降的 loss 曲线怀疑人生。这份 200 张 VOCYOLO 双格式的电瓶车进电梯数据集胜在干净、格式全、开箱即用适合当验证想法的第一块砖。希望帮到你。本文还有配套的精品资源点击获取
返回列表