Skip to content

Multi-view pose fusion, from two scripts that differed by one line - #378

Merged
alexarje merged 1 commit into
masterfrom
pose-fusion
Aug 23, 2026
Merged

alexarje merged 1 commit into
masterfrom
pose-fusion

Conversation

@alexarje

Copy link
Copy Markdown
Contributor

Closes #355.

concert_fuse3d.py and reh_fuse3d.py in the Westney-comparisons study held byte-identical copies of an Umeyama alignment and a visibility-weighted fusion, and differed by a hardcoded list of pieces. That algorithm is now fuse_pose_views(), and the scripts are drivers over it.

It takes extract_pose_landmarks result dicts or plain (world, visibility) arrays, so nothing about it is tied to MediaPipe as a source. It returns the fused skeleton, the per-view rotations and scales, and the cross-view residual per landmark as well as overall.

Verified against the study's own output

Not only against synthetic data. All four concert excerpts, re-fused through the rewritten driver and compared with the committed fused_*.npz:

agreement
keys, NaN pattern identical
residual_mm, t equal to the bit
fused 6e-8 m (float32 storage precision)
view rotations 1e-9

Per-piece residuals unchanged: 139.7, 143.2, 147.7, 151.4 mm.

Two guards the study code lacked

Neither moves a published number.

  1. Reflection. The rotation average projected the mean matrix back with a bare U @ Vt and no determinant check. A mean falling nearer a reflection than a rotation would have mirrored the skeleton silently, swapping its left and right, which nothing downstream would flag. It does not fire anywhere in the concert data, so this is insurance rather than a correction.
  2. Unbounded gap filling. interp_nan's comment said "fill short gaps per coord" while the code filled every gap of any length and held the ends flat, so a long dropout became a straight line through it with nothing marking it. max_gap bounds that now, defaulting to the old behaviour so existing results reproduce.

Testing

Eight tests, all synthetic known-answer — the study data lives outside the repo and is not a dependency. All eight passed on first run, so each guard's test was checked by removing the guard and watching it fail; a check that cannot fail is worth nothing.

mypy musicalgestures/ clean across 70 files. Full suite 714 passed, 4 skipped.

The residual is documented as a consistency measure, not an accuracy one: views that agree closely can agree on a wrong pose.

🤖 Generated with Claude Code

https://claude.ai/code/session_01Xg1f739wddu5M4s3UwdNkn

concert_fuse3d.py and reh_fuse3d.py in the Westney-comparisons study held
byte-identical copies of an Umeyama alignment and a visibility-weighted fusion,
and differed by a hardcoded list of pieces. That algorithm is now
fuse_pose_views(), and the scripts are drivers over it. Closes #355.

It takes extract_pose_landmarks result dicts or plain (world, visibility)
arrays, so nothing about it is tied to MediaPipe as a source, and it returns
the fused skeleton, the per-view rotations and scales, and the cross-view
residual per landmark as well as overall.

VERIFIED AGAINST THE STUDY'S OWN OUTPUT, not only against synthetic data. All
four concert excerpts re-fused through the rewritten driver reproduce the
committed fused_*.npz: identical keys, identical NaN pattern, residual_mm and t
equal to the bit, fused to 6e-8 m, rotations to 1e-9. The residuals are
unchanged at 139.7, 143.2, 147.7 and 151.4 mm.

TWO GUARDS THE STUDY CODE LACKED, and neither moves a published number. The
rotation average projected the mean matrix back with a bare U @ Vt and no
determinant check, so a mean falling nearer a reflection than a rotation would
have mirrored the skeleton silently --- swapping its left and right, which
nothing downstream would flag. It does not fire anywhere in the concert data,
so this is insurance rather than a correction. And interp_nan's comment said
"fill short gaps" while the code filled every gap of any length and held the
ends flat, so a long dropout became a straight line with nothing marking it;
max_gap bounds that now, defaulting to the old behaviour so results reproduce.

Every guard's test was checked by removing the guard and watching the test
fail, because all eight passed on first run and a check that cannot fail is
worth nothing.

The residual is documented as a consistency measure, not an accuracy one:
views that agree closely can agree on a wrong pose.

Co-Authored-By: Claude Opus 5 <noreply@anthropic.com>
Claude-Session: https://claude.ai/code/session_01Xg1f739wddu5M4s3UwdNkn
@alexarje
alexarje merged commit 2a47aed into master Aug 23, 2026
12 checks passed
@alexarje
alexarje deleted the pose-fusion branch August 24, 2026 05:40
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

Multi-view pose fusion (Umeyama alignment + visibility-weighted averaging)

1 participant