image
VincentWei

天地间,浩然正气长存,为天地立心,为生民立命,为往圣继绝学,为万世开太平!

免责声明:网站内容仅供个人学习记录,禁做商业用途,转载请注明出处。

版权所有 © 2017-2020 NEUSNCP个人学习笔记 辽ICP备17017855号-2

多人跳绳智能计数系统

VincentWei    2026年6月10日 17:49:23

多人跳绳智能计数系统设计文档

1. 文档概述

1.1 系统目标

本系统旨在基于计算机视觉技术,实现对视频中多名人员同时进行跳绳计数的自动化处理。系统融合了目标检测、姿态估计、多目标跟踪、数字信号处理及状态机逻辑,能够应对遮挡、绊脚、暂停、人员进出画面等复杂场景,并通过 WebSocket 实时推送计数结果。

1.2 核心特性

  • 多人并发追踪:改进的 DeepSORT 算法,结合骨骼点与外观特征,支持多人同时跳绳计数。

  • 鲁棒的计数逻辑:基于卡尔曼滤波、Savitzky-Golay 平滑与峰值检测的信号处理,配合五阶段状态机(就绪、计数、暂停、遮挡、绊脚)。

  • 防误判机制:包含身体倾斜检测、摇绳姿势校验、节奏突变检测,以及 READY/PAUSED 超时重置机制

  • 全局身份绑定:跨跟踪器 ID 的全局身份映射,防止因跟踪丢失导致计数重置。

  • 实时数据推送:内置异步 WebSocket 服务器,实时广播计数状态。


2. 系统架构设计

系统采用模块化流水线架构,数据单向流转,整体分为五个核心模块:

  1. 视频预处理模块:负责视频解码、降帧、仿射变换与 ROI 裁剪。

  2. 目标跟踪模块:基于 YOLOv8-Pose 检测,结合改进的 DeepSORT 进行多目标追踪。

  3. 独立计数模块:单人的信号处理与状态机演进,输出跳绳次数与频率。

  4. 数据输出模块:WebSocket 实时推送与历史数据持久化。

  5. 主系统编排模块:协调各模块,处理全局身份映射(GID)与视频渲染输出。


3. 模块详细设计

3.1 视频预处理模块

  • 类名VideoPreprocessor

  • 职责:消除视频背景干扰,矫正透视畸变,控制帧率以降低计算负荷。

  • 核心逻辑

    • 降帧策略:根据源视频 FPS 与目标 FPS(默认30),计算帧间隔 frame_interval,仅处理整除帧。

    • 仿射变换:若配置 affine_params,调用 cv2.warpAffine 矫正画面倾斜。

    • ROI裁剪:提取感兴趣区域,自动校正坐标越界问题。

    • 帧生成器stream_frames() 以生成器模式 yield (frame_idx, processed_frame),节省内存。

3.2 改进的DeepSORT跟踪模块

  • 类名Track, ImprovedDeepSORT

  • 职责:在 YOLO 检测基础上,维持跨帧的人员身份,解决短暂遮挡后的重关联。

3.2.1 Track (单目标轨迹)

  • 维护目标的 BBox、关键点、外观特征(HSV 直方图)、中心点历史。

  • 集成 cv2.KalmanFilter (4维状态[x, y, vx, vy], 2维观测[x, y]) 预测下一帧中心位置。

  • 静止判定is_stationary() 判断最近10帧中心位移是否小于阈值,用于区分跳绳者(原地不动)与走动者。

3.2.2 ImprovedDeepSORT (跟踪器)

  • 轻量级外观提取:截取 BBox 区域,Resize至32x64,计算 HSV 直方图并归一化为512维向量。

  • 代价矩阵计算 (_compute_cost_matrix):

    • 高 IoU 优先:若 IoU > 0.3,直接采用 IoU 代价,跳过复杂计算。

    • 静止目标约束:若目标静止且预测中心与检测中心距离>50,拒绝匹配。

    • 多特征融合:代价 = $\alpha \times \text{外观代价} \times 100 + (1 - \alpha) \times \text{骨骼点运动代价} + \text{中心距离代价}$。其中 $\alpha$ 由关键点置信度动态决定。

  • 数据关联:使用匈牙利算法 (scipy.optimize.linear_sum_assignment) 解决二分图匹配。

  • 生命周期管理:未匹配检测创建新 Track,未匹配轨迹 missing_frames 累加,超过 max_missing(90帧) 删除。

3.3 独立计数与信号处理模块

  • 类名PersonJumpCounter

  • 职责:针对单人进行跳绳动作的信号提炼、特征校验与状态管理。

3.3.1 信号处理管线

  1. 关键点时序滤波:对17个关键点分别建立双卡尔曼滤波器(x, y独立),置信度<0.3时采用预测值,平滑抖动。

  2. 质心提取:取左右髋关节(11,12)的Y坐标均值作为身体质心高度 raw_y

  3. 归一化:滑动窗口(60帧)计算均值与标准差,进行 Z-Score 归一化,消除不同身高及距离带来的幅度差异。

  4. 平滑去噪:应用 Savgol 滤波器(窗口7,3阶多项式)。

  5. 倒相寻峰:因跳绳起跳时Y坐标减小,对信号取反,使用 find_peaks 提取波峰,要求最小峰距为5帧,峰度使用动态自适应阈值。

3.3.2 辅助校验机制

  • 身体倾斜检测 (_check_body_tilt):左右肩/髋部Y坐标差异归一化后>0.15视为倾斜(排除侧身走动误判)。

  • 摇绳姿态检测 (_check_holding_rope_posture):

    • 计算手腕相对髋部的Y偏移历史。

    • 判据:偏移方差足够大(手在动)、过零率>=1(手在上下挥动)、摆幅满足最低要求。

  • 节奏中断检测 (_is_rhythm_break):最近波峰间隔与历史均值间隔偏差超过±60%/40%视为节奏破坏。

