Download debug_seq.py from zirobtc/vr-hmr: direct link, hf CLI and curl.
- Browser
- Download file 4.64 kB
-
https://huggingface.co/zirobtc/vr-hmr/resolve/main/debug_seq.py
- Command line
-
hf download hf://zirobtc/vr-hmr/debug_seq.py
-
curl -L -o debug_seq.py https://huggingface.co/zirobtc/vr-hmr/resolve/main/debug_seq.py
4.64 kB
| import os | |
| import json | |
| import numpy as np | |
| import torch | |
| from scipy.spatial.transform import Rotation as R | |
| from hmr4d.utils.smplx_utils import make_smplx | |
| def test_kabsch(): | |
| input_dir = "/mnt/c/Temp/SyntheticDataset" | |
| seqs = ["sequence_100_biboo_birthday_speech_explosion_1.jsonl", "sequence_101_biboo_birthday_speech_explosion_2.jsonl"] | |
| device = "cuda" | |
| model = make_smplx("supermotion").to(device).eval() | |
| fix_rot = R.from_euler("z", 180, degrees=True).as_matrix() | |
| C = np.diag([1.0, -1.0, 1.0]) | |
| C4 = np.diag([1.0, -1.0, 1.0, 1.0]) | |
| fix_mat = np.eye(4); fix_mat[:3, :3] = fix_rot | |
| for seq in seqs: | |
| p = os.path.join(input_dir, seq) | |
| with open(p, "r") as f: lines = f.readlines() | |
| row = json.loads(lines[1]) # frame 0 | |
| # parse unity | |
| R_cam_w = R.from_quat(row["cam_rot_world"]).as_matrix() | |
| R_pel_w = R.from_quat(row["pelvis_rot_world"]).as_matrix() | |
| R_rel_unity = R_cam_w.T @ R_pel_w | |
| R_cv = C @ R_rel_unity @ C | |
| R_final = R_cv @ R.from_euler("z", 180, degrees=True).as_matrix() | |
| go_c = R.from_matrix(R_final).as_rotvec().astype(np.float32) | |
| pelvis_cam_cv = np.asarray(row["smpl_incam_transl"], dtype=np.float64).reshape(3) | |
| root_cam_cv = np.asarray(row.get("smpl_root_incam_transl", [0.0, 0.0, 0.0]), dtype=np.float64).reshape(3) | |
| pelvis_cam_cv = pelvis_cam_cv # + np.array([0.0, -0.02, 0.0], dtype=np.float64) | |
| target_cam_cv = pelvis_cam_cv | |
| R_cam_w_cv = fix_rot @ (C @ R_cam_w @ C) | |
| R_pelvis_w_cv = R_cam_w_cv @ R_final | |
| go_w = R.from_matrix(R_pelvis_w_cv).as_rotvec().astype(np.float32) | |
| pos_cv_raw = (C @ row['pelvis_pos_world']) | |
| pelvis_pos_w_cv = fix_rot @ pos_cv_raw | |
| pose = np.asarray(row["smplx_pose"], dtype=np.float32) | |
| body_pose = pose[3:66].astype(np.float32) | |
| betas = np.zeros(10, dtype=np.float32) | |
| # compute pel0 | |
| with torch.no_grad(): | |
| bt = torch.from_numpy(betas[None]).to(device) | |
| bp = torch.from_numpy(body_pose[None]).to(device) | |
| go_c_t = torch.from_numpy(go_c[None]).to(device) | |
| pel0_c = model(betas=bt, global_orient=go_c_t, body_pose=bp).joints[0, 0].cpu().numpy() | |
| go_w_t = torch.from_numpy(go_w[None]).to(device) | |
| pel0_w = model(betas=bt, global_orient=go_w_t, body_pose=bp).joints[0, 0].cpu().numpy() | |
| tr_c = target_cam_cv - pel0_c | |
| tr_w = pelvis_pos_w_cv - pel0_w | |
| # math check | |
| R_c_v = R.from_rotvec(go_c).as_matrix() | |
| R_w_v = R.from_rotvec(go_w).as_matrix() | |
| R_w2c_v = R_c_v @ R_w_v.T | |
| j0_c = pel0_c + tr_c | |
| j0_w = pel0_w + tr_w | |
| t_w2c_derived = j0_c - R_w2c_v @ j0_w | |
| cam_T_wc = np.eye(4) | |
| cam_T_wc[:3, :3] = R_cam_w | |
| cam_T_wc[:3, 3] = row["cam_pos_world"] | |
| cam_T_wc_cv = fix_mat @ (C4 @ cam_T_wc @ C4) | |
| T_w2c_exported = np.linalg.inv(cam_T_wc_cv) | |
| # Kabsch verify manually | |
| T_c2w_exported = np.linalg.inv(T_w2c_exported) | |
| with torch.no_grad(): | |
| tr_c_t = torch.from_numpy(tr_c[None]).to(device) | |
| j_c = model(betas=bt, global_orient=go_c_t, body_pose=bp, transl=tr_c_t).joints[0, :22].cpu().numpy() | |
| tr_w_t = torch.from_numpy(tr_w[None]).to(device) | |
| j_w = model(betas=bt, global_orient=go_w_t, body_pose=bp, transl=tr_w_t).joints[0, :22].cpu().numpy() | |
| src_mean = j_c.mean(axis=0) | |
| dst_mean = j_w.mean(axis=0) | |
| X = j_c - src_mean | |
| Y = j_w - dst_mean | |
| H = X.T @ Y | |
| U, _, Vt = np.linalg.svd(H) | |
| R_align = Vt.T @ U.T | |
| if np.linalg.det(R_align) < 0: | |
| Vt[-1, :] *= -1 | |
| R_align = Vt.T @ U.T | |
| t_align = dst_mean - src_mean @ R_align | |
| T_c2w_kabsch = np.eye(4) | |
| T_c2w_kabsch[:3, :3] = R_align | |
| T_c2w_kabsch[:3, 3] = t_align | |
| t_err = np.linalg.norm(T_c2w_kabsch[:3, 3] - T_c2w_exported[:3, 3]) | |
| print(f"[{seq}]") | |
| print(f" t_err: {t_err:.3f}m") | |
| print(f" t_c2w_kabsch: {T_c2w_kabsch[:3, 3]}") | |
| print(f" T_c2w_exported: {T_c2w_exported[:3, 3]}") | |
| print(f" diff(kabsch - exported): {T_c2w_kabsch[:3, 3] - T_c2w_exported[:3, 3]}") | |
| print(f" t_w2c_derived: {t_w2c_derived}") | |
| print(f" T_w2c_exported: {T_w2c_exported[:3, 3]}") | |
| print(f" delta_T_w2c (derived - exported): {t_w2c_derived - T_w2c_exported[:3, 3]}") | |
| if __name__ == "__main__": | |
| test_kabsch() | |