fairmotion进阶技巧:如何计算关节角速度与姿态相似度,3步读懂Velocity类原理
【免费下载链接】fairmotionTools to load, process and visualize motion capture data项目地址: https://gitcode.com/gh_mirrors/fa/fairmotion
fairmotion 是一个用于加载、处理和可视化动作捕捉(motion capture)数据的开源 Python 工具库,支持 BVH、AMASS 等多种数据格式。本文聚焦它的进阶核心能力:如何计算关节角速度、如何计算姿态相似度,并用 3 个步骤读懂Velocity类的工作原理,帮你把运动数据真正"用起来" 🎯
fairmotion 的可视化模块可以直接把 BVH 骨骼动画渲染出来,配合速度、相似度计算,从"看动作"到"分析动作"只差一步。
为什么需要关节角速度与姿态相似度?
光看姿态(每帧的关节旋转)远远不够:
- 动作流畅度判断要看"动得多快",即关节角速度(angular velocity)和线速度(linear velocity);
- 动作匹配/过渡(比如舞蹈编排、游戏动作切换)需要量化两个姿态"有多像",即姿态相似度度量。
fairmotion 把这两件事封装成了两个轻量模块:
| 能力 | 所在文件 |
|---|---|
| 关节角速度 / 线速度计算 | fairmotion/core/velocity.py |
| 姿态相似度计算 | fairmotion/core/similarity.py |
| 旋转矩阵 ↔ 轴角等转换工具 | fairmotion/ops/conversions.py |
3步读懂Velocity类原理
Velocity类定义在 velocity.py,它接收两个姿态pose1、pose2和时间间隔dt,为骨架中每一个关节算出一组 6 维向量:前 3 维是角速度w,后 3 维是线速度v。
第1步:用两帧姿态差求出旋转与位移
核心在Velocity.compute方法中:
- 取关节在两帧中的变换矩阵
T1、T2; - 计算相对变换
T1⁻¹ · T2,拆出相对旋转dR和相对位移dp; - 用
R2A把旋转矩阵转成轴角向量(axis-angle,向量模长 = 旋转角度),再除以时间间隔。
w, v = R2A(dR) / dt, dp / dt # 角速度、线速度就这么简单:角速度 = 旋转轴角 ÷ dt,线速度 = 位移 ÷ dt。结果同时保留了两套坐标系:data_local(关节局部坐标系,适合分析关节动作本身)和data_global(世界坐标系,适合分析整体运动方向)。
第2步:用 get_angular / get_linear 按关节取速度
拿到Velocity对象后,按关节名查询即可:
w = vel.get_angular("left_hip", local=True) # 左髋关节角速度 v = vel.get_linear("root", local=False) # 根节点线速度两个方法都支持传入R_ref参数,把速度向量旋转到任意参考坐标系下比较——这是后面做相似度计算的关键细节 ⚡
第3步:用 MotionWithVelocity 全序列预计算 + 任意时刻插值
逐帧手动计算太麻烦,MotionWithVelocity直接继承Motion,一键完成全序列速度预计算:
mv = MotionWithVelocity.from_motion(motion) vel = mv.get_velocity_by_time(3.2) # 任意时刻,自动线性插值get_velocity_by_time会自动在相邻两帧速度之间按Velocity.interpolate做线性插值,所以你可以传入任意浮点时间,不必是整数帧——对动画过渡、慢动作分析非常友好。
如何计算姿态相似度?两种度量按需选择
similarity.py 提供了两个函数,正好覆盖"像不像"的两个层面:
pose_similarity:全关节姿态差异(不看位置,只看动作)
- 逐关节比较局部旋转差(转成轴角后求平方和),再加权比较关节角速度差;
- 默认权重
w_joint_pos=0.9、w_joint_vel=0.1,即"姿态为主、动作为辅"; - 默认开启
apply_root_correction:自动把pose2的根节点朝向对齐到pose1,避免"只是整体转向不同"就被判为不像; - 返回值越小越相似。
root_ee_similarity:根节点 + 末端执行器差异(关注位置与速度)
针对"手在哪、脚在哪、动得多快",由 4 个加权项组成:
| 分量 | 含义 | 默认权重 |
|---|---|---|
| 根节点位置差 | 双脚站立位置差异 | 1.0 |
| 根节点速度差 | 移动快慢差异 | 1.0 |
| 末端执行器位置差 | 手、脚末端差异 | 1.0 |
| 末端执行器速度差 | 末端动得急不急 | 1.0 |
两个贴心设计:
- 差异统一在**各自朝向坐标系(facing frame)**下计算,转向不同不会虚增距离;
auto_weight=True时,按末端执行器的高度自适应加权(越高越重要),让"手的姿态"比"脚的位置"在舞蹈类动作中影响更大。
实战场景:动作图过渡与动作聚类
这两个模块在 fairmotion 内部就有真实用例,可直接参考:
- 动作图(Motion Graph)衔接:motion_graph.py 在比较两段动作的接点时,同时调用
pose_similarity和root_ee_similarity,选出过渡最自然的动作段,实现"动作拼接"; - 动作特征提取与聚类:
fairmotion/tasks/clustering/下的kinetic.py等特征文件大量使用速度信息,把每段动作变成特征向量后聚类降维:
上面这张图就是把动作片段按相似度特征做 t-SNE 降维后的聚类结果——颜色相同的簇代表"动作很像"的片段,这正是相似度度量在数据层面的直观体现。
新手快速上手清单
- 先加载:用
fairmotion/data/bvh.py读取 BVH 文件得到Motion; - 算速度:
MotionWithVelocity.from_motion(motion),之后随时按时间取速度; - 比姿态:两个姿态"动作像不像"用
pose_similarity,"站位/手位像不像"用root_ee_similarity; - 调权重:4 个速度/位置权重可按业务调整,舞蹈调高
w_ee_pos,跑步调高w_root_vel; - 注意单位:角速度单位是 弧度/秒,
dt由Motion.fps自动换算,记得确认帧率正确。
掌握Velocity 类 + 双相似度函数这一套组合,你就拥有了 fairmotion 分析动作数据的"核心三件套",从运动分析到动作过渡都能从容应对 ✅
【免费下载链接】fairmotionTools to load, process and visualize motion capture data项目地址: https://gitcode.com/gh_mirrors/fa/fairmotion
创作声明:本文部分内容由AI辅助生成(AIGC),仅供参考