Camera cuts and PTZ¶
Camera cuts and pan/tilt/zoom, so that camera motion is not read as performer motion.
An operated camera pans, tilts and zooms, and a multi-camera edit cuts between angles. Both
inflate frame-difference measures (quantity of motion, motiongrams) and change who is in the
picture. This module labels each sample of a video as still, moving or cut from the
global geometry between consecutive frames: ORB features matched across the pair and a
partial-affine (translation + scale) RANSAC fit. Consistent geometry with a shift or a scale
change is a camera move; no consistent geometry together with a large change of the picture
is a cut; the rest is still. Shots are the spans between cuts; framings are the still runs
between moves and cuts, which is the unit that matters when counting people or comparing
motion, because the framing is constant inside one.
The analysis runs on a small, low-rate proxy (2 fps, 180 px high by default), made once with ffmpeg and reused, so a 90-minute recording takes about a minute.
make_proxy ¶
make_proxy(filename, proxy_path, fps=2.0, height=180, ffmpeg_input_args=None)
A low-rate, low-resolution copy of the video (ffmpeg), cached at proxy_path.
ffmpeg_input_args go before -i (["-hwaccel", "cuda"] decodes on the GPU).
Source code in musicalgestures/_camera.py
28 29 30 31 32 33 34 35 36 37 38 | |
camera_motion ¶
camera_motion(filename, proxy_path=None, fps=2.0, height=180, move_px=1.0, zoom=0.005, min_inliers=15, cache=None, verbose=True, ffmpeg_input_args=None)
Per-sample camera state for a video.
Returns a dict with hop_s, t (sample times), state (still / moving / cut),
tx, ty (pixels at proxy scale), scale, inliers, cuts (times), shots
({"start", "end"} between cuts) and summary (share of time in each state). move_px and
zoom are the per-sample translation and scale change that count as a move; both were set on an
operated concert camera and are conservative for a tripod. Pass cache (a JSON path) to reuse.
Source code in musicalgestures/_camera.py
41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 80 81 82 83 84 85 86 87 88 89 90 91 92 93 94 95 96 97 98 99 100 101 102 103 104 105 106 | |
camera_state_at ¶
camera_state_at(cam, times)
The camera state at each time (still when the analysis has nothing there).
Source code in musicalgestures/_camera.py
109 110 111 112 113 114 115 116 117 118 | |
still_runs ¶
still_runs(cam, start_s=0.0, end_s=None, min_s=10.0)
Framings: spans inside [start_s, end_s) where the camera held still for at least min_s.
Source code in musicalgestures/_camera.py
121 122 123 124 125 126 127 128 129 130 131 132 133 134 135 136 137 138 | |