Loading BONES-SEED BVH data#
The BONES-SEED dataset is a publicly available optical motion-capture dataset distributed as BVH files with the SOMA 77-joint skeleton. This page walks through the steps to parse a SEED BVH file and convert it into Kimodo’s internal motion representation.
This is a similar pipeline used by the benchmark to extract ground-truth motions from SEED data (see the benchmark pipeline).
Step-by-Step Conversion#
1. Parse the BVH file#
parse_bvh_motion reads a BVH file and returns local joint rotation matrices, root translation (in meters), and the source frame rate.
from kimodo.skeleton.bvh import parse_bvh_motion
local_rot_mats, root_trans, bvh_fps = parse_bvh_motion(bvh_path)
2. Subsample to 30 FPS#
Kimodo operates at 30 Hz. If the source BVH has a different frame rate (120 FPS for BONES-SEED), subsample by striding:
fps = 30
step = round(bvh_fps / fps)
root_trans = root_trans[::step]
local_rot_mats = local_rot_mats[::step]
3. Convert to the standard T-pose#
The SEED BVH rest pose differs from Kimodo’s canonical T-pose. The to_standard_tpose function remaps the local rotations accordingly and returns both local and global rotation matrices:
from kimodo.skeleton import SOMASkeleton77
skeleton = SOMASkeleton77()
local_rot_mats, global_rot_mats = skeleton.to_standard_tpose(local_rot_mats)
4. Compute Kimodo motion features#
Build the motion feature tensor used by the model. The feature layout is described in Motion representation.
from kimodo.motion_rep import KimodoMotionRep
motion_rep = KimodoMotionRep(skeleton, fps)
feats = motion_rep(local_rot_mats, root_trans, to_normalize=False)
5. Canonicalize (optionally) and recover the motion dictionary#
Canonicalize so that the motion starts at the origin facing +Z, then invert the features back into a full motion dictionary:
can_feats = motion_rep.canonicalize(feats)
motion_dict = motion_rep.inverse(can_feats, is_normalized=False)
motion_dict is a dictionary with keys such as local_rot_mats, global_rot_mats, posed_joints, root_positions, smooth_root_pos, foot_contacts, etc. See Output formats for details on the Kimodo NPZ layout.
Full script#
from kimodo.motion_rep import KimodoMotionRep
from kimodo.skeleton import SOMASkeleton77
from kimodo.skeleton.bvh import parse_bvh_motion
# 1. Parse BVH
local_rot_mats, root_trans, bvh_fps = parse_bvh_motion(bvh_path)
# 2. Subsample to 30 fps
fps = 30
step = round(bvh_fps / fps)
root_trans = root_trans[::step]
local_rot_mats = local_rot_mats[::step]
# 3. Convert to standard T-pose
skeleton = SOMASkeleton77()
local_rot_mats, global_rot_mats = skeleton.to_standard_tpose(local_rot_mats)
# 4. Compute motion features
motion_rep = KimodoMotionRep(skeleton, fps)
feats = motion_rep(local_rot_mats, root_trans, to_normalize=False)
# 5. Canonicalize and get the full motion dictionary
can_feats = motion_rep.canonicalize(feats)
motion_dict = motion_rep.inverse(can_feats, is_normalized=False)