☰
电梯内人车识别数据集实战:基于YOLOv8的训练与调参指南
2026/9/30 10:46:21 网站建设 项目流程

简介:这是一份面向目标检测与深度学习开发者的电梯内人车识别数据集,适用于YOLO系列、Faster RCNN、SSD等主流模型训练,可用于电梯安全监控、智慧楼宇、无人配送等场景的算法验证。资源共2000个文件,其中1999个txt标签文件采用YOLO格式记录目标类别与归一化坐标,1个yaml文件指定person、motorcycle、bicycle三个类别及路径配置,可直接接入YOLOv5至YOLOv10等算法框架。压缩包整体约193.33MB,包含97张真实电梯监控场景图片及对应标注,覆盖行人、摩托车、自行车等典型目标,数据规模适中,适合作为模型训练的起点数据集。已有201人浏览学习,说明该资源具备一定参考价值。下载后即可获得已按YOLO与VOC规范整理的标注数据及配套类别配置文件,可大幅减少数据预处理时间,帮助快速开展模型训练、效果验证与算法调优。

1. 电梯内人车识别数据集:为什么这个场景值得单独做一套目标检测数据

电梯内人车识别数据集,听着像是把通用目标检测数据集里的“人”和“车”抽出来重标一遍,实际上完全不是。通用数据集里的车是路面上的汽车,人是街上走来走去的行人,到了电梯里,镜头是从墙角往下拍的广角,人和电动车、轮椅、推车挤在一起,遮挡、反光、形变全占了。拿通用模型直接做电梯目标检测,漏检和误检能把梯控联动的逻辑全带偏。这套数据集的真正价值,是把电梯这个固定视角下的目标尺度、遮挡模式和光照条件固化下来,让模型从第一天起就活在真实场景里。适合做梯控、智慧社区、楼宇安防的工程师,以及想用现成数据快速验证目标检测方案的开发者。

2. 先看懂数据集:标注格式、类别分布和场景覆盖

拿到一套电梯内人车识别数据集,第一件事不是急着训练,而是把它当成待清洗的样本池来审。目标检测数据集的质量直接决定模型上限,电梯这种小场景尤其敏感。我一般会分三步走:先看标注格式,再看类别和场景分布,最后抽样检查边界框。

2.1 电梯场景的数据特性:遮挡、形变和光照

电梯内人车识别的难点不在类别多,而在同一个类别内部形态差异极大。人可能是站着的、蹲下扶电动车的、背对镜头的;车(这里泛指能进电梯的代步工具)可能是电动车、自行车、轮椅、手推车,甚至施工用的平板车。同一个“车”类别,在标注规范不统一的数据集里,经常被标成不同名字,或者把车上的杂物也算进框里。所以使用任何数据集前,先要搞清楚它的类别定义:vehicle包含哪几种,bounding box是标完整车还是标可见部分。这个决定直接决定后面能否迁移到你的业务场景。

另一个特性是视角固定。电梯监控通常是顶角广角,人车目标多数以俯视或斜俯视出现,而且相互遮挡频繁。比如人站在电动车后面,人和车的前半部分重叠,如果标注框只框可见部分,训练时模型学到的是“半个人”,推理时遇到完整的人反而犹豫。因此,标注边界框是基于可见部分还是推测的完整轮廓,这是你拿到数据后必须确认的第一个细节。

光照方面,电梯内是强光、反光、暗光交替。不锈钢镜面反光会把倒影也照出来,夜间红外模式下图像是灰度偏绿的。一套好的数据集应该覆盖这些情况,但很多电梯数据集白天帧占大头。评估时要统计不同亮度、色温下的样本占比,如果全是白天,后续训练就要靠增强补偿,不然模型到了地下室或夜间楼层直接翻车。

2.2 标注格式与目录结构:从XML/JSON到YOLO的转换脚本

