
简介这份电瓶车进入电梯检测数据集面向计算机视觉初学者与目标检测开发者用于训练和验证电梯场景下的电瓶车识别模型可服务于社区安全预警、智能楼宇管理等实际应用。资源包共602个文件包含200张jpg原始图片、200个xml标注文件与202个txt标签文件分别对应Pascal VOC与YOLO两种主流格式压缩包约11.07MB方便直接接入YOLO系列或VOC兼容框架。全部图片由labelImg手工画框标注仅设electric scooter一个类别累计210个标注框标注规则统一、边界清晰适合作为小样本训练或格式转换练习素材。目前已有205人学习下载读者可借此快速搭建数据加载流程、验证模型在电梯狭小空间内的检测效果并对比两种标注格式的差异为后续扩充数据集或迁移到其他场景提供参考。1. 电瓶车进电梯检测200 张 VOCYOLO 数据集到底能干什么电瓶车进电梯检测说白了就是让摄像头认出「电梯轿厢里有没有电动车」然后联动梯控或语音告警。这个场景的难点不在模型多深而在数据电梯内光照差、镜面不锈钢反光、车只露一半、人和车挤在一起公开的大规模数据集基本不覆盖。所以当你看到一份 200 张、VOCYOLO 双格式的电瓶车进入电梯检测数据集第一反应应该是——它够不够跑通一个能用的基线而不是够不够发论文。这份数据的定位很清楚小样本、单类别或极少类别、场景高度垂直。它适合三类人一是想快速验证「电梯场景目标检测」可行性的算法同学二是做社区/物业 AI 摄像头方案、需要先跑个 demo 的工程同学三是刚入门目标检测、想拿一个真实小数据集练 VOC 转 YOLO、练训练调参的新手。200 张不是拿来刷 mAP 的是拿来把「数据长什么样、格式怎么转、模型怎么训、坑在哪」这条链路走通的。下面按这条链路拆开讲。2. 先看清数据VOC 与 YOLO 两种标注格式的差异与转换2.1 VOC 的 XML 结构和 YOLO 的 txt 到底差在哪VOC 格式每张图对应一个同名 XML核心信息在object里类别名name以及bndbox下的xmin/ymin/xmax/ymax这四个值是绝对像素坐标原点在左上角。YOLO 格式每张图对应一个同名 txt每行一个目标class_id x_center y_center width height后四个都是归一化到 0~1 的相对值且是框的中心点和宽高不是角点。这个差异决定了转换时最容易翻车的地方一是坐标要从绝对转相对必须除以图宽和图高除错了框就飞到画面外二是 VOC 的角点要转成中心点加宽高公式是xc(xminxmax)/2/w、yc(yminymax)/2/h、bw(xmax-xmin)/w、bh(ymax-ymin)/h三是类别名要映射成从 0 开始的整数 id映射表一旦和训练时的names对不上模型学出来的类别就是错的。200 张这个量级人工核对一遍是可行的别偷懒。转换脚本跑完抽 10 张用可视化工具画框看一眼比什么都强。2.2 用脚本把 VOC 批量转成 YOLO 并做校验下面这段脚本做三件事遍历 XML、解析框、按类别映射写 txt同时把图宽高从 XML 的size里读出来比用 PIL 再开一次图快。类别映射我一般写成显式字典避免顺序错乱。import os import xml.etree.ElementTree as ET # 类别名 - id顺序必须和训练时 data.yaml 的 names 完全一致 CLASS_MAP {ebike: 0} # 若数据里有 person 等类别按实际补全 VOC_DIR VOC/Annotations # 存放 xml 的目录 IMG_DIR VOC/JPEGImages # 存放 jpg 的目录 OUT_DIR labels # 输出 yolo txt 的目录 os.makedirs(OUT_DIR, exist_okTrue) for xml_name in os.listdir(VOC_DIR): if not xml_name.endswith(.xml): continue tree ET.parse(os.path.join(VOC_DIR, xml_name)) root tree.getroot() # 从 xml 里直接读图宽高避免再开一次图片 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.strip() if name not in CLASS_MAP: continue # 未登记类别直接跳过防止 id 错位 cls_id CLASS_MAP[name] box obj.find(bndbox) xmin float(box.find(xmin).text) ymin float(box.find(ymin).text) xmax float(box.find(xmax).text) ymax float(box.find(ymax).text) # 角点 - 中心点 宽高再归一化 xc (xmin xmax) / 2.0 / w yc (ymin ymax) / 2.0 / h bw (xmax - xmin) / w bh (ymax - ymin) / h # 越界裁剪防止个别标注超出图像边界 xc, yc min(max(xc, 0), 1), min(max(yc, 0), 1) bw, bh min(max(bw, 0), 1), min(max(bh, 0), 1) lines.append(f{cls_id} {xc:.6f} {yc:.6f} {bw:.6f} {bh:.6f}) out_name xml_name.replace(.xml, .txt) with open(os.path.join(OUT_DIR, out_name), w) as f: f.write(\n.join(lines))逻辑说明CLASS_MAP是整条链路的命门训练配置里的names必须和它逐项对应否则类别 id 全乱。size从 XML 读而不是用 PIL是因为 VOC 标注里的宽高就是标注时的图尺寸用它最稳。越界裁剪那两行是后悔药——手工标注难免有框超出边界不裁的话归一化值会大于 1部分训练框架会直接报错或静默丢弃。参数说明xc/yc/bw/bh保留 6 位小数足够YOLO 官方格式对精度不敏感CLASS_MAP里如果只有电瓶车一类就是单类别检测nc1。转换完建议写个校验脚本统计每个 txt 的行数、检查是否有空文件、检查归一化值是否都在 0~1 之间这三项能挡掉大部分脏数据。2.3 划分训练集验证集时别踩的分布坑200 张的划分常见做法是 8:2即 160 训练、40 验证。但电梯场景有个陷阱同一部电梯、同一时段拍的连续帧画面几乎一样。如果随机划分训练集和验证集里会出现高度相似的图验证 mAP 虚高上线就翻车。正确做法是按「电梯编号 拍摄时段」分组划分同一组只进训练或只进验证。数据量小的时候验证集 40 张里如果只有一两部电梯指标波动会很大建议至少覆盖 3 部以上不同电梯或者干脆用 5 折交叉验证看稳定性别只信一次划分的结果。3. 用 YOLO 把这份数据集跑通环境、配置与训练命令3.1 环境配置与目录结构现在主流做法是用 ultralytics 的 YOLO 系列YOLOv8/v11 这一支它对小数据集友好、命令行简洁。环境用 conda 建一个干净环境装 torch 和 ultralytics 即可。目录结构建议按官方约定摆省得改配置dataset/ images/ train/ # 160 张 jpg val/ # 40 张 jpg labels/ train/ # 对应 txt val/ data.yamldata.yaml是训练入口配置内容如下path: /abs/path/to/dataset # 数据集根目录建议写绝对路径 train: images/train val: images/val nc: 1 names: [ebike] # 必须和转换脚本里的 CLASS_MAP 一致path写绝对路径能避免「找不到图片」这类玄学问题nc和names必须和标注映射严格对应这是最常见的低级错误来源。3.2 训练命令与关键参数怎么设一条最小可跑的命令yolo detect train \ datadataset/data.yaml \ modelyolov8n.pt \ epochs100 \ imgsz640 \ batch16 \ lr00.01 \ patience30 \ projectruns/ebike \ nameexp1参数说明modelyolov8n.pt选 nano 版200 张数据用大模型纯属浪费还算得慢nano 足够验证可行性epochs100配合patience30意思是 30 轮指标不涨就早停小数据集很容易过拟合早停是必须的imgsz640是通用值电梯场景目标通常不小640 够用显存紧张可降到 416batch16按显存调8G 显存跑 nano640 一般能到 16~32lr00.01是默认起点如果 loss 一开始就震荡降到 0.001 再试。训练时重点盯两个信号train/box_loss和val/box_loss。如果训练 loss 一直降、验证 loss 先降后升就是过拟合靠早停和加数据增强压。YOLO 默认开了 mosaic、翻转等增强小数据集上这些增强是救命的别关。3.3 推理验证与结果怎么看训练完在验证集上跑yolo detect val modelruns/ebike/exp1/weights/best.pt datadataset/data.yaml输出里重点看mAP50和mAP50-95。200 张、单类别、场景单一的情况下mAP50 跑到 0.8 以上是正常的如果只有 0.3~0.4先别怀疑模型回去查标注框有没有画歪、有没有漏标、类别 id 有没有错。用yolo detect predict跑几张图存下来肉眼看比盯数字有用。电梯场景还要专门看反光和暗光下的漏检这两类是上线后投诉最多的。4. 小数据集训练电瓶车检测的避坑清单4.1 现象验证 mAP 很高实际摄像头一接就废原因验证集和训练集来自同一部电梯、同一时段分布几乎重合模型只是记住了这几部电梯的画面没学到「电瓶车」的通用特征。解决按电梯和时段分组划分验证集必须包含训练时没见过的电梯如果实在凑不出至少做一次「留一部电梯出来」的测试看指标掉多少心里有数。4.2 现象训练一开始 loss 就是 nan原因标注里有归一化值超出 0~1 的框或者 txt 里出现了空行、类别 id 超出nc范围。解决跑一遍校验脚本检查每个 txt 的每行是否恰好 5 个字段、id 是否在[0, nc-1]、四个坐标是否都在 0~1。转换脚本里的越界裁剪能挡掉一部分但手工改过的标注要重新查。4.3 现象模型把电梯里的镜子倒影也框成电瓶车原因电梯镜面不锈钢反光倒影和真车外观接近200 张里如果这类样本少模型分不清。解决这类是数据问题不是模型问题要么补拍带反光的样本并正确标注倒影不标要么在推理侧加后处理比如限制检测框只在画面下半部分生效。别指望换个损失函数能解决。4.4 现象人和电瓶车重叠时车被漏检原因小数据集里遮挡样本太少模型没学过「只露一半的车」。解决训练时开大 mosaic 增强比例或者手动补几十张遮挡样本推理时把conf阈值从默认 0.25 降到 0.15 试试但要注意误检会上升得权衡。4.5 现象换一台分辨率不同的摄像头检测全乱原因训练图的分辨率和推理输入不一致或者训练时imgsz设得和实际部署差太多。解决训练和推理的imgsz保持一致如果部署端摄像头是 1080p训练时也尽量用接近的分辨率或者统一 letterbox 到 640。分辨率这件事训练和部署不一致就是自找麻烦。5. 从 200 张到能用数据增强与主动学习的进阶打法200 张能跑通基线但要真上线得靠增强和持续补数据。我一般这么做先用这份数据训一个初版模型部署到一两部电梯上跑推理把置信度在 0.3~0.6 之间的「模糊样本」自动截下来人工确认后加进训练集这就是最朴素的主动学习闭环。每轮补 50~100 张补两三轮回合模型在真实场景的漏检会明显下降。增强方面电梯场景最值得开的是亮度/对比度扰动和随机遮挡因为暗光和遮挡是主要难点。YOLO 的hsv_v亮度增强可以适当调大mosaic保持默认。但要注意增强不能替代真实样本它只是让 200 张的利用率更高天花板还是由数据分布决定的。验证方法上别只看 mAP。做一个「分场景测试集」暗光、反光、遮挡、多人多车各挑 10~20 张分别统计召回率。哪个场景召回低就针对性补数据。这个习惯比追单一指标有用得多。最后说个我自己的教训早期我拿到小数据集就急着调模型结构、换损失函数折腾一圈发现指标没动回头一看是标注里有一批框画到了电梯门外。数据集的活八成时间该花在看数据和洗数据上模型那点事YOLO 默认配置已经够用了。希望帮到你。本文还有配套的精品资源点击获取