3.3.3 状态机设计

系统定义了5个状态,转换规则如下:

当前状态 触发条件 下一状态 动作
READY 检测到连续2次有效波峰,且幅度/膝角满足启动阈值 COUNTING 累加 pending_peak_framesjump_count
READY 停留在 READY 超过 ready_pause_timeout(10s) READY 清零所有计数与历史,重新计时
COUNTING 检测到有效波峰 COUNTING jump_count++,记录节奏间隔
COUNTING 物理幅度低于最小阈值 / 波峰超时 PAUSED 可能执行回退减3操作 _retract_last_jump
COUNTING 节奏突变或身体严重倾斜 STUMBLED 回退上一次计数,记录绊脚开始帧
PAUSED 幅度恢复且达到重启阈值(1.3x) COUNTING 恢复计数
PAUSED 停留在 PAUSED 超过 ready_pause_timeout(10s) READY 清零所有计数与历史
STUMBLED 绊脚状态持续15帧以上 PAUSED/READY 若有过计数去PAUSED,否则去READY
任意 关键点可见率<0.3 OCCLUDED 暂停逻辑,清空部分历史
OCCLUDED 关键点恢复可见 PAUSED 若之前在COUNTING则回退计数

★ 核心修改点:引入 _set_state 统一记录状态进入帧号,并在 _check_ready_pause_timeout 中实现了超时重置逻辑,避免人员长时间站在画面中发呆导致的历史数据污染。

3.4 数据输出模块

  • 类名DataOutputManager

  • 职责:将内存中的计数状态实时推送至前端,并落盘历史记录。

  • 机制

    • 主线程调用 update_state 更新最新快照。

    • Daemon 线程运行 asyncio 事件循环,维持 WebSocket 服务器。

    • 以固定频率(push_interval,默认2Hz)向所有连接的客户端广播 JSON 数据。

    • 处理结束后,调用 export_history 将全量帧记录写入 jump_history.json

3.5 主系统编排模块

  • 函数名run_rope_counting_system

  • 职责:串联所有模块,处理业务闭环。

3.5.1 全局身份映射

由于 DeepSORT 的 Track ID (TID) 在目标长时间丢失后会消亡,再次出现会分配新 TID。为维持跳绳计数的连续性,设计了 GID (Global ID) 映射机制:

  1. 维护 tracker_to_gid (TID -> GID) 和 gid_last_info (GID最后出现的信息)。

  2. 当出现新 TID 时,遍历已丢失的 GID:

    • 计算中心点距离代价与外观直方图距离代价。

    • 若 GID 处于 COUNTING 状态,施加更严格的距离惩罚。

  3. 若最小代价 < 200,复用该 GID;否则分配新 GID。

  4. 对于超过600帧未更新的 GID,执行内存清理。

3.5.2 渲染与输出

  • 根据 GID 状态渲染不同颜色的 BBox 与文本:

    • COUNTING (绿), PAUSED (黄), READY (橙), STUMBLED (红), OCCLUDED (紫)

  • 同步写入 cv2.VideoWriter 输出结果视频,并调用 cv2.imshow 实时预览。


4. 数据结构设计

4.1 WebSocket 推送数据格式

{
  "timestamp_ms": 12345,
  "frame_idx": 370,
  "persons": {
    "1": {
      "id": 1,
      "total_jumps": 25,
      "state": "COUNTING",
      "frequency_jpm": 76.2
    },
    "2": {
      "id": 2,
      "total_jumps": 0,
      "state": "READY",
      "frequency_jpm": 0.0
    }
  }
}

*(注:frequency_jpm 算法为:过去10秒内跳跃次数 * 6,且需满足至少2次跳跃及持续时间超过1秒)*

4.2 核心队列尺寸限制

变量名 长度限制 用途
center_history 30 判定人员是否静止
raw_y_history 300 存储原始质心高度序列
norm_y_history 300 存储归一化后的高度序列
knee_angle_history 300 存储膝角变化序列
wrist_offset_history 30 摇绳手势判定窗口
recent_peak_amplitudes 5 动态自适应峰度阈值计算
rhythm_intervals 10 节奏突变判定窗口

5. 关键算法参数配置说明

参数 默认值 作用
target_fps 30 视频降帧目标值,影响信号采样的时间分辨率
max_missing 90 跟踪器允许目标消失的最大帧数 (约3秒)
ready_pause_timeout_sec 10 READY/PAUSED 状态超时重置时间 (秒)
dynamic_min_amplitude max(2.5, bbox_size*0.02) 动态计算的最小物理振幅,随目标远近自适应
kf_center processNoiseCov 0.5 跟踪器中心点卡尔曼滤波过程噪声
kf_group processNoiseCov 0.5/5.0 关键点卡尔曼滤波过程噪声 (位置/速度)
adaptive_threshold max(0.1, mean*0.35) 寻峰算法的峰度自适应阈值

6. 系统执行流程图


7. 部署与运行约束

  1. 模型依赖:运行目录下需包含 yolov8n-pose.pt 权重文件。

  2. 批量处理__main__ 入口默认扫描 cloud/*.mp4 目录下的视频进行批量处理,结果视频在原名后追加 _vis.mp4

  3. 并发模型:UI渲染与算法推理在主线程同步执行,WebSocket 服务器在独立 Daemon 线程异步运行。

  4. 中断机制:实时预览窗口按 q 键可中断当前视频处理。

最近更新: 2026年6月10日 17:56:23
浏览: 1.4K

[[total]] 条评论

添加评论
  1. [[item.time]]
    [[item.user.username]] [[item.floor]]楼
  2. 点击加载更多……
  3. 添加评论