最常见的电梯人车识别数据集标注格式是VOC XML或COCO JSON,少数直接给YOLO txt。我建议先用脚本把所有标注统一成YOLO格式,因为后续训练和迁移最省事。下面这个脚本把VOC XML转换成YOLO txt,只保留person和vehicle两个大类,并读取图片尺寸做归一化:

import xml.etree.ElementTree as ET from pathlib import Path classes = {"person": 0, "vehicle": 1} # 按数据集实际类别映射调整 def convert_voc_annotation(xml_file, out_dir): tree = ET.parse(xml_file) root = tree.getroot() img_w = int(root.find("size/width").text) img_h = int(root.find("size/height").text) txt_name = Path(xml_file).stem + ".txt" with open(Path(out_dir) / txt_name, "w") as f: for obj in root.findall("object"): cls_name = obj.find("name").text if cls_name not in classes: continue box = obj.find("bndbox") x1 = int(box.find("xmin").text) y1 = int(box.find("ymin").text) x2 = int(box.find("xmax").text) y2 = int(box.find("ymax").text) # 转为YOLO中心点坐标并归一化 cx = ((x1 + x2) / 2) / img_w cy = ((y1 + y2) / 2) / img_h w = (x2 - x1) / img_w h = (y2 - y1) / img_h f.write(f"{classes[cls_name]} {cx:.6f} {cy:.6f} {w:.6f} {h:.6f}\n") # 用法示例 convert_voc_annotation("annotations/电梯_001.xml", "labels")

逻辑是遍历每个object,读取类别名和bndbox坐标,除以图片宽高得到归一化中心点与宽高。两个关键参数:一是类别映射表必须和数据集的标注名完全一致,常见坑是数据集里把电动车写成“ebike”,脚本只认vehicle,导致大量框被静默丢弃;二是如果原图带旋转框或四边形标注,这个脚本不适用,需要先转外接正框。跑完后每张图生成同名txt,和图片放同一目录。然后写个统计脚本,数一下每个类别的框数量、平均框面积和宽高比,心里就有底了。

2.3 检查数据集质量的三个维度:类别平衡、边界框完整性和重复帧

第一是类别平衡。电梯内人车识别数据集里,人往往占压倒性多数,vehicle类可能只有人的十分之一。直接训练,模型会把注意力全放在人上,车经常漏检。这不只是数据集的问题,而是真实场景里车进电梯本来就是低频事件。处理方法不是简单复制,而是要调整类别权重或做增强,后面章节会细说。

第二是边界框完整性。用LabelImg或X-AnyLabeling打开样本,看框是不是把目标完整包住。有些标注员只框车把手,没框车身,模型就会把“车把手”当特征。遇到这种框,用脚本删掉或人工改,别指望训练自动修正。另一个容易出问题的点是漏标:广角下同一帧可能有三个人一辆车,标注员往往只标了最显眼的。一个廉价但有效的检查方法:拿一个室内场景预训练YOLO模型(比如COCO预训练权重)在全部图上跑推理,把置信度高于0.5但不在任何标注框附近的候选目标抽出来。这个列表不一定都是漏标,但值得扫一遍,尤其是有车出现在图边缘的情况。

第三是重复帧。监控视频抽帧生成的数据集常有连续几十帧几乎一模一样的图,这些训练样本除了增加过拟合风险,几乎没有信息量。用一个感知哈希去重脚本,把相似度超过0.95的帧剔除,再按时间间隔重新采样。很多“数据集跑出来指标虚高,到了现场不行”,就是重复帧造成的信息冗余。处理干净后,再做数据划分,划分要按视频ID而不是按帧随机切,否则前后帧会在train和val之间泄漏,指标虚高更严重。

3. 用该数据集跑通YOLOv8训练:最小可复现流程

数据集审完,就进入最直接的环节:跑通训练。我习惯用YOLOv8,因为它对这类中等规模数据集最友好,训练命令简单,断点续训和导出都顺手。如果你拿到的是VOC或COCO格式,先按第2章转换,再往下走。

3.1 数据划分与YOLO目录组织

