--- license: cc-by-4.0 base_model: cvg/GeoCalib tags: - camera-calibration - perspective-fields - burn - onnx library_name: burn --- # geocalib-pf-burn [GeoCalib](https://github.com/cvg/GeoCalib)'s perspective-field network (Pautrat et al., ECCV 2024), converted to a [burn](https://burn.dev) 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](https://github.com/cvg/GeoCalib): 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: 1. **PyTorch → ONNX**, then **ONNX → burn `.bpk`**. Format conversions. 2. **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 90` at 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`](./NOTICE) — it carries both, and must accompany redistribution.