摔倒检测数据集自建全流程:从采集到质控的实战经验 简介本资源是面向计算机视觉开发者与AI安全系统研究者的专业摔倒检测数据集专用于行人姿态识别、智能监控预警及辅助机器人跌倒响应等场景适合具备目标检测基础的中高级学习者开展模型训练与算法优化。压缩包共2000个文件包含5740张JPG格式原始图像与4576个配套XML标注文件总大小288.95MB其中XML文件完整记录了每张图中行人边界框坐标、摔倒状态标签及关键关节位置如头、肩、膝、踝支撑YOLO、Faster R-CNN等主流检测框架的端到端训练。已有4832人学习下载实际应用中可直接划分训练/验证/测试集并结合数据增强策略快速构建鲁棒模型。资源命名规范如people(1672).xml、标注一致性高且覆盖平地、楼梯、碰撞等多种摔倒类型显著降低数据预处理成本助力高效复现与工程落地。摔倒数据集标注5000张我把从采数据到质控的全流程踩过的坑都写在这了做摔倒检测的人应该都有同感公开数据集一搜一大把但真正拿去训练完一测在公开测试集上看着还行落地到你自己的摄像头视角里就原形毕露。我之前接过一个智慧养老的项目需要识别老人从床上滚落、在卫生间滑倒、从轮椅上下滑这类非常具体的摔倒姿态翻遍了公开数据集要么摔倒样本太少要么全是固定视角、正常人主动摔倒的摆拍根本没有覆盖真实场景里的复杂遮挡和非常规动作。最后只能自己动手做数据集从采集到标注目前累计完成5000张已标注图像配合YOLOv8 pose做关键点检测整套流程跑下来想把这些真正能落地的东西分享出来。这篇文章不聊算法调参专讲数据侧怎么做——采集、清洗、标注工具选型、关键点规范、质控流程、格式转换全是实操记录。1. 摔倒检测为何要自建数据集公开数据集的坑与5000张的价值1.1 公开数据集普遍存在的三个问题先说结论不是公开数据集不能用而是你没法指望它直接满足你的业务场景。我遇到的最典型问题有三个。第一是样本分布极度不平衡。很多公开摔倒数据集里摔倒样本只占几百张而日常行走、坐下、弯腰这类负样本占了几千甚至上万张。用这种数据训练出来的模型对“摔倒”这个正类的召回率会非常难看。做行为识别的人都清楚摔倒是小概率事件但恰恰是小概率事件要求模型有极高的敏感度漏检一次可能就是事故。第二是摔倒姿态的同质化严重。公开数据集里的摔倒大多是“正向跌倒”“侧向跌倒”这种比较标准的角度背景也相对干净。但真实场景是什么是老人从床上滚落时身体蜷缩、腿搭在床沿是卫生间里扶着洗手台慢慢滑坐下去是轮椅上前倾滑落时头部过冲、身体折叠。这些姿态在公开数据里几乎找不到。你拿同质化的数据训练模型自然只能学会“标准摔倒”。第三是视角与摄像头参数的差异。公开数据集的拍摄高度、焦距、俯仰角千差万别你落地时的摄像头装在墙角2.8米高处、用大广角、画面有畸变这时候直接拿公开集训练再迁移效果一定打折扣。自建数据集可以从源头模拟你的部署视角。1.2 自建数据集的定位不是替代而是补充我自建这个数据集的目标很明确不是完全抛开公开数据而是让自建数据成为模型在目标场景下真正“见过世面”的那部分。5000张听上去不多但关键是每张都跟业务强相关。我的做法是“公开数据打底自建数据精修”。先用公开集预训练一个基础模型再用自建数据集做针对性微调。这样既避免了从零开始采集的数据量压力又保证了模型在目标场景下的表现。如果你也想做类似的事建议先问自己三个问题部署场景的摄像头视角用什么样需要识别哪些摔倒子类型哪些负样本最容易误报这三个问题的回答就是自建数据集的选材清单。我自己的清单是床沿滚落、床边坐空、卫生间滑倒、轮椅前倾/侧滑、起身跌倒、站立摔倒等6类正样本另加行走、坐下、躺下、弯腰、蹲下、被遮挡人体等6类负样本。5000张里正负样本比例大概4:6正样本2000张出头负样本3000张左右。实测下来这个比例比纯正样本堆量要稳得多。2. 采集与清洗决定模型上限的第一道关口2.1 视频抽帧策略与样本覆盖很多人做数据集上来就找图片但我建议优先找视频因为视频可以按帧抽不仅效率高而且天然能获得同一动作的连续过渡帧对pose检测特别重要。我采集的视频来源主要有三块一是自己搭的测试场景里请人模拟摔倒注意安全铺好软垫二是从开源视频片段中筛选许可协议允许的素材三是和本地养老机构合作拍摄的真实非隐私模拟场景。抽帧不能贪多否则相邻帧太相似反而降低数据多样性。我采用的策略是先按5fps抽帧然后用感知哈希算法做相似度去重保证同一段动作里取到的帧不会连续三帧都几乎一样。具体落地可以写个简单脚本先隔帧抽再用pHash计算相邻帧汉明距离超过阈值才保留。这比直接每隔固定帧数抽样效果好得多既能保留动作连续性又能避免冗余。另一个关键是场景覆盖。我特意把视频素材拆成了不同光照、不同时段、不同背景白天强光、傍晚暗光、夜间红外、日光灯、暖光灯、有窗帘逆光、有风扇遮挡、有家具遮挡都尽量包含。因为摔倒检测的常见部署地就是卧室、卫生间、客厅这些环境的光线和遮挡模式差异非常大。抽帧之后会产生一个原始图池我大约抽了两万多张原图最后经过清洗只保留了一部分。2.2 清洗时最容易漏掉的干扰场景清洗是最容易被人忽视、但影响极大的环节。很多标注项目翻车就是因为脏数据没去掉标注员费了大力气标了一堆模型没法学的东西。我总结清洗要重点关注四类图。一是过度模糊和运动拖影的图。人在摔倒瞬间动作速度极快视频抽帧很容易抽到模糊帧。这类图如果用YOLOv8 pose标关键点标注员只能靠“猜”标出来的关键点位置根本不可信。我人工清洗时看到模糊到无法准确看到手肘或膝盖位置直接删除不要手软。二是人物占比过小的图。如果画面里人只占几十个像素关键点标注基本没意义。除非你明确要做远景检测否则建议裁掉或删除。标注规范里我设了一条硬线人体高度小于画面高度1/10的图不入库。三是异常形变和极端视角的图。比如顶视角向下拍摄的人或者被栏杆、床栏、玻璃严重遮挡的人标注难度极大而且普通矩形框和关键点都很难表达。这类图要么单独分类标注要么先排除。四是最容易被忽略的“假负样本”。比如人在画面里但被大范围遮挡模型很容易误判成未检出。清洗的时候不能因为“看不全”就把图删掉有些应该作为困难负样本保留。我的做法是单独开一个“困难场景”文件夹专门存放遮挡严重、光照反常、低分辨率的图这些在训练时能帮助模型学会不误报。我清洗两万多张原图后剩下约8500张质量合格的图再经过标注后筛选最终保留5000张。这中间每一步都需要人工介入工作量不小但这是保模型下限的关键。3. 标注工具选型与团队协作工作流3.1 主用工具Labelme的配置与部署数据标注工具我前前后后试过不少包括Labelme、Label Studio、Makesense、X-AnyLabeling还有在线标注平台。最后主力工具定为Labelme原因很简单全本地化部署离线可用不用把数据传到第三方服务器对隐私场景友好支持polygon和关键点标注导出格式是json容易转成各种训练格式。Labelme的部署没什么难度pip install labelme就可以但我建议用conda单独建环境避免依赖冲突。我的环境一般是Python 3.9 labelme 5.5.4。启动时有一个很实用的参数labelme --autosave --labels labels.txt。--autosave会在每次切换下一张图时自动保存json避免标注员忘记保存--labels指定预定义标签文件避免每次手输标签也防止不同人标签写法不一致。预定义标签文件很重要比如fall_from_bed fall_in_bathroom fall_from_wheelchair fall_standto_ground sitting walking lying squatting bending person_occluded有了这个文件标注员双击标签就能选中类别不会因为输入法大小写、空格问题导致同一个类出现多个写法。我见过太多团队栽在这种细节上一个Fall和fall就够训练脚本烦半天。3.2 Label Studio在行为分段标注中的优势虽然标注图片主力用Labelme但有一个环节我用Label Studio那就是视频行为分段标注。摔倒检测不只是单帧分类很多时候需要输出一个动作序列比如“行走-后仰-摔倒-躺地”。这个序列对时间边界要求很高。Label Studio对视频标注支持得很好可以按时间轴打标签把每一段时间标记为某个动作类别。我们标完视频片段后再根据标签的时间范围去抽帧抽出来的帧就有了“动作阶段”的上下文信息。比如同一段摔倒在“后仰”阶段和“躺地”阶段的关键点姿态差异很大模型如果只知道“摔倒”这一个标签压力会非常大。如果只是做单帧目标检测Label Studio比Labelme重但这个阶段补充上下文对pose任务很有帮助。我团队的流程是先用Label Studio标行为片段再导出事件列表后续抽帧时用事件内容自动打上分类标签再到Labelme里精修关键点。这样两条线互补效率反而更高。3.3 多人标注任务的协同与命名规范5000张图靠一个人标是不现实的我拉了三人小团队分工。多人在线协作如果直接共享同一个Labelme目录会乱套我们的做法是按子任务拆分成多个目录每个标注员负责一个目录互不干扰。文件名在采集阶段就统一命名格式为{场景}_{动作类别}_{视频来源}_{序号}.jpg例如bedroom_fallbed_001_000123.jpg。这个命名后面排重、追溯都靠它。每次标注完成后标注员把json文件放在annotations/{标注员姓名}/文件夹下方便管理人。隔天抽取前一天的标注结果做交叉复核及时反馈。这里重点说一下命名规范不要用frame_0001.jpg这种没信息的名字。你后面清洗、转格式、查错的时候没有语义信息的文件名会让人崩溃。哪怕这个文件名长一点也要包含场景和动作信息。4. YOLOv8 pose摔倒标注的核心细节4.1 关键点定义与骨架连接逻辑YOLOv8 pose采用的COCO 17关键点定义鼻子、左眼、右眼、左耳、右耳、左肩、右肩、左肘、右肘、左腕、右腕、左髋、右髋、左膝、右膝、左踝、右踝。摔倒检测里真正起决定性作用的关键点集中在下半身——髋、膝、踝以及上半身的肩、肘、腕。因为摔倒瞬间的典型特征是髋关节高度快速下降、躯干与地面夹角突变、四肢伸展或蜷缩异常。我们标注时的原则是“只标可见的关键点”。被遮挡或完全不可见的关键点不要硬标也不能随便给一个位置。这个和检测框不一样框可以包住被遮挡的人体但关键点必须有像素依据。比如一个人侧身倒地远处的那个肩膀可能被上臂挡住这时候左肩、左肘、左腕大概率不可见就直接留空。YOLOv8 pose训练时支持关键点缺失用-1表示这比乱标好得多。还有一个容易踩的坑关键点的“位置”到底标在关节中心还是关节点外侧我在标注规范里明确要求标在关节骨性中心的像素位置例如膝盖就标在髌骨附近不要标到腿骨边缘。这直接影响模型预测的稳定性。多人标注前必须先花半天统一标准用三五张典型图做试标大家对比讨论差异。4.2 遮挡、自遮挡与低质量帧的标注规范摔倒场景的遮挡远比普通行人检测多。常见情况老人倒在床边下半身被床栏挡住从轮椅滑落时手臂被身体压住卫生间滑倒后蜷缩膝盖遮挡了脚踝。遇到这些情况我们的处理规则如下关键点可见性低于30%的帧直接不标关键点只保留检测框类别为“person_occluded”。这类图可以作为检测层的困难负样本但不会进入pose训练。如果关键点被部分遮挡但轮廓可推断比如膝关节被裤腿遮挡但能看到腿的走向这种可以标注但要在备注列写明“inferred”。自遮挡比如侧躺时左右髋关节重叠非常棘手我们规定此时两个关键点都标在同一像素位置附近允许重复但不允许随意选择不存在的“中间点”。如果实在分不清左右两个点都标到可见的那一侧同时给该样本打“side-occlusion”标签后续数据增强时可以考虑对这类样本水平翻转增加左右混淆的多样性。低质量帧主要指模糊和运动拖影。我在第2章清洗时删了一部分但保留了一部分轻微模糊的帧因为真实摄像头实时推理时必然会出现模糊帧。这类帧的关键点标注策略是能看清轮廓的标注看不清的宁可缺省不要硬猜。硬猜的关键点会让模型学到噪声。4.3 从Labelme到YOLO格式的转换脚本Labelme导出的每个json长这样{ version: 5.5.4, flags: {}, shapes: [ { label: fall_from_bed, points: [[x1,y1], [x2,y2], ...], group_id: null, shape_type: polygon, flags: {} }, { label: left_shoulder, points: [[x,y]], group_id: null, shape_type: point, flags: {} } ], imagePath: bedroom_fallbed_001_000123.jpg, imageData: null }注意Labelme的检测框通常用polygon表示需要先求外接矩形。关键点都是shape_type为point的shape。转换到YOLOv8 pose格式时标签文件是txt每行格式为class_id x_center y_center width height px1 py1 px2 py2 ... px17 py17 visibility1 visibility2 ... visibility17这里visibility是COCO的可见性标志0表示未标注1表示标注但被遮挡2表示可见。转换的时候我写了一个脚本把Labelme的point归类到17个关键点名称并把可见性设为2如果有遮挡备注手动设成1缺失的关键点坐标填0visibility填0。下面是一个简化版的转换脚本核心逻辑供参考import json import os COCO_KEYPOINT_NAMES [ nose, left_eye, right_eye, left_ear, right_ear, left_shoulder, right_shoulder, left_elbow, right_elbow, left_wrist, right_wrist, left_hip, right_hip, left_knee, right_knee, left_ankle, right_ankle ] def labelme_to_yolov8_pose(json_path, img_w, img_h, class_map): with open(json_path, r, encodingutf-8) as f: data json.load(f) boxes [] keypoints_dict {} for shape in data[shapes]: label shape[label] if shape[shape_type] polygon or shape[shape_type] rectangle: pts shape[points] if shape[shape_type] polygon: xs [p[0] for p in pts] ys [p[1] for p in pts] x_min, x_max min(xs), max(xs) y_min, y_max min(ys), max(ys) else: x_min, y_min pts[0] x_max, y_max pts[1] boxes.append((label, x_min, y_min, x_max, y_max)) elif shape[shape_type] point: pt shape[points][0] if label in COCO_KEYPOINT_NAMES: keypoints_dict[label] (pt[0], pt[1]) # 这里假设每张图只有一个人体目标如果有多个需要扩展 if len(boxes) 0: return None label, x_min, y_min, x_max, y_max boxes[0] class_id class_map[label] # 归一化检测框 dw 1.0 / img_w dh 1.0 / img_h x_center (x_min x_max) / 2.0 * dw y_center (y_min y_max) / 2.0 * dh w (x_max - x_min) * dw h (y_max - y_min) * dh parts [f{class_id}, f{x_center:.6f}, f{y_center:.6f}, f{w:.6f}, f{h:.6f}] for kp_name in COCO_KEYPOINT_NAMES: if kp_name in keypoints_dict: kx, ky keypoints_dict[kp_name] parts.append(f{kx * dw:.6f}) parts.append(f{ky * dh:.6f}) parts.append(2) else: parts.append(0) parts.append(0) parts.append(0) return .join(parts)这段代码只处理单人的简单情况如果画面里有多人需要用group_id把同一个人对应的检测框和关键点关联起来。我实际数据集中很多是单人场景但床沿、轮椅附近也有多人场景处理多人时我建议直接用Labelme的group_id字段把每个人的身体部件划分到同一组转换时按组分别生成一行标注。这一点不写清楚很容易踩坑。还有一个非常容易踩的坑Labelme保存的图像尺寸和实际图像尺寸不一致。如果你的json是从一个尺寸的图标的后面换图了坐标全漂移。我每次转换前都先确认data[imageWidth]和data[imageHeight]如果和文件名对应的图尺寸不匹配必须重批或者特判。否则模型训练出来坐标全偏各种奇葩预测都来了。5. 5000标注全流程质控错误标注如何毁掉模型5.1 双人复核与抽检机制设计标注量大之后错误是不可避免的。常见的错误有关键点位置偏移、类别打错、检测框漏框、明明是负样本却标成正样本。如果不能及时拦截等训练时再发现就是灾难。我的质控流程分三层第一层是标注员自检。每标完一批标注员自己用Labelme重新打开图片把所有关键点都显示出来检查有没有明显偏离关节的点比如左脚踝标到了右脚上。这一层能拦掉至少一半的低级错误。第二层是交叉复核。我要求每张已标注图必须由另一个人复核一次复核人只负责看不能直接改发现了问题在专门的问题记录表里登记文件名、错误类型、修改建议。每日记录每周统计错误率。如果某人的错误率超过了5%就要重新培训并对这位标注员负责的所有历史数据重新排查。第三层是AI辅助抽检。训练一版快速模型用模型正向预测这批标注数据将预测结果和标注结果做mismatch比对。如果模型预测的关键点与人工标注的关键点相差超过一定像素阈值比如20像素就找出来人工确认。这一步能发现人工很难注意的“系统性偏差”——比如某个人习惯把肩关键点标得比实际位置偏外5像素一个人看不容易发现AI一对比就现形。5.2 错误标注对训练loss的影响实例很多人总问“错误标注会导致模型训练集loss降不下来吗”答案是会而且会以非常迷惑的方式出现。我举一个实际遇到的例子。有一批卫生间滑倒难例标注员小张习惯把左髋和右髋标在同一水平线上但真实像素里右侧髋关节明明被水渍和阴影干扰看起来偏上于是她就把右髋挪到左髋的高度。结果训练时这个样本的loss始终很高模型预测的右髋位置老是比标注低一截。表面上是模型学不会实际上标注本身就是错的模型反而学得更接近真实位置。另一次是检测框的问题。有一个“弯腰捡东西”的负样本标注员不小心把框标成了站立姿态而不是弯腰后的姿态框内一半是空的模型学到的特征是“上半身空白区域弯腰”导致推理时大量误检。这类错误比关键点偏移更隐蔽因为它发生在类别和框的匹配关系上。我的经验是如果训练过程中发现某个类别的loss显著高于其他类别先别急着调权重立刻去抽查这个类别的标注数据。把loss最高的20张样本可视化出来对照原图看标注你会发现至少一半问题出在标注上。还有一个更直接的指标标注框的宽高比分布。如果发现某个类别框的宽高比方差异常大大概率是框标错了。5.3 类别不均衡的处置摔倒样本为什么必须过采样5000张图里正样本各类摔倒2000多张负样本3000张看似比例还行。但在YOLOv8 pose训练里真正参与loss计算的只有标注了关键点的人体也就是说所有负样本里的站立、行走、坐下如果没有人形框和关键点它们对pose分支没有贡献。我实际训练时发现了一个问题如果负样本过多而正样本不足模型检测框分支会非常保守倾向于把所有直立人都框出来但摔倒姿态的框经常漏。解决方式我用了两种。一是离线过采样。对摔倒正样本做几何增强例如水平翻转、小角度旋转、尺度缩放、随机擦除把正样本数量临时扩充到负样本的1.2倍。生成后的增强样本不会永久加入数据集只在训练流水线里动态生成避免同一图像反复出现导致过拟合。二是Focal Loss配合类别权重。YOLOv8本身支持每个类别的loss weight我通常把摔倒正类的权重设为1.5~2.0负类保持1.0。但这只能缓解误分类不能替代数据层面的均衡。权重只是一个平滑器真正管用的还是让模型看到更多的摔倒姿态。另外还有一个小技巧把摔倒动作的“时序中间帧”当作关键样本单独增强。比如从站立到倒地的过程第1帧、中间帧、末帧的姿态差异很大我在采样时特意保证对每个摔倒动作至少保留“前摇、倒地、躺定”三个阶段各5帧而不是均匀抽帧。这样模型能学到摔倒的动态过程而不是只记住“躺在地上”这一个静态姿态。这个思路来自行为学视频标注的启发对时间序列中的动作识别特别重要。6. 数据集发布前最后一道工序切分、增强与格式统一6.1 train/val/test划分的讲究数据切分看似简单其实坑很多。最大的坑是“视频泄漏”如果同一个视频抽出的帧一部分在训练集一部分在验证集模型其实已经“看过”同一场景的相邻帧验证集loss会虚低。这会让模型在真实场景上的表现被严重高估。我的切分原则是“按视频源分绝不按帧随机分”。也就是说一个视频的所有帧只能全部进入train、val或test三者之一。如果视频之间还存在重复场景比如同一拍摄环境不同时段也要尽量把相同场景归入同一个集合避免场景泄漏。正常比例我按8:1:1划分。但在划分前我会先做一次“难例集中”处理把所有困难场景遮挡、低照度、模糊单独拎出来按比例分配到val和test里保证评估集中困难样本的比例和真实场景接近而不是全部塞进train里当难度负担。这样训练难度虽然大了但评估结果更有说服力。6.2 针对摔倒场景的数据增强策略YOLOv8训练时默认有mosaic、随机仿射等增强但有些增强对pose任务并不友好比如mosaic拼接时如果把人裁切到边缘关键点坐标可能负值需要小心处理。我额外使用的增强策略主要有随机水平翻转但对“左右关键点”的交换逻辑要实现正确。比如翻转前鼻子在中心偏左翻转后应该变到中心偏右同时左肩变成右肩。这个映射在数据加载时必须写对。随机旋转和小角度透视变换。一个小技巧是旋转角度控制在±15度以内过大旋转会让摔倒姿态失真比如因为透视原因人倒地后头部本来就在画面边缘再旋转30度就出画了。随机遮挡模拟。摔倒场景里腿被床栏、桌椅遮挡很常见我用随机矩形遮挡模拟这种情况但遮挡框不能太大否则关键点全部失效。我通常限制遮挡区域不超过人体框的20%。色彩抖动和亮度对比度增强。夜间红外模式下的图像是灰度图而白天采集的是彩色图。我专门生成了一组“红外模拟图”把彩色图转灰度再增强噪声让模型适应夜间模式。这个对智能监控项目尤其有效。6.3 格式兼容YOLOv8 pose与COCO的互通标注完成后我最终输出的数据集同时提供YOLOv8 pose格式和COCO格式方便团队在不同框架间切换。YOLOv8的官方格式上文已经写了COCO格式则需要一个annotation的json文件包含images、annotations、categories三段。如果后续要做人体姿态估计模型复现COCO格式更通用。转换的关键点是COCO里每个annotation的keypoints是一个长度为51的一维数组顺序是[x0,y0,v0, x1,y1,v1, ..., x16,y16,v16]num_keypoints字段表示可见关键点数量。我建议写一个双向转换工具把YOLO txt转成COCO json然后统一用COCO API做可视化验证。可视化这一步很重要把所有标注渲染到图上随机抽查几百张看关键点是否落在合理位置检测框是否紧凑。这一步我每次发货前必做能直观发现很多脚本层面看不出的问题。关于在线工具如果你不想本地部署可以用Makesense.ai快速试标一批但它的pose关键点标注能力很弱主要还是检测框。在线标注工具可旋转比如针对遥感或大图的旋转标注对于摔倒这种常规图像意义不大我更推荐本地流程隐私和稳定性都有保障。至于3D点云标注和遥感图像标注那是另一套体系和2D图像标注在工具链上完全不一样这里就不展开讲了。最后再分享一个个人经验数据集做到5000张级别真正难的其实不是数量而是“每一张都值得被训练看到”。我中间有段时间为了凑数把条件不太好的模糊帧也放进来结果模型收敛速度明显变慢后来删掉这批只保留质量中上的训练反而更稳。所以如果你也在自建摔倒数据集我的建议是先保证每个子类别有足够的代表样本再谈总量。5000张如果分布合理已经足够YOLOv8 pose做落地级微调了。本文还有配套的精品资源点击获取