YOLO系列希望数据目录长成下面这样:

dataset/ images/train/ images/val/ labels/train/ labels/val/

划分时必须按视频片段维度做。同一个视频里前5秒和后5秒的帧相似度极高,如果随机打散,train和val之间会互相泄漏,验证mAP就没有参考意义。我在处理电梯抽帧数据时,先按文件名里的视频ID归组,再把视频ID按8:2划分,脚本如下:

import os import random import shutil from pathlib import Path src_images = Path("images") src_labels = Path("labels") # 假设文件名格式为 lift01_00012.jpg,取下划线前作为视频ID video_groups = {} for img_path in src_images.glob("*.jpg"): video_id = img_path.stem.split("_")[0] video_groups.setdefault(video_id, []).append(img_path) video_ids = list(video_groups.keys()) random.seed(42) random.shuffle(video_ids) split_point = int(len(video_ids) * 0.8) for split, ids in [ ("train", video_ids[:split_point]), ("val", video_ids[split_point:]), ]: os.makedirs(f"images/{split}", exist_ok=True) os.makedirs(f"labels/{split}", exist_ok=True) for vid in ids: for img_path in video_groups[vid]: label_path = src_labels / (img_path.stem + ".txt") shutil.move(str(img_path), f"images/{split}/") shutil.move(str(label_path), f"labels/{split}/")

这里的核心是按视频ID而不是按单帧划分。随机数种子固定为42,保证每次跑完结果可复现。如果你的文件名不带视频ID,必须先根据时间戳或图像相似度聚成伪视频组,不能直接shuffle。

划分完再统计一下train和val里每个类别的框数量,确保稀有类在验证集里至少有几个样本。如果某个类在val里一个都没有,那验证mAP没有意义,得手动调整split_point或干脆把稀有类视频单独划一个val。

3.2 编写data.yaml并调整模型参数

YOLOv8通过data.yaml把数据集和训练配置连接起来。对电梯人车识别,我一般这样写:

# data.yaml path: /absolute/path/to/dataset # 建议写绝对路径 train: images/train val: images/val names: 0: person 1: vehicle

path字段建议写绝对路径,避免不同工作目录下解析出错。names的索引必须和标注txt里的类别id一致,如果转换脚本里person=0、vehicle=1,这里就不能写成1: person。

第一轮训练不要做任何花哨操作,直接用默认配置跑一个baseline。训练命令:

yolo detect train data=data.yaml \ model=yolov8n.pt \ imgsz=640 \ epochs=100 \ batch=16 \ device=0 \ project=ele_ev \ name=baseline

选择yolov8n而不是s/m/l,是因为电梯场景目标数量少、类别少,小模型往往足够,迭代快。如果算力充足,可以换yolov8s。epochs设100,但YOLOv8默认有早停,实际上大部分电梯数据集在40到60轮已经收敛。batch=16是8GB显存下的保守值,如果显存不够就降batch,尽量不要降imgsz,否则小目标会更难学。

3.3 训练与验证:先看baseline,再谈调优

训练结束后,用验证集跑一次指标:

yolo detect val model=ele_ev/baseline/weights/best.pt \ data=data.yaml \ split=val

不要只看mAP@0.5这一个数字,要同时看mAP@0.5:0.95和每个类别的AP。电梯这种小数据集,mAP@0.5可能到0.95以上,但mAP@0.5:0.95如果低于0.6,说明框的定位精度不够,对梯控这种需要精确联动(比如车到门口才报警)的场景不够用。

看训练曲线时,重点看train/box_loss和val/cls_loss。如果box_loss持续下降但val/cls_loss上升,就是过拟合。这时候不要把锅甩给模型,回去查第2章的重复帧和漏标,数据集干净度比模型容量更容易成为瓶颈。

3.4 首轮训练后做一次错误分析

训练完baseline,先别急着调参,用模型在val集上跑预测,把结果画出来人工扫一遍:

yolo detect predict model=best.pt source=val/images save=True conf=0.25

