Skip to content

People on stage and camera motion, read off the video - #382

Merged
alexarje merged 8 commits into
masterfrom
stage-performer-count
Sep 12, 2026
Merged

alexarje merged 8 commits into
masterfrom
stage-performer-count

Conversation

@alexarje

@alexarje alexarje commented Sep 12, 2026

Copy link
Copy Markdown
Contributor

Summary

Two new modules, exported from the package root.

_performers

  • detect_people(video, fps=1, width=640, model="yolo11n.pt", ...): person boxes per sampled frame via an ffmpeg pipe and YOLO (ultralytics extra), normalised coordinates, GPU when torch sees one.
  • on_stage(box): keeps boxes whose heads are in the upper half of the frame and drops audience members cut off by the bottom edge.
  • people_track / performer_count(detections, start_s, end_s, camera=None): how many perform in a span. Without camera analysis, a high percentile of per-frame counts (the wide shots). With it, one count per framing (see below), the widest framing being the estimate.

_camera

  • camera_motion(video): each sample of a 2 fps proxy labelled still / moving / cut from ORB matches and a partial-affine RANSAC fit; returns cuts, shots and the time share per state. make_proxy, camera_state_at, still_runs (framings) alongside.

Validated on an IMV concert recording with an operated camera (14% of the time moving, 25 cuts): the framing rule is exact for a solo pianist, a guitar/bass duo and a five-piece band, where the frame percentile counted 10 for the band and a per-shot median 4; a 17-voice choir comes out as 7, which the docstrings state.

Test plan

  • tests/test_performers.py: stage filter on real box geometries, audience exclusion, the wide-shot percentile, span bounds, and a smoke test of detect_people that skips without weights/network.
  • tests/test_camera.py: synthetic footage with a static scene, a pan and a cut → states, cut time, shots, framings, camera_state_at; performer_count per framing ignores the swing past a crowd.
  • mypy notes from the first CI run addressed.

🤖 Generated with Claude Code

https://claude.ai/code/session_01PcjBSXbXjqdj1tmYHoLiKd

alexarje and others added 2 commits September 12, 2026 21:40
A person detector on a concert video finds the audience too: heads and shoulders
in the lower part of the frame, cut off by the bottom edge. Performers are on a
raised stage, so their heads are in the upper half, and that one geometric fact
separates the two well enough to count a soloist, a duo and a five-piece band from
an operated camera. The camera moves, so no frame shows everyone; the span
statistic is a high percentile of per-frame counts, the wide shots, reported with
the median and maximum so the framing's variation is visible.

`detect_people` samples the video at a low rate through an ffmpeg pipe and runs
YOLO (the existing `ultralytics` extra); `on_stage` is the filter; `people_track`
and `performer_count` summarise. A choir is under-counted, which the docstring says.

Co-Authored-By: Claude Fable 5.1 <noreply@anthropic.com>
Claude-Session: https://claude.ai/code/session_01PcjBSXbXjqdj1tmYHoLiKd
An operated camera pans, tilts and zooms, and a multi-camera edit cuts between
angles; both inflate frame-difference measures and change who is in the picture.
`_camera.camera_motion` labels each sample of a small 2 fps proxy still, moving or
cut from ORB matches and a partial-affine RANSAC fit between consecutive frames,
and returns cuts, shots and the share of time in each state; `still_runs` gives the
framings, the still runs between moves and cuts, and `camera_state_at` samples the
state so motion measures can leave camera motion out.

`performer_count(..., camera=)` counts per framing: the 75th percentile of each
framing's per-frame counts, the widest framing being the estimate. That is what
makes the count right with a moving camera: the percentile over all frames took the
audience in the band's wide shot for two more performers, and a per-shot median
took the dominant close framing for the band. Also the mypy notes from CI.

Co-Authored-By: Claude Fable 5.1 <noreply@anthropic.com>
Claude-Session: https://claude.ai/code/session_01PcjBSXbXjqdj1tmYHoLiKd
@alexarje alexarje changed the title People on stage, counted from the video People on stage and camera motion, read off the video Sep 12, 2026
@alexarje
alexarje merged commit 6419726 into master Sep 12, 2026
11 of 12 checks passed
@alexarje
alexarje deleted the stage-performer-count branch September 12, 2026 21:47
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