Skip to content

Optimize PoseVisualizer.draw (~10x faster, simpler)#229

Merged
AmitMY merged 2 commits into
masterfrom
optimize-pose-visualizer
Jun 23, 2026
Merged

Optimize PoseVisualizer.draw (~10x faster, simpler)#229
AmitMY merged 2 commits into
masterfrom
optimize-pose-visualizer

Conversation

@AmitMY

@AmitMY AmitMY commented Jun 23, 2026

Copy link
Copy Markdown
Collaborator

What

visualize_pose was running at ~20 fps. Profiling the draw path showed ~75% of time in numpy MaskedArray element indexing — the per-point person[i+idx] lookups and point[:2] slicing in point_to_xy, each of which walks __array_finalize__/_update_from/view.

Changes to _draw_frame

  • Resolve all coordinates to plain rounded ints once per frame instead of indexing the masked array millions of times.
  • Vectorize per-component point-color computation (was a per-component @lru_cache closure rebuilt every frame).
  • Collect draw ops as lightweight tuples instead of dicts; same single z-sort (painter's algorithm) preserved.
  • Remove a leftover print() inside the limb loop.

Results

Measured on a 799-frame 256×256 pose:

fps
draw path before 18.7
draw path after 190

End-to-end visualize_pose: ~40s → ~5s.

Correctness

  • All 4 visualization_test.py tests pass; ruff clean.
  • Rendered frames are identical to the old output up to 1 color-value of anti-aliasing rounding on 0.5% of pixels (from averaging int colors).
  • draw_on_video (plain-array path) and FastAndUglyPoseVisualizer (overrides _draw_frame) unaffected.

🤖 Generated with Claude Code

AmitMY and others added 2 commits June 23, 2026 07:08
The draw path spent ~75% of its time in numpy MaskedArray element
indexing (per-point `person[i+idx]` and `point[:2]` lookups). Resolve
all coordinates to plain ints once per frame, vectorize per-component
color computation, drop the per-component lru_cache closure, and remove
a leftover debug print in the limb loop.

Draw path on a 799-frame 256x256 pose: 18.7 -> 190 fps. End-to-end
visualize_pose: ~40s -> ~5s. Output frames are identical up to 1
color-value of anti-aliasing rounding.

Co-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com>
Precompute static connectivity (limb index pairs, color palettes) once
in __init__ instead of rebuilding them every frame, and replace the
per-point/per-limb Python color and depth averaging with vectorized
numpy over each component. Only the cv2 draw calls remain per-op.

Draw path: 190 -> 240 fps. Output unchanged (frames identical to the
prior commit). Remaining time is dominated by OpenCV's anti-aliased
line rasterization of the face-mesh tessellation.

Co-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com>
@AmitMY AmitMY merged commit 31fee0f into master Jun 23, 2026
8 checks passed
@AmitMY AmitMY deleted the optimize-pose-visualizer branch June 23, 2026 05:23
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.

1 participant