
简介面向电梯内人车识别任务的目标检测数据集包含97张真实监控视角图片标注了人、摩托车、自行车三类目标适用于YOLO系列、Faster R-CNN、SSD等主流目标检测模型训练也适合目标检测入门者熟悉标注格式与训练流程。图片均来自真实电梯监控视角覆盖不同时间、角度和光照条件目标大小和姿态变化丰富有助于提升模型在封闭小场景中的鲁棒性和泛化能力。数据集标注格式规范兼容YOLO与VOC两种常用格式便于数据增强与格式转换。资源包共2000个文件由1999个txt格式标签文件和1个yaml类别配置文件构成txt文件记录每张图片的目标框坐标与类别yaml文件声明类别名称可直接用于YOLOv5至YOLOv10等版本训练。压缩包约193.33MB整体结构简洁下载后无需额外整理即可开始训练节省数据采集与标注时间。目前已有201人学习下载适合电梯安防、智能楼宇等实际项目落地。1. 电梯内人车识别数据集为什么通用目标检测在电梯里会“翻车”电梯内人车识别数据集听起来像“把 COCO 里的 person 和 bicycle 筛出来再训一遍”但真正拿通用目标检测模型在电梯轿厢里跑过的人都知道这一招几乎必然翻车。轿厢空间小、机位高目标在画面里只占几十个像素开门瞬间逆光、关门后灯箱反光再加上人与电动车相互遮挡漏检和误检率比开阔道路场景高出一大截。这类数据集要解决的问题很具体物业和社区想自动识别电动车进电梯、轿厢内人员滞留或异常状态并把结果接入告警系统。它适合刚接手算法验证的工程师也适合准备自建电梯安全视觉方案的团队。下面我会把数据结构、标注口径、YOLO 训练参数和排错经验完整拆开让一套可用数据拿回来之后能少走弯路直接落地。2. 先把“人车”拆清楚电梯场景的数据形态、标注口径与模型选型2.1 电梯内“人车”指的是谁类别定义与常见误标拿到任何一份电梯内人车识别数据集第一件事不是选模型而是把类别定义看明白。轿厢里很少出现真正的汽车所谓的“车”绝大多数是电动自行车、自行车、轮椅、婴儿车、手推车。很多数据集直接把它们统一标成 vehicle这会在训练里埋下极大的混淆电动车的车身线条、车轮纹理和轮椅结构差异很大如果被塞进同一个类模型必须学会“所有带轮子的物体”这个抽象概念而样本数量又不足以支撑这种抽象。我习惯先按业务诉求把类别拆开。如果社区物业只想知道“有没有电动车入梯”用 person e-bike 两类就够如果需要兼顾无障碍设施监测就再加 wheelchair、stroller。一个可用的类别体系如下表类别 id标签名语义常见误标0person轿厢内乘客含抱婴、蹲坐、背向镜头把轮椅上的老人整体标成 person1e-bike电动自行车、电动滑板车把外卖保温箱当成车身一部分2wheelchair轮椅将其归入 e-bike3stroller婴儿车、手推车和轮椅混淆导致同类目标框形状差异过大类别定义直接影响边界框的几何分布。电梯监控大多是从顶部或侧前方斜拍电动车的边界框呈现出明显的长条形宽度高度比经常小于 0.5人的框则相对竖高。如果标注时把“电动车后座的外卖箱”强行并进框里框的高宽比会被拉得更极端模型学习到的就不是车辆结构而是“一种样本里出现过的奇形轮廓”。训练后换个角度或换辆车就漏检。我通常会在标注规范里写明一条铁律框必须包住目标主体突出物如车筐、外卖箱、扶手可以不包含进框无法确认边界时把该区域画成 ignore 区域而不是硬拉一个大框。这样做的原因是目标检测损失函数对边框回归的惩罚非常敏感一个标注偏差超过 30% 的框会直接拖累同类别的 AP 好几个点。2.2 数据从哪来、怎么标一份可落地的标注规范电梯内人车识别数据集的来源渠道很杂常见做法是从电梯监控录像抽帧。服务器拉流后用 ffmpeg 按 1fps 到 5fps 抽帧再人工挑选画面。要重点覆盖六种工况白天轿厢门关闭、白天开门瞬间、夜间照明开启、夜间应急灯或黑白红外模式、轿厢内有人无车、人推车进入。只抽同一段连续视频的高相似帧会让训练集和验证集之间的差异过小最后验证精度虚高部署时换个电梯就失效。抽完帧后进入标注阶段。开源工具推荐 CVAT 或 LabelImg导出格式选择 YOLO txt。标注画面时有两个关键规范第一遮挡超过 50% 的目标不标人与车重叠至少露头时人和车都要独立标注不能把两者框进同一个框。第二轿厢镜面或金属门板反光里的“虚像”不标这个虚像如果被框进去训练出的模型会把反光里的轮廓也当作有效目标推理阶段同一人在镜面两侧出现两个框后处理去重都救不回来。一份标注样本的 txt 内容长这样0 0.472656 0.602344 0.238281 0.168750 1 0.390625 0.620750 0.205469 0.254500每行五个值类别 id归一化中心点 x归一化中心点 y归一化宽度归一化高度。所有值都在 0 到 1 之间由标注工具自动换算不需要手动计算。拿到别人的数据集时我会先写一个脚本把所有 txt 扫描一遍检查有没有坐标小于 0 或大于 1 的脏数据这类脏标签不会让程序报错但会让训练 Loss 异常波动。数据集切分也要提前做好。我通常按 70% 训练、20% 验证、10% 测试划分并且强制同一段录像的帧只能出现在其中一个集合里。如果训练和验证集里混有同一组连续帧模型等于把题目和答案一起看了验证 Loss 看起来很好真实场景里换一台电梯立刻现原形。这种问题在监控类数据集里极其常见是电梯人车项目里第一个需要防的坑。2.3 选型为什么 YOLO 系比两阶段模型更合适电梯内人车识别数据集的核心落地场景是实时告警这决定了模型选型必须把推理速度和部署难度放在首位。以 Ultralytics YOLO 系列为代表的单阶段 anchor-free 检测器是目前最稳妥的选择。两阶段模型如 Faster R-CNN 精度略高但对算力要求更高在 Jetson 或嵌入式盒子上跑到实时帧率很吃力Transformer 检测器检测精度和泛化能力都不错可一旦要部署到瑞芯微、海思这类边缘芯片上算子兼容性问题会占用大量额外工时。YOLO 系列里我建议从 n 或 s 尺寸起步而不是一上来就用 l 或 x。理由是电梯轿厢场景的目标数量少通常不超过 10 个大模型的参数量优势无法充分发挥反而显著拖慢训练和推理。先用 yolov8n.pt 预训练权重在自建数据上跑通完整流程记录 baseline再换 s 或 m 对比提升幅度。如果 AP 提升不足 2 个点就坚持用轻量模型把算力预算留给多路并行。Ultralytics 环境配置在网上的资料很全非常适合 0 基础纯小白照着做训练脚本和权重加载接口统一后面的调试成本最低。另外需要强调电梯内人车识别数据集不等同于通用行人检测数据集。CrowdHuman 这类密集行人数据集对轿厢场景只能做预训练补充因为它的拍摄视角是平视或俯视光照条件相对稳定而电梯内目标尺度小、强背光、金属反射多模型的输入分辨率和增强策略必须单独调。接下来直接讲怎么把一套数据用 YOLO 跑通训练。3. 用 YOLO 在电梯人车数据集上跑通训练目录、YAML 与最小命令3.1 数据集目录怎么摆默认路径与划分比例Ultralytics YOLO 对数据集目录有固定约定。按照默认规则组织训练命令可以少写不少参数也不容易搞乱路径。常见的目录结构如下elevator_hv/ ├── train/ │ ├── images/ # 训练图像 jpg/png │ └── labels/ # 与图像同名的 txt 标注 ├── valid/ │ ├── images/ │ └── labels/ └── test/ ├── images/ └── labels/images 和 labels 下的文件名必须一一对应比如000123.jpg对应000123.txt。只要一张图缺了 txtYOLO 训练时会把它当负样本跳过目标漏学。很多人拿到数据集后直接开训结果发现某个类别 AP 特别低最后排查下来是几百张图没有对应标签文件。我习惯在训练前做一次全量校验脚本不长但很管用import os from collections import Counter img_dir elevator_hv/train/images label_dir elevator_hv/train/labels missing_labels 0 cls_counter Counter() for img_name in os.listdir(img_dir): stem os.path.splitext(img_name)[0] label_path os.path.join(label_dir, stem .txt) if not os.path.exists(label_path): missing_labels 1 else: with open(label_path) as f: for line in f: parts line.strip().split() if len(parts) 5: cls_counter[int(parts[0])] 1 print(missing labels:, missing_labels) print(class distribution:, cls_counter)这段脚本做了两件事统计缺少标签的图像数量同时统计每个类别出现的次数。类别分布会直接告诉你数据集是否失衡比如 person 出现 5000 次而 e-bike 只有 300 次后续就需要做重采样或加权重处理而不是盲目加大 epoch。参数里的 stem 是去掉扩展名的文件名用于拼接标签路径counter 统计结果可以辅助判断类别取舍。3.2 写 data.yaml类别 id、路径与校验训练前必须写一个 YAML 配置文件告诉 YOLO 数据在哪里、类别有哪些。对于电梯内人车识别数据集一个能直接用的 data.yaml 如下path: E:/datasets/elevator_hv train: train/images val: valid/images test: test/images names: 0: person 1: e-bike 2: wheelchair 3: strollerpath 是数据集根目录的绝对路径如果换机器跑改这一行就够了。train、val、test 相对路径指向 images 目录而不是 labels 目录YOLO 会按相同文件名自动寻找 labels。names 的索引顺序必须和 txt 里的类别 id 完全一致这是最常见的翻车点很多人把 names 从 1 开始写模型训练出来的每个预测类别整体错位一位推理时把 e-bike 显示成 person看起来精度还行实际完全不能用。写完 YAML 后先做一次快速验证不要去启动长训练。用少量图片确认标签和图像能够正确关联。from ultralytics import YOLO model YOLO(yolov8n.pt) results model.val(dataelevator_hv.yaml, imgsz640, splitval)这条命令会把验证集跑一遍推理并在终端输出各指标。更直观的方法是加载一张图像画框检查确认边界框贴合目标。前者验证数据通路后者验证标签质量。两步做完再进入训练流程可以省掉后面大量的返工时间。3.3 训练最小命令与参数含义训练一个电梯人车检测模型的最小命令很简单但参数含义必须弄清楚否则出了问题不知道改哪里。推荐用预训练权重启动而不是从头训练因为电梯场景的数据量通常只有几千帧从头训练难以收敛。典型命令如下yolo train modelyolov8n.pt dataelevator_hv.yaml epochs150 imgsz960 batch16 device0model 参数填 .pt 文件路径时加载预训练权重填 .yaml 文件路径时则从零初始化网络结构。data 指向刚才写的 YAML。epochs 建议设为 120 到 150 之间因为样本量小epoch 太少会欠拟合但超过 200 之后容易过拟合验证 Loss 反而上升。imgsz 是训练输入尺寸960 是电梯场景的常用选择这个值直接影响小目标检测能力后面单独展开。batch 取决于显存8GB 显存跑 imgsz 640 时 batch 可以到 32跑到 960 时建议降到 16。device0 表示使用第一张 GPU没有 GPU 就改成 cpu但训练速度会慢到无法接受。如果想要一点容错能力可以加一个参数启动缓存和日志落盘yolo train modelyolov8n.pt dataelevator_hv.yaml epochs150 imgsz960 batch16 device0 cacheramcacheram 会把图像一次性载入内存减少训练时的磁盘 IO。数据集几千帧时内存压力不大训练速度提升明显。如果中途崩溃可以用 resume 续训yolo train resumeTrue modelruns/detect/train/weights/last.ptcontinuation 的逻辑是加载 last.pt 接续训练epoch、学习率等状态都会恢复不需要重新调整参数。第一次跑通后不要急着调增强策略先让模型完成一轮完整训练把 result 文件里的指标曲线作为后续对比基线。4. 把精度压上去电梯狭小空间的三个必调参数与增强策略4.1 imgsz 与 mosaic对“轿厢小目标”的取舍电梯内人车识别数据集最典型的问题是目标小、数量少、占画面比例低。轿厢内一个人可能只占画面高度的十分之一如果训练输入尺寸只有 640x640人脸的纹理和电动车轮毂细节经过下采样后已经模糊模型能学到的有效特征很少。提升 imgsz 是性价比最高的调整方式把输入从 640 提高到 960通常能带来 2 个点以上的 mAP50-95 变化提高到 1280 效果更好但训练时长和显存占用都非线性上涨。下表是我在实际项目里常用的参考值输入尺寸相对训练时间小目标召回适用场景6401x偏低快速跑通流程、算力紧张960约 1.7x中等偏上通用电梯监控场景推荐1280约 3x明显提升目标极小或需要远距离检测另一种可选技巧是动态分辨率训练前 100 个 epoch 用 640最后 20 个 epoch 把 imgsz 调整到 960 或 1280让模型在收敛后期对准真实输入尺度。Ultralytics 支持训练中途修改 imgsz 参数不需要改网络结构。mosaic 增强在电梯场景要谨慎处理。mosaic 会把四张图拼成一张增强模型鲁棒性但对小目标极不友好拼图后目标尺寸变为原来的四分之一电动车和人的细节进一步损失而且目标被拼图边界切断的情况经常出现。我一般设置 mosaic0.0 完全关闭或者在前一半 epoch 开启、后一半关闭。关闭后精度可能会有 0.5 到 1 个点的降幅但漏检率会显著下降对真实业务场景更有利。4.2 类别不平衡与重采样电梯画面里“人”的出现频率远高于“电动车”这是类不平衡问题的根源。如果数据集里人员样本 5000 个、电动车只有 400 个模型训练时会对 person 类别的梯度贡献明显更大导致电动车召回率偏低。这正好是一个常见的落地痛点视频里最需要告警的恰恰是电动车漏检一次就会让整个方案失去意义。解决思路首先是数据层面重采样。对样本少的类别做复制或多尺度增强。我在实践中常用简单直接的方法把包含 e-bike 的图像在训练集中额外复制一份并把原始图像的左右翻转版本也加进去。这样既不污染标签又能把该类别在训练中的抽中概率提上去。注意翻转增强会让车身文字、车灯方向反向如果数据集里的车辆本身存在明显的左舵右舵不对称特征翻转后的样本反而会增加学习难度要结合实际情况判断。训练参数层面可以用损失权重去调整。Ultralytics 的标准命令里可以通过设置分类损失的权重 cls 来放大或缩小类别分支的贡献。但更推荐在自定义训练脚本里针对类别做加权from ultralytics import YOLO model YOLO(yolov8n.pt) class_weights {0: 1.0, 1: 3.0, 2: 2.5, 3: 2.5} model.train( dataelevator_hv.yaml, epochs150, imgsz960, cls1.2, )这里的 class_weights 只是一个自定义层级的数据结构实际训练中要结合类别频率去设定。比如 person 占 5000 次、e-bike 占 400 次那么 e-bike 的权重设置在 2.5 到 3.0 之间比较合理。权重过大会让模型对电动车过于敏感背景里的垃圾桶或维修工具被误检为车。比较稳妥的做法是先做数据重采样再观察验证集 per-class AP如果 e-bike AP 仍然偏低再叠加损失权重。4.3 强背光与夜间低照度增强的取舍电梯轿厢的环境光极不友好。白天开门瞬间走廊高亮光线直射摄像头逆光下人脸完全看不清夜间轿厢内只有顶部灯箱照明色温偏暖摄像头自动增益后画面出现大量噪点。这些光照变化无法靠一个固定预处理函数消除只能通过训练增强让模型适应。我建议在训练配置里显式调整 HSV 增强参数。Ultralytics 的默认 hyp 配置在自然光数据集上效果不错但电梯场景需要更针对性修改hsv_h: 0.01 hsv_s: 0.5 hsv_v: 0.35hsv_h 色相扰动保持很小因为轿厢内灯光色温基本恒定把色相拉大幅度变化会制造出不符合真实环境的颜色让模型学到错误映射。hsv_s 饱和度和 hsv_v 亮度扰动可以适当加大模拟开关门瞬间和应急灯切换时的照度变化。此外不要用 mixup 和 cutout 这类拼凑型增强在电梯近景里它们容易把人或车的轮廓切开导致语义破坏。夜间红外模式要多加小心。很多电梯摄像头在低照度时会自动切换到红外黑白模式画面里没有颜色信息。如果训练数据里包含 RGB 图像和红外图像模型必须学会兼容两种完全不同的输入分布。我见过一个项目把红外和 RGB 混合训练反而导致两种模式下的精度同时下降。更稳的做法是分别训练两个模型或者把红外图像统一转换成灰度图后再参与训练让网络把色彩通道当作冗余信息而不是依赖特征。4.4 验证与回归别只盯着 mAP调参过程中验证标准决定了你会朝哪个方向优化。电梯场景对漏检的容忍度极低但对定位框的像素级精度要求并没有 VOC 或 COCO 那么苛刻因为下游业务只需要判断“轿厢内有没有电动车”不需要精确到轮廓每个像素。建议把验证指标拆成三档指标关注点mAP50判断边界框是否大致命中目标位置per-class AP单独看 e-bike 的召回发现类别失衡片段级漏检率按视频时间窗统计“出现但完全没检到”的帧数跑验证集时用 best.pt 权重不要用 last.pt。best.pt 是按验证集指标选出的最优权重last.pt 只是训练到最后一轮的权重两者差距在电梯场景里通常有 1 到 3 个 AP 点。验证命令里把 imgsz 设置成和部署推理时一致因为输入尺寸不同会让指标无法对齐yolo val modelruns/detect/train/weights/best.pt dataelevator_hv.yaml imgsz9605. 训练自验与常见问题排查Loss 不降、漏检、余光检测错乱5.1 Loss 不降或送负先查标签和缓存现象训练到第 20 个 epochtrain_loss 从 1.8 降到 1.2 之后基本不降验证集 mAP 也没有明显提升甚至出现训练 Loss 下降但验证 Loss 上升的过拟合征兆。原因大多数情况是标签质量有问题。电梯人车数据集中典型病例是电动车目标被漏标无标签的电动车图像在网络看来属于背景模型学到的结果是“把电动车从人的特征里分离出去”这件事越来越难。另一种情况是 Ultralytics 在训练时会缓存标签文件如果之前跑过一次训练后修改了类别数量或标签内容旧缓存的 .cache 文件没有过期导致模型读到的数据不是最新的。解决先删除数据集目录下所有*.cache文件再重新启动训练。标签质量校验建议专门写一个可视化脚本随机抽取 30 张训练图把标注框直接画出来人工检查。这一步不花多少时间但能避免整个训练批次白费。删除缓存后如果 Loss 曲线恢复正常说明问题出在数据链路而不是网络结构。5.2 漏检严重别急着换模型先换输入尺寸与训练策略现象把训练完的模型部署到实际电梯监控上发现人员基本能识别但电动车经常在画面里出现后完全没框出来尤其是目标距离远或车体被人体部分遮挡时。原因漏检多数情况不是模型容量不足而是输入分辨率和阈值不匹配。电梯内电动车的视觉特征集中在车体的几何轮廓在 640 输入尺寸下这些特征经过卷积下采样后丢失得所剩无几。另一个原因是置信度阈值设得过高模型对小目标的置信度天然偏低目标本身检出来了但在后处理时被阈值过滤掉。解决先把推理 imgsz 调到 960 以上再降低置信度阈值测试用 0.2 到 0.25 对比上一版结果。如果只是少量小目标漏检换大模型不如换大输入。这一步做完后再考虑组合使用 TTA 或切片推理但电梯场景目标遮挡多切片推理很容易把同一目标切成两个框对后续追踪造成巨大麻烦能不用就不用。5.3 白墙/镜面反光出现重复框与误检现象电梯轿厢的镜面不锈钢门板反光严重时模型对同一个人输出两到三个框其中一个落在镜面虚像上更恶劣的情况是反光纹理被误检成电动车。原因训练阶段如果标注了反光虚像模型会把虚像里的轮廓当作真实目标特征。如果没标注模型又可能因为背景纹理和电动车车体边缘相似而误判。这类问题本质上是对比度缺陷金属表面的拉丝纹理与车轮辐条在灰度图中的边缘非常接近。解决训练集里把反光虚像区域统一标注为 ignore 类别不让它们参与损失计算。推理阶段可以对固定机位做 ROI 预处理把轿厢门缝、天花板转角等不可能出现目标的区域直接裁掉真实业务里噪声来源集中且位置固定ROI 抠图能立竿见影。更成熟的方案是接上时序追踪真实目标的框在连续多帧中稳定出现反光虚像的框位置和形状不断跳变追踪平滑后自然被过滤掉。5.4 显存溢出 / 训练中断现象训练跑到一半报 CUDA out of memory或者服务器停电、SSH 断连导致训练进程被杀。8GB 显存跑 imgsz 1280 时最容易出现。原因显存溢出通常是 batch 和 imgsz 的组合超过显存上限。电梯数据集虽然帧数不多但一旦输入尺寸拉大每张图的显存占用成倍增长尤其最后阶段 Transformer 风格的注意力模块更吃显存。训练中断的深层原因往往不是代码错误而是训练机环境和稳定性问题。解决用 Ultralytics 的自动批量搜索功能把 batch 参数设为 -1让它按显存自动推到最大可用值。如果自动搜索得到的 batch 只有 4就不要强行用 16训练时间长一点总比跑到一半断掉好。断点续训用 resumeTrue 加载 last.pt这是 YOLO 提供的后悔药机制不需要重新跑前面的 epoch。生产环境里训练建议用 nohup 后台运行并输出到 log 文件防止 SSH 断开导致任务终止配了 UPS 的机器更踏实毕竟训练中断最伤的是时间成本。6. 从单帧检测到电梯端侧部署验证方法、追踪去重与一点经验6.1 在测试视频上做序列级验证模型训练完成后静态指标只能说明“这个模型在验证集上表现如何”不能说明它在真实电梯里能不能用。我会专门准备一段 5 分钟原始监控视频包含完整流程门打开、人推车进入、关门、电梯启动。用保存的 best.pt 做推理yolo predict modelruns/detect/train/weights/best.pt sourceelevator_test.mp4 imgsz960 conf0.25 saveTrue查看输出视频时重点关注两件事第一电动车从画面边缘出现到首次被稳定框住的帧延迟超过 10 帧就说明模型对运动小目标的响应太慢第二轿厢门开关瞬间画面亮度剧烈变化后模型是否出现整帧丢失检测的现象。这两类问题在静态图片验证里完全看不出来但直接决定了业主是否会投诉这套系统。6.2 接上追踪与 Re-ID别把同一辆车框成三次电梯场景是连续视频而不是单帧图片部署端需要考虑目标去重。一台电动车在轿厢内停留 30 秒如果每帧都产生一个告警后端平台会被刷屏。常见做法是用 ByteTrack 做多目标追踪对每个目标分配稳定 ID然后统计同一 ID 的连续出现时长达到阈值才触发告警。from ultralytics import YOLO model YOLO(runs/detect/train/weights/best.pt) tracks {} for result in model.track(sourceelevator_test.mp4, persistTrue, conf0.25, imgsz960): if result.boxes is None or result.boxes.id is None: continue ids result.boxes.id.cpu().tolist() for tid in ids: tracks[tid] tracks.get(tid, 0) 1 if max(tracks.values(), default0) 15: print(电动自行车乘梯持续超过15帧触发告警) breakpersistTrue 的作用是让追踪器在视频流中持续保留同一目标的 ID而不是每帧重新分配。如果去掉这个参数上一帧和下一帧的同一个目标会被当成两个新目标去重逻辑彻底失效。这个 demo 里的 15 帧按 30fps 换算就是 0.5 秒实际部署时建议把持续时间阈值调到 2 秒以上避免门口有人推车临时停靠也误报。6.3 最后一个经验先定误报预算再谈 mAP把模型精度从 mAP 0.85 提到 0.87远不如想清楚误报和漏报之间怎么取舍。电梯项目里物业最关心的是漏报漏一次电动车进电梯就约等于系统失效但误报也不能太多一天弹出几十条虚假告警保安很快就会把系统关掉。我在一次部署中曾为了提升召回把置信度阈值降到 0.15结果镜面反光和维修手推车带来的误报让后台近乎瘫痪。最终把电动车的置信度单独调整到 0.35同时加入轿厢内 ROI 限制告诉系统只有目标进入轿厢地板范围才告警。这个限制代码改动量很小误报率却降了一个数量级。每一条检测参数都应该先问业务能接受多少误报再去调整模型指标。希望这个习惯能帮到你毕竟算法做到最后难点从来不在那张 loss 曲线里。本文还有配套的精品资源点击获取