geocalib-pf-burn
GeoCalib's perspective-field network (Pautrat et al., ECCV 2024), converted to a burn weight pack so it runs inside a Rust application with no Python at runtime.
It answers two questions from one image: how wide is this camera's field of view, and which way is down. Only the network is here — the least-squares solve that turns its fields into camera parameters is a separate native implementation.
This repository exists to distribute one file to one program. It is not a general-purpose release. If you want GeoCalib, take the original: better documented, unmodified, and it includes the parts this omits.
What this is
| File | geocalib_pf.bpk |
| Size | 116,136,452 bytes |
| sha256 | f28f9aeb157cafe84e1cac1ee1fc637536d200c064c750a0340db8c806717afd |
| Input | RGB, dynamic H×W, short edge 320, both edges a multiple of 32 |
| Outputs | up field, up confidence, latitude field, latitude confidence |
| Runtime | burn (CPU) |
What was changed — and one change is not a format change
The weights were not retrained or fine-tuned. Three modifications were applied:
- PyTorch → ONNX, then ONNX → burn
.bpk. Format conversions. - The NMF bases are frozen. This one alters behaviour and is the reason the licence's indication-of-changes requirement is engaged rather than merely acknowledged.
Why the bases had to be frozen
Upstream's NMF2D._build_bases draws torch.rand on every forward pass. The same image
therefore answers differently each time it is asked — measured over 24 runs, up to 1.86° of
horizontal field of view and 2.31° of gravity direction.
That is not a defect in the original, which is used interactively. It is disqualifying for a product: a value that changes when nothing changed cannot be verified against a reference, cached, or shown to a user twice.
So the bases are drawn once from a documented seed (numpy PCG64, 20260805) and embedded in the graph as initializers. The chosen draw was checked to be typical rather than favourable — within 0.3–1.6σ of the unmodified model's own mean on every frame of a 12-frame corpus. The result is bit-identical across process restarts.
The frozen bases are published alongside the pack so the modification is inspectable rather than merely described.
Accuracy, measured on real frames
Validated against real game frames rather than only synthetic ones, because a synthetic corpus proved unrepresentative — it suggested a 1.3–17° low bias that real content does not show.
- First person, known ground truth (id Tech 4,
g_fov 90at 16:9 = 106.26° true): measured 105.27°, an error of **−0.99% **. Gravity within a degree of level on a level camera. - Third person: field of view is tracked correctly — a five-point sweep of a game's own FoV slider returns a monotonic response over 34° — but the absolute value carries several degrees of content-dependent error, because a large foreground character perturbs the perspective cues the network reads. Repeatability at a fixed camera configuration is 0.24°.
Gravity is the more trustworthy output in every scene tested.
Reproducibility, honestly
The ONNX→burn conversion is not byte-reproducible: rebuilding from the same ONNX yields a functionally identical pack with a different digest. Verify against the sha256 above rather than by rebuilding. This repository's file is the canonical artifact, not one instance of many.
Licence and attribution
GeoCalib's code is Apache-2.0; its pretrained weights are CC BY 4.0, and this is a derivative of the weights. Attribution and a statement of modification are therefore required, not optional.
See NOTICE — it carries both, and must accompany redistribution.