HumanML3D 与 motion-latent-diffusion 代码介绍
Posted 长虹剑
tags:
篇首语:本文由小常识网(cha138.com)小编为大家整理,主要介绍了HumanML3D 与 motion-latent-diffusion 代码介绍相关的知识,希望对你有一定的参考价值。
这两份代码都跑通了,大概记录一下关键点代码
HumanML3D
目前的疑惑点在系数的全局旋转,是在是搞不清楚。
raw_pose_processing.py
amass_to_pose: 这个函数主要就是把系数转成了3D关键点,并且对于关键点做一个绕着x轴顺时针90度的旋转
。
生成文件带有M的,是做了动作的镜像。
motion_representation.py
uniform_skeleton: 这个函数主要就是对齐骨骼,tgt 这个是随便从数据集里面找到一个然后把所有的初始位置都对齐到这里。
# 对齐缩放,也就是平移
scale_rt = tgt_leg_len / src_leg_len
# print(scale_rt)
src_root_pos = positions[:, 0]
tgt_root_pos = src_root_pos * scale_rt
# 之后就是求系数,重新求出 joints
skeleton.py 这个里面是重点
get_offsets_joints: 这个就其实定义了骨架的结构,即偏离父节点的长度和方向(一般都是横平竖直的),前向的时候就是用这个旋转。
inverse_kinematics_np:
一、这里面先计算人体的朝向,
1)先通过肩膀和胯下,计算向量,这两个向量是直接相加,作为身体’水平方向’
2)竖直方向用 [0,1,0], 叉积算出朝前的方向 forward
【疑问】对于躺下的动作,应该直接就会有问题
二、然后计算出 [0,0,1] 到 forward 的旋转,作为root 旋转
三、接下来该算每一个关节的旋转。
t2m_raw_offsets: 这个其实记录了,后一(子)节点相对于当前节点的标准旋转
当去除掉全局+父旋转时,就是local 旋转。
TIPS: 解释一下这里IK的本质,其实就是当给定标准pose后,稠密点IK的计算方式。因此IK也分多种情况:1)给定稠密点,求出相对标准姿态的骨骼系数 2)给定叶节点,求出相邻跟骨骼的合适位置
quat_params 里面存储的就是各个骨骼旋转的系数。
接下来继续 motion_representation.py
【1】选择一个样本,获得骨骼的长度,进行IK。最终对齐(tgt)骨骼系数,然后得到新的关键点坐标
【2】接着就认为整个序列的最低点在地面上,然后放置在地面上
【3】按照第一帧的XZ坐标,进行对齐
【4】接着算出第一帧旋转的值,然后把人给转正
【5】根据脚的移动速度算出是否接触地面(经验值)
【6】然后计算,速度,和角速度
【7】计算joint相对位置(对齐到x,z),并且转正。然后计算 height,和转正之后骨骼点的位置
【8】一些额外的特征,然后joint velocity 还是有个root 旋转,其实应该就是顺便记录下全局位置
【9】后面的代码展示了回复的步骤
这里面再分析一下速度的计算
'''XZ at origin'''
root_pos_init = positions[0] # pos 只做到步骤[2],这里选择了序列的第一帧
root_pose_init_xz = root_pos_init[0] * np.array([1, 0, 1]) # 这里是记录下第一帧的hip位置
positions = positions - root_pose_init_xz # 以第一帧hip为原点,对齐所有的点
# forward_init 是第一帧朝前的向量
target = np.array([[0, 0, 1]])
root_quat_init = qbetween_np(forward_init, target) # 计算和标准朝向的差距,注意这里本质上一个逆
root_quat_init = np.ones(positions.shape[:-1] + (4,)) * root_quat_init # 扩展一下
positions = qrot_np(root_quat_init, positions) # 其实就是把第一帧给转正了,其他的修正一下
# root_quat = qbetween_np(forward, target) # 最开始是个逆? 转正的旋转
r_rot = quat_params[:, 0].copy() # 因此这个本质上是个逆? 这个非常重要
'''Root Linear Velocity'''
velocity = (positions[1:, 0] - positions[:-1, 0]).copy()
velocity = qrot_np(r_rot[1:], velocity) # 这一步具体意义不明,主要就是还考虑了个root绝对旋转。
# 强行理解就是,让(x,y)位置还能保留角度信息
'''Root Angular Velocity'''
r_velocity = qmul_np(r_rot[1:], qinv_np(r_rot[:-1])) # 就是获得相对旋转
# position:局部坐标 + 转正
ric_data = positions[:, 1:].reshape(len(positions), -1)
local_vel # 其实也是带有旋转的
# root_rot_velocity (B, seq_len, 1)
# root_linear_velocity (B, seq_len, 2)
# root_y (B, seq_len, 1)
# ric_data (B, seq_len, (joint_num - 1)*3)
# rot_data (B, seq_len, (joint_num - 1)*6)
# local_velocity (B, seq_len, joint_num*3)
# foot contact (B, seq_len, 4)
接下来就是如何从 data 数据中恢复骨骼
recover_root_rot_pos:这个就是恢复 root 的位置(r_pos)和y轴旋转。
recover_from_rot:利用 r_pos 和 系数 进行 forward 获得最终的 关键点.
recover_from_ric:之前的 ric 已经转正了,现在需要
以上是关于HumanML3D 与 motion-latent-diffusion 代码介绍的主要内容,如果未能解决你的问题,请参考以下文章