ARTICLE DETAIL

资讯详情

深耕网站建设与运营推广的一线实战洞察。

基于YOLOv8的跌倒检测实战:数据集、训练与源码全解析

基于YOLOv8的跌倒检测实战:数据集、训练与源码全解析 简介这份资源面向计算机视觉初学者与安防场景开发者提供一套可直接上手的跌倒检测完整方案解决从数据到模型落地的全流程问题。压缩包共1438个文件约78.41MB其中1428张jpg图片构成跌倒与正常行为的数据集6个py脚本负责训练、推理与数据处理2个md文档说明使用方式另附1个pt权重与1个onnx模型便于直接部署或二次训练。资源基于YOLOv8实现特征提取采用CSPDarknet结构通过CSP跨阶段部分网络减少参数量并提升特征提取效率检测头借鉴YOLOv4-Head思路并采用Anchor-Free方式直接预测目标中心点与宽高比例减少锚框数量、兼顾速度与精度。目前已有1020人学习下载读者可据此复现训练流程、理解模型结构并快速迁移到老人监护、智能看护等实际场景中。1. 跌倒检测为什么值得用 YOLOv8 重做一遍做过跌倒检测的工程师大多踩过同一个坑用姿态估计先抽骨架再拿 LSTM 或阈值判据去分类“摔倒”这个动作结果模型在实验室里准确率 95%一搬到走廊、卫生间、夜间红外场景就集体翻车。原因不复杂——骨架点本身抖动大遮挡一多关键点就飘动作分类器再强也救不回上游的噪声。而 YOLOv8 走的是另一条路把“人跌倒”当成一个目标检测类别直接让网络在像素层面学“躺倒的人体框长什么样”绕开了关键点估计这一层玄学。这套「基于 YOLOv8 训练跌倒检测模型 数据集 源码」的思路本质是把跌倒检测从时序动作识别问题降维成单帧目标检测问题。它解决的是在监控摄像头、边缘盒子、嵌入式设备上用一张图就能判断画面里有没有人处于跌倒姿态并给出位置框。适合谁适合手上有摄像头视频流、想快速落地一个可报警的跌倒识别模块的开发者也适合刚学完 YOLOv8 想找一个真实场景练手的人。数据集和源码打包在一起意味着你不用从零标注几千张图直接能跑通训练到推理的闭环。2. 跌倒检测数据集怎么准备从原始视频到 YOLO 格式2.1 跌倒检测的数据集长什么样才算合格跌倒检测数据集和通用 COCO 最大的区别在于类别定义。常见做法是只保留两个类fall跌倒和person正常站立/行走/坐。为什么保留person因为如果只训fall一个类模型会把所有躺着的物体、地上的阴影、甚至横放的拖把都判成跌倒误报率会高到没法用。加上person类之后网络被迫学会区分“站着的人”和“倒下的人”边界清晰很多。一个能用的跌倒数据集通常需要覆盖这些场景维度白天/夜间红外、室内走廊/卧室/卫生间、单人/多人、部分遮挡床沿、沙发、桌子挡住半个身子。数量上fall类至少 1500 到 3000 个实例框person类 3000 到 6000 个比例别太悬殊。如果fall太少训练时正样本被淹没召回率上不去。提示网上能直接下载的公开跌倒数据集大多来自 UR Fall、Le2i 这类学术库帧率和分辨率参差拿来直接用之前一定要做去重和抽帧否则相邻帧几乎一样等于变相过拟合。2.2 用抽帧脚本把视频转成图片原始素材如果是视频第一步是抽帧。不要每秒都抽跌倒动作持续 1 到 2 秒按 5 到 8 fps 抽就够既能覆盖动作过程又不至于产生大量冗余帧。import cv2 import os def extract_frames(video_path, out_dir, fps_target6): 按目标帧率抽帧避免相邻帧高度重复 os.makedirs(out_dir, exist_okTrue) cap cv2.VideoCapture(video_path) src_fps cap.get(cv2.CAP_PROP_FPS) # 计算抽帧间隔源帧率 / 目标帧率 interval max(int(round(src_fps / fps_target)), 1) idx, saved 0, 0 while True: ret, frame cap.read() if not ret: break if idx % interval 0: # 统一缩放到 640 宽减少后续标注和训练开销 h, w frame.shape[:2] scale 640.0 / w frame cv2.resize(frame, (640, int(h * scale))) cv2.imwrite(os.path.join(out_dir, fframe_{saved:05d}.jpg), frame) saved 1 idx 1 cap.release() print(f共保存 {saved} 帧) extract_frames(fall_video.mp4, frames/)逻辑说明interval控制抽帧密度源视频 30fps 时interval5正好得到 6fps。缩放这一步很关键YOLOv8 默认输入 640提前把图缩到 640 宽能省掉训练时的重复缩放也统一了标注坐标系。参数上fps_target建议 5 到 8太低会漏掉跌倒中间态太高则冗余。2.3 用 Labelme 标注再转 YOLO 格式标注工具用 Labelme 还是 LabelImg 都行Labelme 装起来方便输出 JSON。但 YOLOv8 要的是每张图一个.txt每行class_id cx cy w h全部归一化到 0 到 1。所以需要一个转换脚本。import json import os import glob # 类别映射顺序必须和 data.yaml 里的 names 一致 CLASS_MAP {person: 0, fall: 1} def labelme_to_yolo(json_path, out_dir, img_w, img_h): with open(json_path, r, encodingutf-8) as f: data json.load(f) lines [] for shape in data[shapes]: label shape[label] if label not in CLASS_MAP: continue pts shape[points] xs [p[0] for p in pts] ys [p[1] for p in pts] # 转成中心点 宽高并归一化 cx (min(xs) max(xs)) / 2.0 / img_w cy (min(ys) max(ys)) / 2.0 / img_h w (max(xs) - min(xs)) / img_w h (max(ys) - min(ys)) / img_h lines.append(f{CLASS_MAP[label]} {cx:.6f} {cy:.6f} {w:.6f} {h:.6f}) name os.path.splitext(os.path.basename(json_path))[0] with open(os.path.join(out_dir, name .txt), w) as f: f.write(\n.join(lines)) for jp in glob.glob(labels_json/*.json): labelme_to_yolo(jp, labels_txt/, 640, 480)逻辑说明CLASS_MAP的 id 必须和后面data.yaml的names顺序严格对应否则训练出来的模型会把fall和person搞反。归一化用图片实际宽高所以抽帧时如果做了缩放这里要填缩放后的尺寸。转换完记得抽查几张用可视化脚本把框画回图上确认没偏。2.4 划分训练集验证集和 data.yaml 配置目录结构按 YOLOv8 官方约定来dataset/ images/ train/ val/ labels/ train/ val/然后写data.yamlpath: /home/user/dataset train: images/train val: images/val nc: 2 names: [person, fall]nc是类别数names顺序和CLASS_MAP一致。划分比例常见 8:2如果fall样本本来就少可以 9:1把更多跌倒样本留给训练。验证集里必须包含至少几百个fall实例否则评估指标没意义。3. YOLOv8 训练跌倒检测模型的完整命令与参数3.1 环境配置CPU 版和 GPU 版怎么选标题里带“源码”通常意味着开箱能跑但环境还是得自己配。Ubuntu 20.04 上装 YOLOv8 最省事的方式是 pip# 创建虚拟环境避免污染系统 Python python3 -m venv yolov8_env source yolov8_env/bin/activate # 安装 ultralytics会自动带上 torch pip install ultralytics # 验证安装能打印版本号就说明通了 yolo version如果你只有 CPU比如在没独显的服务器或笔记本上先跑通流程pip install ultralytics装的就是 CPU 版 torch训练会慢但能跑。有 NVIDIA 显卡的话先去 pytorch 官网按 CUDA 版本装对应 torch再装 ultralytics否则会默认装 CPU 版。GTX 1660 Ti 这类 6G 显存的卡跑yolov8n或yolov8s加imgsz640没问题yolov8m就要降 batch。注意yolo version报错多半是 PATH 没生效重新source一下虚拟环境或者直接用python -c import ultralytics; print(ultralytics.__version__)验证。3.2 从预训练权重开始训练的最小命令跌倒检测数据量通常不大从 COCO 预训练权重微调比从头训收敛快得多。最小命令yolo detect train \ datadataset/data.yaml \ modelyolov8n.pt \ epochs100 \ imgsz640 \ batch16 \ device0 \ projectruns/fall \ nameexp1逐参数说明data指向刚才写的 yamlmodelyolov8n.pt会自动下载官方预训练权重n 是最小模型速度快适合先验证流程epochs100对跌倒这种二类任务通常够看验证集 mAP 不再涨就可以停imgsz640是输入分辨率跌倒目标通常占画面比例不小640 够用batch16在 6G 显存上跑yolov8n比较稳显存不够就降到 8device0指定第一块 GPUCPU 训练改成devicecpu。训练过程中终端会打印每个 epoch 的 box_loss、cls_loss 和 mAP50。跌倒检测最该盯的是fall类的召回率因为漏报一次跌倒比误报一次严重得多。如果fall召回一直上不去先别急着加 epoch回头查数据集里fall框是不是标得太松或太紧。3.3 关键训练参数怎么调跌倒场景的三个必调项第一个是imgsz。监控画面里人通常只占画面一小块如果原始分辨率是 1080p直接缩到 640 会让人变得很小跌倒姿态特征丢失。这种情况可以把imgsz提到 960 甚至 1280代价是显存和训练时间上升。判断标准把一张典型图缩到目标尺寸人框还能不能看出是躺着的。第二个是batch和workers。workers是数据加载线程数默认 8在 CPU 核多的机器上可以提到 16 加快喂数据但别超过核数否则线程切换反而拖慢。batch受显存限制显存爆了会报 CUDA out of memory降 batch 或降 imgsz 二选一。第三个是数据增强。YOLOv8 默认开了 mosaic、HSV 抖动、翻转。跌倒检测里水平翻转一般安全但垂直翻转要小心——把画面上下颠倒后站着的人看起来像倒立可能被误标成跌倒。如果数据集里没有倒立场景建议关掉flipudyolo detect train datadataset/data.yaml modelyolov8n.pt \ epochs100 imgsz640 batch16 device0 \ flipud0.0 mosaic1.0mosaic1.0表示 100% 概率做马赛克拼接增强对小数据集有帮助但如果fall样本本来就少mosaic 可能把跌倒框拼到奇怪位置可以降到 0.5 观察效果。3.4 训练完怎么验证看曲线和混淆矩阵训练结束后runs/fall/exp1/下会有results.png、confusion_matrix.png、weights/best.pt。results.png里重点看三条线train/box_loss和val/box_loss是否同步下降如果训练 loss 降但验证 loss 涨就是过拟合需要加数据或加增强metrics/mAP50(B)是否稳定上升后走平metrics/recall(B)对跌倒检测尤其重要。混淆矩阵能直接看出fall被误判成person的比例。如果fall大量跑到person那一列说明模型没学好跌倒特征可能是fall样本太少或者标注时把“蹲下”也标成了fall导致类别边界模糊。4. 推理部署与跌倒报警逻辑怎么接4.1 用 best.pt 跑单张图和视频流推理训练完拿best.pt做推理命令行一行yolo detect predict modelruns/fall/exp1/weights/best.pt \ sourcetest_video.mp4 saveTrue conf0.4conf0.4是置信度阈值跌倒检测建议比通用检测低一点比如 0.3 到 0.4宁可多报也别漏报。saveTrue会把画了框的视频存到runs/detect/predict/。如果要接自己的业务逻辑用 Python API 更灵活from ultralytics import YOLO model YOLO(runs/fall/exp1/weights/best.pt) results model.predict(sourcetest_video.mp4, conf0.4, streamTrue) for r in results: for box in r.boxes: cls_id int(box.cls[0]) conf float(box.conf[0]) # cls_id 1 对应 fall 类 if cls_id 1 and conf 0.4: print(f检测到跌倒置信度 {conf:.2f})逻辑说明streamTrue让推理按帧流式返回适合视频流不占内存。box.cls是类别 id和data.yaml的names对应fall是 1。拿到跌倒框后可以接报警连续 N 帧检测到fall才触发避免单帧误报。4.2 连续帧确认把单帧检测变成可靠报警单帧检测最大的问题是误报一个人弯腰捡东西可能某一帧看起来像跌倒。工程上常用“连续帧计数”来过滤fall_counter 0 FALL_THRESHOLD 5 # 连续 5 帧检测到跌倒才报警 for r in results: has_fall any(int(b.cls[0]) 1 and float(b.conf[0]) 0.4 for b in r.boxes) if has_fall: fall_counter 1 else: fall_counter 0 # 一旦没有跌倒就清零 if fall_counter FALL_THRESHOLD: trigger_alarm() fall_counter 0FALL_THRESHOLD按帧率定25fps 下 5 帧约 0.2 秒能过滤掉大部分瞬时误报又不会漏掉真实跌倒。如果摄像头帧率低比如 10fps阈值可以降到 3。4.3 嵌入式部署前要做的模型导出如果最终要部署到 RK3588、Hi3516 这类嵌入式平台需要把.pt导出成 ONNX 或 RKNN。先导 ONNXyolo export modelruns/fall/exp1/weights/best.pt formatonnx imgsz640导出后得到一个.onnx文件再用各平台自己的转换工具转成板端格式。导出时imgsz必须和训练时一致否则精度会掉。嵌入式部署的坑在于后处理YOLOv8 的输出解码逻辑要自己实现建议先在 PC 上用 ONNXRuntime 跑通再上板。5. 跌倒检测训练避坑五个血泪教训5.1 现象训练 mAP 很高实际推理全是误报原因数据集里fall和person的拍摄场景太单一比如全是一个房间、一个角度模型学到了背景而不是人体姿态。解决训练前把数据按场景分组确保验证集里有训练集没见过的房间和角度如果 mAP 在验证集上还行但换场景就崩说明泛化不够需要补数据。5.2 现象fall 类召回率始终低于 0.5原因fall实例太少或者标注框把跌倒的人框得太紧只框了躯干没框到腿模型学不到完整姿态。解决检查标注跌倒框应该包含整个人体如果fall只有几百个用 mosaic 和 copy-paste 增强扩充或者把person类下采样让两类比例接近 1:2。5.3 现象训练 loss 正常但验证 loss 震荡原因batch太小或者学习率默认值不适合小数据集。解决把batch提到显存允许的最大值或者显式降学习率lr00.001默认 0.01 对微调偏大。震荡严重时加warmup_epochs5让前期稳定。5.4 现象导出的 ONNX 推理结果和 PyTorch 对不上原因导出时没指定opset或者后处理里 anchor 解码写错。解决导出加opset12然后在 PC 上用同一张图分别跑 PyTorch 和 ONNX逐框对比坐标差超过几个像素就查解码逻辑。YOLOv8 是 anchor-free 的解码和 YOLOv5 不一样别照抄旧代码。5.5 现象CPU 训练慢到无法接受原因imgsz和batch在 CPU 上开销成倍放大。解决CPU 训练把imgsz降到 416 或 320batch降到 4 到 8model用yolov8nepochs先跑 30 看趋势。CPU 只适合验证流程真正训练还是得上 GPUGTX 1660 Ti 这种级别的卡跑yolov8n一百个 epoch 也就几小时。6. 把跌倒检测精度再往上推一档的实用技巧模型跑通之后真正决定能不能上线的是误报和漏报的平衡。我一般会做两件事一是用yolo detect val拿到每个类的最优置信度阈值而不是拍脑袋定 0.4二是把检测结果和简单的姿态规则结合比如跌倒框的宽高比如果接近 1:1 甚至更宽才认为是真跌倒站着的人框通常是高大于宽。# 在验证集上找最优阈值 yolo detect val modelruns/fall/exp1/weights/best.pt datadataset/data.yaml验证输出里会给出不同 conf 下的 P、R、mAP挑一个fall召回不低于 0.9 且精确率还能接受的阈值。如果找不到说明模型本身不行回去补数据比调阈值有用。另一个技巧是类别权重。YOLOv8 训练时如果fall样本远少于person可以在data.yaml同级加一个hyp.yaml调cls损失权重但更简单的做法是直接在数据集层面复制fall样本让两类数量接近。我试过把fall复制三倍召回率从 0.72 提到 0.88代价是精确率掉了几个点但跌倒检测里这个交换是划算的。最后说个习惯每次改完数据集或参数别只看最终 mAP一定把confusion_matrix.png打开看一眼。我有一次 mAP 涨了但fall被误判成person的比例也涨了差点上线才发现。跌倒检测这活儿指标好看不等于能用盯着混淆矩阵和实际视频抽帧看比什么都靠谱。希望帮到你。本文还有配套的精品资源点击获取
返回列表