然后把预测图按置信度排序,重点看两类错误:把背景当成人(电梯门开、地砖倒影),以及把电动车漏检。这一步花15分钟,能直接告诉你下一步该调什么。如果错误全是倒影,那就要在数据增强里加入翻转和亮度扰动;如果错误全是“人骑在车上”这种高度重叠目标,那就要考虑NMS策略或类别合并。这个习惯能帮你躲开90%的“loss曲线玄学”。

4. 人车识别调参:针对电梯环境的3个必调参数

有了baseline之后,调参要针对电梯场景的特点来,不要照搬通用目标检测套路。这里讲三个我每次做电梯人车识别都会调整的点:输入尺寸、类别损失权重、NMS与重叠目标策略。

4.1 小物体与遮挡:输入尺寸和训练超参

电梯内人车目标近大远小,广角畸变让同一辆车的框在不同位置宽高比差异极大。640输入通常够用,但如果val集里小目标较多,可以试试imgsz=800,小目标召回往往能提升三到五个点,代价是训练时间增加约一半。YOLOv8是anchor-free模型,不需要手动调锚框,但可以加mosaic=1.0和mixup=0.2,让模型在训练时看到更多遮挡叠加的合成样本。

超参数不需要命令行硬塞,我一般单独写一个hyp文件:

# hyp_ele.yaml lr0: 0.01 mosaic: 1.0 mixup: 0.2 cls: 0.7 box: 7.5

训练时加hyp=hyp_ele.yaml。这里cls: 0.7相比默认0.5略高,是让模型更重视类别分类,对低频的vehicle类友好;box: 7.5控制边界框损失权重,如果mAP@0.5够了但mAP@0.5:0.95不够,可以适当调到8.0。注意这些值不要一次改太多,一次动一个,否则没法归因。

4.2 类别不均衡:采样策略与离线增强

电梯数据集里person和vehicle的比例可能到10:1甚至更夸张。YOLOv8没有暴露直接的类别权重参数,但有两招很实用。第一招是调整copy_paste。在hyp文件里把copy_paste从0.0改成0.3,训练时会随机把一张图里的目标“粘贴”到另一张图,等效增加vehicle样本出现频率。第二招是离线做车辆类过采样,只对vehicle样本做随机HSV扰动、旋转、缩放,生成副本加进训练集,但注意副本不要直接复制原帧,否则会加深过拟合。

另一个思路是训练后处理:如果业务只关心“电梯里有没有违规车”,没必要强求模型把所有车完全分开。把person和vehicle框的IOU大于0.5的预测合并成“人车重叠事件”,也能达到梯控触发目的,这种取舍在安防场景很常见。

4.3 NMS与拥挤框:多人多车怎么后处理

电梯内经常出现两个人和一辆车挤在一帧里,检测框之间的IOU非常高。默认NMS阈值0.5可能把挨得近的两个人合并成一个框,或者把人和车压掉一个。预测时可以用更低阈值:

yolo detect predict model=best.pt source=val/images iou=0.4 conf=0.25

iou=0.4让NMS更激进,宁愿多保留重叠框也不合并。这个值对拥挤场景有效,但也会带来少量重复检测,需要结合实际报警策略权衡。如果发现“人推自行车”这种长期重叠的情况,与其调NMS,不如把训练数据里类似样本刻意多放一些,让模型学习到重叠部分属于哪个目标。

下面是我用过的参数组合,供参考:

参数baseline电梯场景推荐作用
imgsz640640或800提升小目标召回
cls0.50.7缓解类别不均衡
copy_paste0.00.3增加重叠样本
mixup0.00.2抗遮挡过拟合
iou0.50.4避免拥挤框合并

每次只改一个参数,跑完val对比,再改下一个。别同时动三个,不然模型翻车了都不知道是哪一项引起的。

5. 电梯人车数据集训练避坑:5个常见翻车点与排查

