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

电梯内人车识别数据集:YOLO训练实战与避坑指南

电梯内人车识别数据集:YOLO训练实战与避坑指南 ★ FEATURED ARTICLE
简介电梯内人车识别数据集是面向目标检测任务的垂直场景训练集素材拍摄于真实电梯监控环境涵盖不同时段光照与视角变化对画面中出现的人、摩托车、自行车等目标进行了精细标注覆盖日常乘梯与人车混行等多种情况。资源包文件总量为两千个主体为文本格式的标签文件保存每个目标的归一化坐标与类别标识另含一个类别配置文件整体体积约一百九十余兆字节方便下载与部署。其标签格式可直接用于常见的目标检测算法如YOLO系列与Faster RCNN、SSD等免去格式转换步骤。开发者无需自行采集视频和逐帧标注能够节省大量预处理时间适合进行电梯人车识别、轿厢客流统计、安防预警等方向的研究与验证。目前已有201人学习下载对于需要高质量垂直场景数据来训练模型、开展实验的深度学习和计算机视觉从业者是一个很实用的资源。1. 电梯内人车识别数据集比通用目标检测难在哪电梯内做目标检测难点从来不在“识别”而在“尺度”和“遮挡”。轿厢一般就 2 到 3 平方米人贴着人站儿童和成年人高度差可能超过一倍婴儿车、轮椅、宠物又穿插其中再加上金属壁面反光、低照度和广角镜头畸变通用目标检测模型拿过来直接跑漏检率和误检率往往高得让人怀疑人生。这也是电梯内人车识别数据集存在的意义它把训练样本限定在轿厢场景让模型学到的是“电梯里的人车长什么样”而不是泛泛的“人”和“车”。如果你正在做电梯智慧监管、电动车禁入、困人检测或轿厢清洁度评估这个数据集就是模型能不能落地的地基。下面从数据构成、标注格式、训练适配、参数选择和踩坑五个方面展开全程按可复现的标准来写。2. 电梯内人车识别数据集的构成三类样本与标注格式2.1 数据集里到底有什么真实轿厢样本的典型分布以我接触过的电梯轿厢数据为例一个合格的数据集至少包含三类场景样本空轿厢、载人轿厢、载人非机动车轿厢。空轿厢样本用于抑制误检——很多模型在没人时把壁面反光、扶手阴影识别成人载人轿厢是主样本占 60% 到 70%人车混合样本是训练“车”类别的关键占 20% 到 30%少了这部分的模型在电动车进入时会直接漏框。样本来源通常有两种一是真实电梯监控录像切帧覆盖不同楼层停靠、不同时段光照、不同摄像头安装高度二是在实验室搭场景补拍主要补极端角度和遮挡样本。分辨率一般不低于 1280×720因为轿厢内目标偏小低分辨率下人头只有十几个像素标注和识别都无从谈起。帧率方面不需要连续视频流训练集建议按 3 到 5 秒间隔抽帧避免相邻帧高度相似导致数据冗余。另一个容易被忽略的是轿厢门状态。门开着时外界光线涌入模型容易把走廊里的人也算进来门关闭后的均匀光照才是典型场景。高质量数据集会单独标记门状态或确保样本分布均衡你在二次筛选时要注意这一点。2.2 标注格式从 COCO 到 YOLO 的实际转换这个数据集的标注格式常见有两种COCO JSON 和 PASCAL VOC XML也有直接提供 YOLO txt 的。拿到原始数据后第一步要确认类别编号典型映射如下类别ID 0person人 类别ID 1bicycle自行车/电动自行车 类别ID 2motorbike摩托车如果你的原始标注只有 person 和 vehicle 两个类别我建议拆成 person、bicycle、motorbike 三分类而不是人车二分类。原因有两个一是电梯内不允许进入的通常是电动自行车和摩托车而自行车管理政策不同二分类会让模型把自行车也当非法目标而误报二是三分类的框形差异明显模型收敛更快。如果拿到的是 COCO 格式要转成 YOLO 训练格式转换脚本如下# COCO JSON 转 YOLO txt 格式适配电梯轿厢小目标场景 import json import os from pathlib import Path def coco_to_yolo(coco_json_path, output_dir, img_width, img_height): coco_json_path: COCO标注文件路径 output_dir: 输出目录每个图片对应一个同名txt img_width/img_height: 图片实际宽高用于归一化坐标 with open(coco_json_path, r, encodingutf-8) as f: coco json.load(f) # 建立类别名到ID的映射person0, bicycle1, motorbike2 cat_id_map {} for cat in coco[categories]: name cat[name].lower() if name in [person, bicycle, motorbike, motorcycle]: cat_id_map[cat[id]] { person: 0, bicycle: 1, motorbike: 2, motorcycle: 2 }[name] img_id_map {img[id]: img for img in coco[images]} # 按图片ID聚合所有标注 anns_by_img {} for ann in coco[annotations]: if ann[category_id] not in cat_id_map or ann.get(iscrowd, 0) 1: continue # 跳过crowd标注电梯场景拥挤时crowd框无法用于训练 anns_by_img.setdefault(ann[image_id], []).append(ann) os.makedirs(output_dir, exist_okTrue) for img_id, anns in anns_by_img.items(): img_info img_id_map[img_id] yolo_lines [] for ann in anns: # COCO的bbox是[x, y, width, height]需要转成YOLO的[x_center, y_center, w, h]归一化格式 x, y, w, h ann[bbox] if w 0 or h 0: continue x_center (x w / 2) / img_width y_center (y h / 2) / img_height w_norm w / img_width h_norm h / img_height # 防止归一化后坐标越界 x_center min(max(x_center, 0.0), 1.0) y_center min(max(y_center, 0.0), 1.0) class_id cat_id_map[ann[category_id]] yolo_lines.append(f{class_id} {x_center:.6f} {y_center:.6f} {w_norm:.6f} {h_norm:.6f}) if yolo_lines: stem Path(img_info[file_name]).stem with open(Path(output_dir) / f{stem}.txt, w, encodingutf-8) as f: f.write(\n.join(yolo_lines))转换时有两个细节要特别小心。第一是类别映射表如果原数据集里摩托车叫 motorcycle 而你的业务文案叫 motorbike必须做显式合并否则模型会把它当未知类别。第二是跳过 iscrowd 标注项电梯里人贴人时标注员经常标 crowd这类框包含多个目标直接用于训练会误导模型学到一个框里多个目标重叠的形状。跳过之后如果发现样本量下降超过 15%说明原始数据集中拥挤场景比例高这是电梯场景的正常现象不需要补回 crowd 框但要额外补充单人场景样本来平衡。3. 训练前必须做的数据体检标注质量决定精度上限3.1 用脚本筛出三类致命标注错误数据集的标注质量直接决定模型上限这不只是口号。电梯场景里最常出现三类标注错误类别标签与人不对应——把推婴儿车的家长标成了自行车把轮椅标成 motorbike遮挡目标漏标——前排人挡住了后排人标注员只标了可见的那一个极端长宽比框——轿厢广角镜头下靠近镜头的人框高宽比能达到 4:1 甚至 5:1这类框在训练时会被降采样到统一尺寸目标特征被拉伸变形。写一个快速体检脚本检查每张图的框数分布和尺寸分布# 数据体检脚本统计YOLO格式标注的框数量与尺寸特征 import os from pathlib import Path from collections import Counter def inspect_yolo_labels(label_dir): label_dir: YOLO txt标注目录 统计每张图的框数、类别分布、目标尺寸分布 empty_imgs 0 total_boxes 0 cls_counter Counter() size_counter Counter() # small: 32x32, medium: 32~96, large: 96 for txt_path in Path(label_dir).glob(*.txt): lines txt_path.read_text().strip().splitlines() if not lines: empty_imgs 1 continue for line in lines: parts line.split() cls int(parts[0]) w float(parts[3]) h float(parts[4]) cls_counter[cls] 1 total_boxes 1 # 按归一化宽高反推像素尺寸假设图宽640 pixel_w w * 640 pixel_h h * 640 if pixel_w 32 and pixel_h 32: size_counter[small] 1 elif pixel_w 96 or pixel_h 96: size_counter[medium] 1 else: size_counter[large] 1 print(f总标注框数: {total_boxes}) print(f空图数量: {empty_imgs}) print(f类别分布: {dict(cls_counter)}) print(f尺寸分布: {dict(size_counter)}) # 框数异常检测单图超过15个框往往是漏标或错误聚合 too_many [] for txt_path in Path(label_dir).glob(*.txt): count len(txt_path.read_text().strip().splitlines()) if count 15: too_many.append(txt_path.stem) print(f单图框数15的图片: {len(too_many)} 张需人工复查)跑完脚本后重点看两个数类别比例和小目标占比。如果三分类的比例偏离 6:2:2 太远比如 motorbike 只占 5%训练时即使加了类别权重模型对摩托车的召回率也会偏低。小目标占比超过 50% 时需要在下游训练中开启高分辨率输入或使用 P2 检测层——关于这一点后面训练章节会细说。3.2 划分训练验证测试集按电梯单元隔离而非按帧随机切最常见的翻车操作是用 random split 切分数据集同一台电梯、不同帧的图片同时出现在训练集和验证集里模型见过场景后验证集指标虚高上线新电梯时精度骤降。正确做法是按“电梯单元”或“楼栋”划分所有来自同一路摄像头的帧只能进入同一个子集。手动划分容易出错建议用脚本按目录名分组完成# 按电梯单元划分数据集train/val/test 按目录隔离 # 目录结构要求data/raw/camera_01/xxx.jpg, data/raw/camera_02/xxx.jpg # 运行后生成 data/images/{train,val,test} 和 data/labels/{train,val,test} python split_by_camera.py \ --source data/raw \ --output data \ --train_ratio 0.8 \ --val_ratio 0.1 \ --test_ratio 0.1脚本内部逻辑是按摄像头目录名排序后按比例分配而不是每张图独立随机分配。测试集的比例虽然只有 10%但一定要保证测试集中的摄像头完全不参与训练。如果摄像头数量太少比如只有 3 台电梯的数据按摄像头隔离后模型在测试集上的表现会波动剧烈这时建议改用 k-fold 交叉验证每轮换一台电梯当测试集取五次评估的均值作为最终性能。划分完成后还要做一个检查把训练集中“人车”同框的图片比例打印出来如果低于 15%模型大概率只学会了在无人时检测车而有人和车同时出现时会顾此失彼。这种情况的补救方法是去原始帧里专门抽人推车进门、人在轿厢内扶车等画面比改参数有用得多。4. 用 YOLO 训练电梯内人车识别模型选型与三个必调参数4.1 YOLOv8 还是 YOLOv11电梯轿厢场景的选型逻辑当前目标检测社区最活跃的框架是 Ultralytics 的 YOLO 系列YOLOv8 成熟稳定、中文教程多、遇到问题好搜YOLOv11 在骨干网络上做了改进小目标表现理论上更好但环境配置和算子兼容性还需要自己踩坑。对电梯人车这种类别少、目标尺寸极端、算力常受限的场景我的建议是先用 YOLOv8n 或 YOLOv8s 快速跑通基线验证数据质量指标合格后如果还有余量再换 YOLOv11 提点。环境配置上最省事的路径是# 创建独立环境避免和已有项目冲突 conda create -n elevator_yolo python3.10 -y conda activate elevator_yolo # 安装CPU版或GPU版torch后再装ultralytics pip install ultralytics # 验证安装是否成功 yolo predict modelyolov8n.pt sourcehttps://ultralytics.com/images/bus.jpgGPU 环境建议先确认 CUDA 版本再选择 torch 版本不要在 conda 里装默认的最新 torch很容易出现 cuDNN 不匹配导致训练时直接报“CUDA error: device-side assert triggered”。这个报错的坑在避坑章节会详细展开。4.2 训练命令与三个必调参数imgsz、batch、mosaic数据准备好后训练命令如下yolo train \ modelyolov8n.pt \ dataelevator.yaml \ epochs200 \ imgsz1280 \ batch16 \ patience30 \ optimizerAdamW \ lr00.001 \ mosaic0.5 \ close_mosaic10这里的 elevator.yaml 内容如下# elevator.yaml 训练数据配置 train: data/images/train val: data/images/val test: data/images/test nc: 3 names: [person, bicycle, motorbike]三个必调参数各自的理由imgsz 从默认 640 上调到 1280。电梯中小目标占比高640 分辨率下人脸和车轮只有十几个像素特征图里几乎没有响应区域。YOLOv8 输入分辨率提升到 1280 后小目标特征点数大约增加到原来的 4 倍mAP50 通常能提高 5 到 10 个点。代价是显存占用翻倍如果你的显卡只有 8GBbatch 要降到 8或者使用 imgsz960 作折中。batch 不要图大。轿厢内样本相似度高batch 过大容易让模型过拟合到某一台电梯的特定光照和壁面纹理上。8GB 显存配 1280 分辨率时 batch 设 8 到 16 比较合理。如果训练时显存不足优先降 batch不要降分辨率——降分辨率会直接毁掉小目标检测能力。mosaic 是 YOLO 系列最有效的增强手段之一把四张图拼成一张训练显著提升模型对遮挡和小目标的鲁棒性。但对电梯场景mosaic 比例不要拉满因为四张拼接图里可能出现两个电梯轿厢的画面拼接模型学到的是“不同光照的拼缝”而不是真实轿厢内目标关系。我一般设 0.5 到 0.7同时在最后 10 个 epoch 关闭 mosaicclose_mosaic10让模型在接近真实分布的增强下微调避免 mosaic 造成的分布偏移影响最终精度。AdamW 和 SGD 的选择上小数据集用 SGD 更稳大数据集 AdamW 收敛更快。4000 张以下的电梯数据集用 SGD 配 lr00.01 是常见做法超过 8000 张或样本多样性足够时再换 AdamW 0.001 的起始学习率。4.3 训练过程中的玄学现象与判断标准训练时看 loss 曲线电梯数据集出现过拟合的时间点通常比通用数据集更早——因为场景单一模型在 60 到 80 个 epoch 时 val loss 就开始反弹。此时不必急着改参数先看 patience 是否触发早停如果 30 个 epoch 内 val loss 没有改善就停了说明模型容量可能过剩换更小的 yolov8n 而不是增加正则化。真正需要人工介入的情况是 mAP50 在 0.5 以下徘徊。这个时候不要盲目调训练参数先回数据层面做两件事验证集里随机抽 20 张图用训练出的模型跑一次推理把漏检和误检的图片单独归到一个文件夹里人工看。你会发现大概率是三种情况小目标整体没学到、人和车同时出现时只认出一个、暗光下大面积漏检。对症下药比调优参数直接得多小目标整图漏检imgsz 改为 1280确认数据增强里没有 random_perspective 把目标缩得太小人和车同时出现漏检一个检查训练集中同框图片数量补充人车同框数据暗光漏检在 hsv_h、hsv_s、hsv_v 增强参数里把亮度扰动范围加大或者用图像增强预处理把暗帧提亮后再喂模型表格总结如下便于对照排查现象指标特征首选调整小目标漏检多mAP50小目标类别偏低imgsz1280人车同框漏检一个类别AP差异大补充同框样本训练后期val loss反弹epoch80后上升close_mosaic10验证集指标虚高换新电梯骤降按摄像头隔离切分5. 避坑章节电梯内人车识别训练踩坑实录5.1 现象CUDA error: device-side assert triggered训练到一半程序崩溃命令行报“CUDA error: device-side assert triggered”后面还带着一堆看不懂的调用栈。这个报错绝大多数情况下跟显存无关而是标注框越界或类别 ID 超出 nc 设置。原因在于 YOLO 的损失计算里目标框坐标无论归一化还是绝对值一旦超过图片尺寸或者在数据增强过程中被拉伸到图外CUDA 核函数里的 assert 就会触发。电梯数据集的原始标注如果是由不同标注员分批完成的有人习惯用像素坐标输出、有人用归一化坐标输出混合使用时就会出现极少数框的中心点在图像外。解决方式分两步。第一步打开数据集 YAML 文件检查 nc 和 names 是否与实际标注一致第二步跑一次数据集检查yolo detect train dataelevator.yaml modelyolov8n.pt epochs1如果首个 epoch 就崩用脚本筛出越界框import os from pathlib import Path def filter_invalid_labels(label_dir): corrupted [] for txt in Path(label_dir).glob(*.txt): for line in txt.read_text().strip().splitlines(): parts line.split() cls int(parts[0]) x_center, y_center, w, h map(float, parts[1:]) # 越界判断中心点必须在0~1内宽高必须为正且不超过1 if not (0 x_center 1 and 0 y_center 1 and 0 w 1 and 0 h 1): corrupted.append((txt.stem, line)) break return corrupted把筛出来的异常行打印出来看多数是某个标注文件里混入了一行格式完全不同的数据删掉或修正后即可复训。5.2 现象电动车进入电梯时经常漏检但空车时检测正常这是最常见的业务投诉电梯门口的电动车监管功能上线后人工复核发现漏检率高达 20% 到 30%而空车在轿厢内的检测效果却不错。原因有两个层面。数据层面训练集中人车同框样本占比过低模型把“人推着车”当作一个整体而不是两个独立目标车的大部分区域被人遮挡后特征响应被人的类别压过。模型层面YOLO 的 NMS 后处理在遇到高重叠框时会保留得分较高的一个人的分类置信度通常高于车于是车的框被抑制掉。解决方式要根据业务目标选择。如果任务是“禁止电动自行车入梯”那么人的框和车的框重叠时应该保留车框可以在训练中提高 bicycle 和 motorbike 类别的 loss 权重# elevator.yaml 中加入类别权重 class_weights: [0.8, 1.0, 1.0]另一种更长效的方式是在后处理阶段对重叠框做逻辑判断车框的中心点落在一个 high-confidence 的人框内部且面积比例大于 60% 时不直接抑制而是单独保留并标记。这个逻辑用 Ultralytics 的 post-process 回调可以实现但要注意别过度修改源码升级框架版本时会丢失改动。5.3 现象门开着时误检率飙升走廊行人被识别为轿厢内目标模型训练时没有区分门状态门开时摄像头视野延伸到走廊模型把走廊里的人全部框出来导致误报率居高不下。原因不是模型没学好“轿厢内”的语义而是数据集里门开样本太少模型没有见过“轿厢视野延伸”的真实分布。解决的方向是给数据打状态标签或做场景分类。常见做法是在训练数据中把门开样本单独挑出来如果业务上不需要检测门外区域就在标注阶段直接把延伸到轿厢外的目标整体裁掉如果业务希望保留走廊检测能力则需要把门开样本占比提升到 20% 以上并单独设一个 corridor 目标的业务规则。要特别注意不要在推理阶段只通过检测器的置信度阈值来过滤门外目标阈值调高时门外误检被压低轿厢内的小目标同时也会被压制这是一种典型的“调参掩盖问题”。5.4 现象同一份数据换一台新电梯精度大幅下降模型在原数据集测试集上 mAP50 能达到 0.85装上另一栋楼的电梯后 mAP 掉到 0.6感觉像是模型没训练好。原因在于不同电梯轿厢的内饰差异非常大——镜面不锈钢、拉丝金属、白色铝板、木质装饰光照条件也完全不同有的还有广告屏额外光源。模型的泛化能力被训练集的单一视觉风格锁住了。解决方式是在数据层面做多样性增强。除了常规的 hsv 扰动还要针对电梯材质做特殊增强镜面不锈钢的场景会引入高光反射模型容易把反射影像当成真实目标建议用 random_erasing 配合镜面区域抠图增强。另一个可行做法是训练时加入 style transfer 模拟不同材质的轿厢内壁但工程成本偏高一般项目先用材质分类 数据补充的方式解决按电梯单元收集超过 10 种不同内饰的数据每个单元的样本量不用太大200 到 300 张即可泛化能力提升会很明显。6. 用单层电梯场景做性能验证验证你的模型真的能上线模型在公用测试集上跑出 mAP 后不要急着接生产环境。最后一步我建议做单层场景验证——选取一个全新的、完全没参与训练的电梯单元去现场采集 10 分钟连续视频分帧后用训练好的模型逐帧推理统计人工复核后的 mAP 和误报率。这个方法比任何测试集指标都真实因为现场视频里的光照、运动模糊、摄像头抖动都是训练数据里没有的。具体做法是把视频抽帧 推理 标注合并到一个脚本里连续跑两轮。第一轮不看指标只看失败样本——把所有漏检和误检帧导出到一个文件夹人工逐张分类记录失败原因。第二轮把失败原因按“小目标”“遮挡”“曝光”“反射”四个类别归类看占比最高的那一类再针对性调整。如果反射导致的误检最多就去补充镜面壁样本如果小目标漏检占比最高就要考虑换更高分辨率输入或加 P2 检测头。验证通过后推理部署还有一个容易踩的细节不要把检测器的置信度阈值固定成 0.5。电梯场景里目标的置信度分布与光照强相关电梯门打开到关闭的过程中同一目标置信度可能从 0.7 掉到 0.3。常见做法是运行时按帧自适应阈值轿厢内光照稳定时用 0.5光照剧烈变化时放宽到 0.35 并配合目标跟踪算法。但注意阈值放宽后误检也会增多需要叠加规则连续 3 帧同一位置出现同一类别才触发报警这个规则能滤掉大部分单帧误检。最终评估建议以业务指标为准——误报率和漏报率的业务容忍度而不是盯着 mAP 不放。在某次电梯电动车禁入项目中我一开始把 mAP 从 0.83 优化到 0.91客户反馈却没变化后来发现漏检主要集中在骑手低头看手机、车身被身体大面积遮挡的瞬间这时人的视觉注意力也不在车上。后来我学到的教训是电梯场景的模型优化优先级永远是“小目标不漏”“遮挡不丢”“高置信度不误报”mAP 只是参考手工复核才是真正的验收标准。这个习惯帮我避开了至少三次盲目调参与无效交付希望也能帮到你。本文还有配套的精品资源点击获取
阅读完成 · 觉得有帮助?
咨询建站