No LiDAR, no stereo rig. This product turns an ordinary fixed camera into a metric 3D sensor by self-calibrating height, tilt, and focal length purely from the boxes of people already walking through the scene, then reports metric position, speed, and height for anything it tracks. Pure Python (numpy/scipy) math, no GPU, and no model weights involved. Most feed-forward monocular 3D work assumes a moving camera, where the baseline between frames is what makes triangulation possible. Fixed CCTV inverts that: the camera never moves, so there is no baseline, but the person walking through frame is not noise, it is the thing an operator actually wants measured. Scale instead comes from people of known, tightly distributed height acting as a running calibration target.
bench_results.json) from
fixedcam3d.cli bench --seed 0. Reproduced fresh for this update: the full test
suite (python -m pytest) printed 27 passed in 8.55s, and re-running
the bench command reproduced the published RMSE and sensitivity numbers digit for digit, on
2026-07-09.run_bench function the 3-point sweep uses, across 42 height/tilt
combinations, seed 0, run fresh in this session. Same code, same math, wider sweep, disclosed
as an extension below.| camera (truth) | position RMSE | position p90 | speed MAE | height MAE |
|---|---|---|---|---|
| 3 m, 20° tilt (hard case) | 4.30 m | 5.77 m | 0.353 m/s | 0.038 m |
| 5 m, 30° tilt | 0.16 m | 0.23 m | 0.083 m/s | 0.056 m |
| 8 m, 45° tilt | 0.19 m | 0.22 m | 0.076 m/s | 0.078 m |
Pick a metric, then click any cell. Each cell is one full run of the real self-calibrate-then-localize-then-speed pipeline against a synthetic scene at that mounted height and tilt (seed 0, 80 calibration walkers, 60 evaluation points, focal length scaled with height the same way the shipped 3-point sweep does). Darker red is worse (higher error or more sensitivity); green is better.
Click a cell to see its full measured detail.
The 3 m / 20 degree configuration is a genuinely ill-conditioned geometry for single-camera self-calibration: a shallow viewing angle makes far-field distances fragile even when the calibration residual itself is low. The calibrator's own diagnostic output flags exactly that, in the field the pipeline writes for every run:
"shallow/ill-conditioned geometry, low residual but far-field distances are fragile; treat positions beyond mid-scene as approximate"
We keep that configuration in the headline sweep, in the same table as the two easy cases,
rather than dropping it as an outlier. The calibration's own sensitivity metric
(sensitivity_m_per_half_deg in src/fixedcam3d/calibration.py) makes the
mechanism visible: it perturbs the recovered camera tilt by half a degree and measures how far the
median foot point's ground position moves in response. That is a real conditioning probe, not a
confidence score bolted on afterward: the optimizer can converge to a low residual while still
recovering a tilt that is off by a few degrees, and the residual alone cannot see that failure
mode. In the grid above, watch how sensitivity climbs sharply as tilt drops toward 15 to 20
degrees at low camera heights, exactly where position RMSE also blows up, the same conditioning
problem showing up in two different measured quantities.