Skip to main content
SCAR icon

SCAR

Satellite-based Calibration for Aerial Recordings

SCAR refines the intrinsics of an aerial camera and its extrinsics relative to a GNSS/INS from the recording itself: it matches the images against georeferenced orthophotos, lifts the matches to 3D anchors with a surface model and optimizes a factor graph (GTSAM) over cameras, anchors and the calibration. No calibration target or ground control points are needed.

You provide images with timestamps, INS poses, an initial calibration and reference data:

  • Germany: official orthophotos and DSMs of the federal states supported by georaffer (NRW, RLP, BW, BY, BB, ...) are downloaded on demand.
  • Anywhere else: your own orthophoto and surface model as GeoTIFF/COG/VRT in any CRS (e.g. NAIP + 3DEP in the US, national mapping data, your own survey), or your own reference provider.

Frame cameras and event cameras (as reconstructed frames) are supported. The paper version is kept frozen as the preset cvprw2026 and the tag v1.0.0-cvprw2026.

Installation

SCAR needs Python 3.11+.

git clone https://github.com/hlzmnhnry/scar.git && cd scar
pixi install            # environment with GTSAM, pyproj, rasterio, georay (CPU only)
pixi install -e gpu     # + PyTorch/CUDA, learned matchers (vismatch), georaffer, rerun viewer

With pip: pip install -e ".[references,matching,viewer]" (add germany for German state data). georay renders the reference views. The germany extra adds georaffer.

Quick start

A complete run on a synthetic flight with local GeoTIFF reference data, CPU only and without downloads:

pixi run python examples/custom_region_geotiff/make_demo_data.py examples/custom_region_geotiff/demo
pixi run scar run examples/custom_region_geotiff/config.yaml
pixi run python examples/custom_region_geotiff/make_demo_data.py --compare examples/custom_region_geotiff/demo

For your own flight:

scar init my_flight.yaml --template csv     # or: ltc, event
scar check my_flight.yaml --render          # time coverage, CRS, reference availability, footprint overlays
scar run my_flight.yaml --viewer            # collect anchors and optimize, live view in rerun
scar reproject my_flight.yaml --every 50    # reference points projected with initial and calibrated result
scar export runs/my_flight/calibration/calibration.yaml --format kalibr --output camchain.yaml

scar reproject shows calibrations on the images: reference points, matched as during collection (or --source anchors: the anchors of the run), projected with the pose priors, next to the reference view, the legend gives the median error and the mean offset per calibration. By default it compares the initial and the calibrated result, --calibration takes any others (also camera and extrinsics files, --calibration old=camera.json,extrinsics.json), --vector-scale magnifies the offsets and --save writes the images instead of opening a window.

scar collect and scar optimize run the two steps separately, scar evaluate scores a calibration on anchors of an independent test sequence (reprojection error, optionally visual localization), and scar anchor-noise estimates how precise the collected anchors are by matching tracked observations against the reference data again. See examples/ for an LTC campaign; scar init --template event starts an event camera setup.

Data

  • LTC dataset (Leaving the City, ECCV 2026): the full aerial recordings with INS data and calibrations, licensed under CC BY 4.0. SCAR reads the campaign folders directly (scar init my_ltc.yaml --template ltc). Images are distributed in archives (<campaign>_images/<index>.png), meta/image_shards.csv lists which frames each archive contains.

  • SCAR evaluation data: the subset used in the paper (per campaign every 10th image of the training and test segments, camera.csv, ins.csv) is available here. Put a campaign folder at data/<campaign>/ and run, e.g. for 2022-10-19:

    pixi install -e gpu
    pixi run -e gpu scar run examples/ltc_quickstart/config.yaml
    

    The configuration needs the GCG2016 quasigeoid (see examples/README.md), reference tiles are downloaded automatically. For the other campaigns copy the configuration and set the campaign and the time window from paper/cvprw2026/campaigns.yaml.

If you use LTC data, please also cite the LTC paper.

Inputs

All inputs are described in one YAML file, the templates in scar/config/templates document every option.

Input Format
Images CSV with timestamp and path, a directory of files named by timestamp, or LTC camera.csv
Poses CSV with geodetic (lat, lon, height) or projected positions in any CRS, quaternion or Euler orientation w.r.t. NED or ENU, optional per-sample accuracies
Calibration SCAR YAML, Kalibr camchain or LTC camera.json/extrinsics.json, pinhole with radial-tangential distortion
Reference data georaffer regions (Germany) or local orthophoto and DSM rasters

Poses are interpolated to the image timestamps (linear position, SLERP rotation), optionally with a time offset. The conventions for frames, heights, datums and the meridian convergence are described in docs/coordinate_systems.md, please read it before using your own data.

Images are selected in one time window (selection.start/end) or in several selection.segments. A few short segments with different headings (ideally opposite ones) and altitudes constrain the calibration better than one long straight leg: on a single heading a boresight error cannot be told apart from a world-fixed offset of positions or reference data. scar check --matches N matches a few frames per segment and shows whether the terrain gives enough anchors, anchors are not tracked across segments. With large image motion between frames, collect.settings.tracking_config.forward_backward_threshold_px: 1.0 drops tracks that lag behind, for test anchors seconds apart, switch tracking off (tracking: false, collect_every_nth_frame: 1). scar evaluate leaves out observations that project behind the camera or far outside the image, and --offsets those with gross errors.

Outputs

A run directory contains the anchors (anchors.json), the per-stage results (calibration/stages.json), the final calibration with the marginal covariance of the intrinsics (calibration/calibration.yaml) and, with --viewer, a rerun recording. scar export writes Kalibr, OpenCV and LTC formats.