训练和调参过程中,有几类问题我反复遇到过,每次都能从数据或配置里找到原因。这里写出来,是希望你能少走几趟弯路。

5.1 现象:loss一直下降,但mAP上不去

原因:标签里有大量漏标或错标,尤其是车窗、倒影被标成人,模型学了一堆矛盾特征。loss下降不代表模型学对了,它只是在拟合噪声。

解决:回第2章做漏标排查,把预训练模型的预测结果和标注框比对,抽200张图人工复核。通常能把标签的问题解决掉,mAP就开始跟着loss走了。

5.2 现象:电梯门开启瞬间,大量误检

原因:数据集里几乎没有“空电梯+门打开后外部走廊出现”的帧,模型没见过门缝里突然出现的人影,于是把门框、楼道尽头的杂物当成人。

解决:补充电梯门开启瞬间的负样本,即没有目标的帧。在训练集里加入纯背景帧,标签为空txt。让模型学会“没人就是没人”,这是抑制误检最直接的手段。

5.3 现象:地砖反光倒影被识别成人

原因:标注时把倒影也框成了person,或者训练时有倒影的样本太少,模型把倒影形状当成了人形特征。

解决:先检查标注,把倒影框全部删掉。然后在增强里加大hsv_h和hsv_s的随机范围,让模型对人形颜色不那么敏感。如果现场还是误检,就在后处理加一条规则:检测框底部与镜面区域重叠超过70%就过滤掉,但注意不要把真实站立的人过滤了。

5.4 现象:夜间红外图整体偏色,模型检测率暴跌

原因:白天训练样本太多,模型隐式学到了白平衡和亮度的特征。夜间红外图是灰度偏绿,模型没见过。

解决:训练时加hsv_v随机变暗,以及灰度化增强。更彻底的做法是找一批真实夜间红外样本,哪怕只有几十张,用复制粘贴增强扩到训练集里。不要指望单独用CUT或风格迁移,成本高收益低。

5.5 现象:训练时batch size稍微调大就显存溢出

原因:电梯数据集图片分辨率高,imgsz=640时一张图占显存可能超过1GB,batch=16在8GB显卡上已经接近极限。

解决:优先降batch到8,显存仍不足就把workers调低,或把cache关掉。不要同时降imgsz,因为imgsz对小目标影响太大。实在不行用梯度累积,YOLOv8里通过batch配合accumulate参数等效放大batch。

6. 从数据集到落地的最后一公里:扩充、导出与验收习惯

baseline跑通、参数调完,整个流程才走了一半。真正让电梯人车识别数据集发挥价值的,是把模型用起来,并让它适应现场数据。这里说一个我常用的验证习惯:拿一段连续30分钟的电梯监控视频,不做任何剪辑,原速跑推理,统计每帧的检测结果,关注误报率和漏报率,而不是只看mAP。mAP衡量的是离线指标,连续视频才能暴露出帧间抖动、门开误检、灯光切换带来的现实问题。

如果现场误报多,先用第5章的负样本思路补数据,再考虑剪枝或量化。导出到嵌入式设备前,我会把FP32模型和INT8模型在同样30段视频上跑一遍,对比每段的误报数。INT8掉点一般在1到2个mAP以内,如果掉得厉害,就启用混合量化,只量化卷积层。最后把模型导出为ONNX或Engine格式,用推理引擎跑一遍,确保后处理里的iou和conf参数和训练时一致。

这个东西做久了,我最大的教训是:数据集干净、划分科学、验证视频真实,比任何花哨的网络结构都重要。每次现场翻车,八成原因是训练数据没覆盖到某个角落的光照或遮挡模式。所以现在每拿到一套电梯内人车识别数据集,我都会先花两天时间清洗和补样本,而不是急着训练。这套流程走顺了,后面调参基本是水到渠成。希望帮到你。

本文还有配套的精品资源,点击获取

需要专业的网站建设服务?

联系我们获取免费的网站建设咨询和方案报价,让我们帮助您实现业务目标

立即咨询