| """MEI 138D rendering: SMPL-H mesh with skeleton overlay. |
| |
| Pipeline: |
| 1. Recover joint positions (for skeleton + camera) |
| 2. Recover SMPL-H mesh vertices from MEI features |
| 3. Render mesh with pyrender (shared camera from joints) |
| 4. Overlay skeleton on mesh images |
| """ |
|
|
| import numpy as np |
|
|
| from .recovery import recover_joint_positions |
| from .representation import mei_to_smplh |
| from ..tools.render_skeleton import ( |
| get_smpl22_chains, |
| render_skeleton_frames, |
| compute_camera_params, |
| ) |
| from ..tools.smplh import ( |
| load_smplh_model, |
| get_J0, |
| smplh_forward, |
| LEFT_HAND_MEAN_AA, |
| RIGHT_HAND_MEAN_AA, |
| ) |
| from ..tools.render_mesh import render_mesh_frames |
|
|
|
|
| def _recover_mesh(motion): |
| """Recover SMPL-H mesh vertices from MEI 138D features. |
| |
| Uses neutral gender and betas=0 (uniform body shape), consistent |
| with the joint recovery pipeline. |
| |
| Args: |
| motion: (T, 138) denormalized MEI features. |
| |
| Returns: |
| verts: (T, 6890, 3) mesh vertices. |
| faces: (F, 3) triangle indices. |
| """ |
| T = motion.shape[0] |
|
|
| |
| out = mei_to_smplh(motion.astype(np.float64), fps=30.0) |
| root_orient = out["root_orient"].astype(np.float32) |
| body_pose = out["body_pose"].astype(np.float32) |
| transl_abs = out["transl"].astype(np.float32) |
|
|
| |
| lh = np.tile(LEFT_HAND_MEAN_AA, (T, 1)) |
| rh = np.tile(RIGHT_HAND_MEAN_AA, (T, 1)) |
| poses_aa = np.concatenate([root_orient, body_pose, lh, rh], axis=-1) |
| poses_aa = poses_aa.reshape(T, 52, 3) |
|
|
| |
| gender = "neutral" |
| betas = np.zeros(16, dtype=np.float32) |
| model = load_smplh_model(gender) |
|
|
| |
| J0 = get_J0(model, betas) |
| transl = transl_abs - J0[None, :] |
|
|
| |
| verts = smplh_forward(model, gender, betas, poses_aa, transl) |
| faces = model["f"] |
|
|
| return verts, faces |
|
|
|
|
| def render_frames(motion: np.ndarray) -> list: |
| """Render 138D MEI motion features to image frames. |
| |
| Renders SMPL-H mesh with skeleton overlay on top. |
| |
| Args: |
| motion: (T, 138) denormalized MEI features. |
| |
| Returns: |
| list of np.ndarray images (H, W, 3), uint8. |
| """ |
| |
| joints = recover_joint_positions(motion) |
|
|
| |
| verts, faces = _recover_mesh(motion) |
|
|
| |
| cam_params = compute_camera_params(joints) |
|
|
| |
| mesh_images = render_mesh_frames(verts, faces, cam_params) |
|
|
| |
| return render_skeleton_frames(joints, get_smpl22_chains(), canvas_images=mesh_images) |
|
|