Views
No views yet
.glb animation on
an RPM-style avatar (e.g. Sofia, Avaturn, Rayan) that visually matches the
movement in the video. Quality is measured by a MediaPipe-based pose
similarity score (MP score, 0–100).wham-v18). Ceiling
appears to be driven by the extractor's own accuracy on dance motion, not
by the retargeting stage.video.mp4
│
├─► [extractor] ──► pose sequence (SMPL, 3D joints, or rotations)
│ ├─ WHAM / SMPL-est-X / 4D-Humans / PromptHMR-Vid
│ ├─ GVHMR / TRAM / HybrIK
│ └─ MediaPipe 3D
│
├─► [retarget] ────► bone rotations on Mixamo skeleton
│ ├─ ARP (Auto-Rig Pro) — most used
│ ├─ analytical IK from 3D joints
│ └─ MoCapAnything-style Procrustes+swing
│
├─► [post] ────────► smoothing / correction
│ ├─ SmoothNet
│ ├─ DNO / MotionFix refinement (not tried)
│ └─ learned-correction (static Δ per bone)
│
└─► [avatar bake] ─► final .glb with avatar mesh + animationscripts/dtw_match.py.| # | Approach | MP score | Outcome |
|---|---|---|---|
| 1 | WHAM raw → bone rotations (no post) | 6.4 | broken bind-pose / twist |
| 2 | WHAM + ARP baseline (wham-v6) | 38.6 | OK but shoulders off |
| 3 | WHAM + ARP copy_bone_rest on shoulders (v18) | 39.3 | current champion |
| 4 | GT rendered → ARP mirror-rest (closure sanity) | 17.4 | pipeline loses ~60pt even with perfect input |
| 5 | Learned per-bone static correction Δ | low | 30.5° residual is frame-dependent, can't be static |
| 6 | Analytical IK from 3D joints (shortest-arc) | 0 | axis convention / frame mismatch |
| 7 | MoCapAnything-style IK (Procrustes + swing, temporal warm-start) | not measured | math verified symbolically; visually off because WHAM-derived joints inherit WHAM error |
| 8 | SMPL-est-X → ARP (with hands) | similar | hand mesh clipping unresolved |
| 9 | 4D-Humans / HMR2.0 single-frame HD render | 0 | ViTDet detector failed on workbench renders |
| 10 | Retrieval — MediaPipe + DTW → library lookup | n/a | cluster correct (idle→idles, dance→dances); exact GT not always top-1 |
bone_error_metric.py:poses_body = 23 SMPL-relative rotmats (body joints 1..23)poses_root_world = root rotation in world frametrans_world = root translationverts_cam = 6890 SMPL vertices in camera spacereturn_y_up=True. yup2ydown flips Y-axis
on root rotation and translation only — body-relative rots are frame-independent.poses_body + poses_root_world
directly, not via joint positions.wham-v18 output. Diffusion-based
motion denoising. Expected +5–10 MP. Low risk, well-documented.project_groq_autooptimize.md).scripts/gvhmr_client.py); or PromptHMR-Vid tuning.| Dir | Purpose |
|---|---|
scripts/ | All Python/Blender scripts (77 files). Each targets a specific extractor or stage. See "Key scripts" below. |
extractions/ | Per-extractor output data — {wham,4d-humans,gvhmr,mediapipe,nlf,prompthmr,prompthmr-vid,smplest-x,wham-joints3d}/ subdirs. |
artifacts/ | Generated strategy GLBs playable in ui/strategies.html. Named ${anim}-${extractor}-${strategy}.glb. |
videos/ | 3 test videos: 01-idle.mp4, 02-dance1.mp4, 03-dance2.mp4 (rendered from F_Standing_Idle_001 / F_Dances_001 / F_Dances_005). |
ui/ | Side-by-side comparison HTML (strategies.html). Loads original vs strategy GLB with Babylon.js. |
motion-library/ | Library signatures (library.npz, 119 anims × 12 joints × T frames, body-local normalised) + per-video MediaPipe signatures + match results. |
mocapik/ | GLBs from MoCapAnything-style IK experiment (procrustes + swing, baked on Avaturn). |
docs/ | This README. |
autorig/ | Auto-Rig Pro paid addon binaries (pinned versions). Private backup — do not redistribute. See autorig/README.md. |
wham_to_joints3d.py — convert WHAM pkl → per-frame 3D joint JSON.fourdh_to_json.py — same for 4D-Humans.hybrik_client.py, gvhmr_client.py — HTTP clients for remote extraction services.extract_video_signature.py — MediaPipe → 12-joint body-local npz.extract_library_signatures.py — Blender batch extractor for Mixamo library GLBs.arp_retarget.py — Auto-Rig Pro retargeting (champion path). Supports --mirror-target-rest for closure tests.mocapanything_ik.py — Procrustes + swing IK from 3D joints. §3.5 of arxiv 2512.10881.joints3d_to_animation.py — shortest-arc IK (failed, score 0).smpl_to_rpm_retarget.py, sofia_source_retarget.py, retarget_fk.py, rokoko_retarget.py, blender_retarget.py — alternative retargeters.apply_hybrik_correction.py, hybrik_calibration.py — HybrIK-specific post.bone_error_metric.py — per-bone quaternion angular error GT vs extracted.closure_test.py — GT → our JSON format → compare; validates pipeline correctness.learn_correction.py — attempt to learn static per-bone Δ (failed, 30.5° residual).compare_extraction.py, compare_mocap.py, compare_rotations.py — various side-by-side comparators.dtw_match.py — DTW matching with motion-energy penalty (fix for idle-bias).
Results:
01-idle → M_Standing_Idle_002 (cost 0.25, correct cluster)02-dance1 → F_Dances_006 (cost 0.80, GT was F_Dances_001)03-dance2 → M_Dances_003 (cost 0.75, GT was F_Dances_005)render_animated_avatar.py — HD render avatar + animation via workbench engine.render_wham_mesh.py, render_smpl_verts.py — render raw extractor output (no retarget).pip install mediapipe opencv-python numpy joblib.1# 1. Extract library signatures (one-time, ~3 min for 121 GLBs)
2blender -b -P scripts/extract_library_signatures.py -- \
3 --lib-dir <path-to-rpm-library> --out motion-library/library.npz
4
5# 2. Extract video signature
6python3 scripts/extract_video_signature.py \
7 --video videos/02-dance1.mp4 \
8 --out motion-library/videos/02-dance1.npz \
9 --model <path-to>/pose_landmarker_heavy.task
10
11# 3. Match
12python3 scripts/dtw_match.py \
13 --library motion-library/library.npz \
14 --video motion-library/videos/02-dance1.npz \
15 --subsample 3 --top-k 10 --mode dtw
16
17# 4. MoCapAnything IK from WHAM joints (alternative path)
18blender -b -P scripts/mocapanything_ik.py -- \
19 --avatar <path-to>/avaturn.glb \
20 --joints extractions/wham-joints3d/02-dance1-joints3d.json \
21 --out mocapik/02-dance1-wham-mocapik-arp.glbtests/ml-mocap/{extern,humor,synsp,video2anim,data}/,
excluded to keep repo size down. Fetch from:pose_landmarker_heavy.task (MediaPipe) — https://storage.googleapis.com/mediapipe-models/pose_landmarker/pose_landmarker_heavy/float16/latest/pose_landmarker_heavy.taskbasicModel_neutral_lbs_10_207_0_v1.0.0.pkl) — https://smpl.is.tue.mpg.de/scripts/.
External test videos and Mixamo-derived GLBs retain their original licenses.