Optimization presets

Preset Description
default Staged schedule of the paper (rotation, translation, landmarks, calibration, full) followed by a robust least-squares fit of the extrinsics (frames whose pose estimate failed do not pull the result), use with the corrected pose processing (default of all templates)
cvprw2026 Frozen paper configuration, together with paper/cvprw2026 it reproduces the published results
joint Experimental: extrinsics as a variable of the factor graph instead of the least-squares fit

Reproducing the paper

paper/cvprw2026 contains the scripts, campaign definitions and initial calibrations of the CVPRW 2026 evaluation, the reproduction log and an ablation of geodetic corrections that were not part of the paper version (float32 coordinates, meridian convergence, heights, interpolation). The meridian convergence correction alone lowers the test reprojection error by 21 % on average over the six LTC campaigns. anchor_noise_ltc.py estimates the anchor noise of an LTC sequence, the empirical counterpart of the landmark prior.

Development

pixi run test           # unit, synthetic and system tests, regression tests need local LTC data
pixi run -e repro test  # bit-exact paper regression with GTSAM 4.2.0

Citation

If you use SCAR in academic work, please cite:

@InProceedings{Holzemann_2026_CVPR,
    author    = {H\"olzemann, Henry and Schleiss, Michael},
    title     = {SCAR: Satellite Imagery-Based Calibration for Aerial Recordings},
    booktitle = {Proceedings of the IEEE/CVF Conference on Computer Vision and Pattern Recognition (CVPR) Workshops},
    month     = {June},
    year      = {2026},
    pages     = {987-996}
}

Reference data obtained through georaffer are subject to the licenses of the respective providers (e.g. NRW: dl-de/zero-2.0, RLP: dl-de/by-2.0), SCAR does not redistribute them.

Metadata

Release files for scar-calib 2.2.0

For a detailed explanation of source distributions (sdists) and built distributions (wheels), please see the package formats documentation.

Source distribution (sdist)

Source distribution for scar-calib 2.2.0
File Size Uploaded Provenance Actions
scar_calib-2.2.0.tar.gz 86.4 kB With provenance Details for scar_calib-2.2.0.tar.gz

Built distribution (wheel)

Table of built distributions (wheels) for scar-calib 2.2.0
File Interpreter ABI Platform Actions
scar_calib-2.2.0-py3-none-any.whl Python 3 none any Details for scar_calib-2.2.0-py3-none-any.whl

Total release size: 189.4 kB

Release files / scar_calib-2.2.0.tar.gz

Download URL scar_calib-2.2.0.tar.gz
Size 86.4 kB
Tags Source
SHA-256 checksum
How to use checksums
f5c4fededa7c90d2aab665ad244e4f2e45ba00c0ef05e26c7525ce7dbe39b5b1
BLAKE2b-256 checksum
How to use checksums
17b5b262aa33ac0f6e5b8428ed1480ea35d63568899ced62bd9408e76db29069
Upload date
Uploaded using Trusted Publishing?
What is trusted publishing?
Yes
Uploaded via twine/7.0.0 CPython/3.13.16

Provenance

Provenance describes where a file came from. On PyPI, provenance is shared via attestations, which provide a verifiable record of the build or publishing details. View details, limitations and caveats.

PyPI Publish Attestation

PyPI verified that this artifact, at this checksum, originated from the publisher listed below.

Signed by GitHub Actions, verified by PyPI on Oct 20, 2026.

Transparency log

Release files / scar_calib-2.2.0-py3-none-any.whl

Download URL scar_calib-2.2.0-py3-none-any.whl
Size 103.0 kB
Tags Python 3
SHA-256 checksum
How to use checksums
cc6e4935dbf101c07a3e6957cb803fa7bec3192f8f745f89e624595fb318f0f8
BLAKE2b-256 checksum
How to use checksums
131606040af09e019168e91181a202f610173cfefdb87dc60add1b17be0116e6
Upload date
Uploaded using Trusted Publishing?
What is trusted publishing?
Yes
Uploaded via twine/7.0.0 CPython/3.13.16

Provenance

Provenance describes where a file came from. On PyPI, provenance is shared via attestations, which provide a verifiable record of the build or publishing details. View details, limitations and caveats.

PyPI Publish Attestation

PyPI verified that this artifact, at this checksum, originated from the publisher listed below.

Signed by GitHub Actions, verified by PyPI on Oct 20, 2026.

Transparency log

Security for scar-calib 2.2.0

Provenance

Provenance describes where a file came from. On PyPI, provenance is shared via attestations, which provide a verifiable record of the build or publishing details. View details, limitations and caveats.

Full provenance

All 2 files in this release have been uploaded with provenance metadata.

Select from 2 files

Attestation for scar_calib-2.2.0.tar.gz

PyPI Publish Attestation

PyPI verified that this artifact, at this checksum, originated from the publisher listed below.

Signed by GitHub Actions, verified by PyPI on Oct 20, 2026.

Transparency log

A note on package security

PyPI is a repository for distributing packages, not a service for auditing them. While third-party security researchers and our staff do their best to detect and remove malicious packages, PyPI cannot guarantee the quality, security or suitability of any given package.

To learn more about protecting yourself from malicious actors, visit our package security documentation.

Anthropic, PBC Visionary sponsor Bloomberg Visionary sponsor Hudson River Trading Visionary sponsor Meta Visionary sponsor NVIDIA Visionary sponsor Microsoft Sustainability sponsor Depot Continuous Integration AWS Cloud computing and Security Sponsor Datadog Monitoring Fastly CDN Google Download Analytics Sentry Error logging StatusPage Status page