Aerial Film Restorer
Measured-fidelity restoration of scanned historical aerial survey film. Mid-century aerial archives reach the reader as flattened, patchworked mosaics โ per-plate exposure steps, vignette haze, lost local contrast, film grain, the accumulated damage of print, storage and scanning. This model reverses that damage without inventing a pixel of content, and โ unusually for the genre โ its fidelity is a measured quantity: every number and every image on this card comes from held-out photograph pairs with professionally-produced ground truth that the training never saw.
Bourges, IGN survey flight (1950s) โ a held-out pair. Left: the raw scanned mosaic as archives publish it, a plate seam running through the medieval fabric. Middle: this model โ the seam is gone and the city reads street by street. Right: the professionally cleaned orthophoto IGN produced from the same photographs, the ground truth every number on this card is measured against.
The measured claim
Restoration models usually argue with adjectives. This one argues with three numbers, each an energy ratio against ground truth where 1.00 means exactly what the negative holds, evaluated on 40 reserved pairs (mean ยฑ s.e., shown here on the 22 pairs additionally unseen by checkpoint selection):
| axis | value | meaning at 1.00 |
|---|---|---|
| detail on structure | 1.02 ยฑ 0.03 | every real edge as sharp as truth โ no smoothing, no fake acutance |
| detail in flat film | 1.07 ยฑ 0.05 | grain neither amplified nor scrubbed |
| large-scale tone | 1.01 ยฑ 0.07 | the ground's own tonal variation preserved โ no "uniform grey" |
The known failure modes of naive training โ aliased targets that manufacture sharpness, adversaries that trade grain for punch, losses that flatten tone โ were each identified by measurement and removed. What remains restores, and only restores.
Bordeaux โ likewise held out. Vignette haze lifts into street-level legibility; every roofline stays exactly where the film put it.
Warsaw, June 1944 โ a wartime reconnaissance print (GUGiK archival aerial), fully outside the training distribution: no historical Warsaw imagery has ground truth. The scan is shown AS SCANNED โ before any correction; the target annotations are part of the print's face and are treated as content. The window is cropped to the photograph, as the limitations advise โ off-white mount paper counts as content to the no-evidence shield.
Warsaw city centre, 4 November 1944 โ after the city's fall, during its systematic razing. Captured German reconnaissance film (US National Archives, RG 373, public domain by age), orthorectified by the Warsaw Rising Museum. The scan as scanned โ the model: the blotched exposure evens and block after block of roofless shells becomes individually legible โ the record of the destruction, made readable without one invented pixel.
Warsaw, 1951 โ the reconstruction-era survey (City of Warsaw open data, ยฉ m.st. Warszawa) at whole-city zoom, the native mosaic as scanned: dozens of survey plates, each with its own exposure. The patchwork resolves into one continuous city โ including across the river โ while every block stays what the film recorded.
Processing aerials
pip install -r requirements.txt
python inference.py scan.tif restored.png # the model
python inference.py scan.tif restored.png --weights model-prof.safetensors
As a library, over a folder:
import glob
import numpy as np
from PIL import Image
from inference import load_model, read_image, restore
net = load_model("model.safetensors") # picks cuda / mps / cpu itself
for path in sorted(glob.glob("archive/*.tif")):
out = restore(net, read_image(path)) # float32 [0,255], input-sized
Image.fromarray(out.astype(np.uint8)).save(path.replace(".tif", "-restored.png"))
What the machinery does for you, and what it expects of you:
- Input: single-channel film imagery, ~0.4โ13 m/px, any size โฅ 64 px.
read_imagehandles 8-bit and 16-bit files (PIL'sconvert("L")clips 16-bit scans โ use the provided reader) and reduces colour to luminance. - Five channels from one image: the model wants registered 2ร/4ร context views; they are built from the input's own block-mean pyramid, tiled on a 256 px lattice, Hann-blended. 256 is the model's contract โ it was trained and validated at this window; there is no tile-size knob on purpose.
- No-evidence shield (on by default): black voids and blown margins are detected, filled from nearest valid content for the model's eyes only, and returned verbatim in the output. Nothing is invented outside coverage. Off-white scan paper and mounts are in-range and count as content โ crop scans to the photograph, or mask processing to the image face.
- Throughput: ~0.4 MPix/s on Apple-silicon MPS (a 1024ยฒ frame in ~3 s); CUDA is faster, CPU workable for single frames. Memory is bounded by the fixed tile โ arbitrarily large frames stream through.
- Determinism: same input, same output; the shipped
tests.py(pytest) pins the geometry, the shield, and the small-input path.
Two checkpoints
| file | sha256 | profile (structure/grain/tone) | character |
|---|---|---|---|
model.safetensors |
9dfdd1a1โฆ |
1.02 / 1.07 / 1.01 on unseen pairs | the model โ at truth on every axis |
model-prof.safetensors |
11cac467โฆ |
0.97 / 1.03 / 1.08 on unseen pairs | gentler variant: slightly softer, lowest saturation โ prefer for very bright or fragile material |
Intended use and honest limitations
- It restores; it does not invent. Saturated regions stay saturated โ the training deliberately under-represents saturation so the model never learns to hallucinate content into no-evidence areas.
- Trained on panchromatic survey film (France 1947โ65 ground truth; Swiss 1946 and modern Polish orthophoto content; degradations calibrated against a 1935โ1994 municipal archive). Colour imagery: restore luminance, carry chroma separately.
- Below ~0.8 m/px no film ground truth exists anywhere; behaviour there is extrapolation and should be judged by eye.
- Scan mounts and paper margins that are not saturated white count as content โ the no-data shield catches voids and blown regions, not off-white paper (median ~247 in the prints we examined).
- A single tonal step wider than the model's context (~4ร the tile, ~1 km at 1 m/px) crossing textureless ground โ open water, blank fields โ may survive partially; ordinary plate patchwork resolves fully, and through textured ground even large seams dissolve (see the Bourges panel).
- Outputs are derivatives of the input imagery: the source's terms and credits apply to them unchanged, and no rights are claimed in restored pixels. If you serve restored imagery, label it as machine-restored and keep provenance (model, weights hash, date) โ the transparency posture this model ships under (cf. EU AI Act art. 50).
Training data and attribution
| source | role | licence |
|---|---|---|
| IGN France โ raw scans + BD ORTHOยฎ Historique 1950โ1965 | the paired ground truth | Licence Ouverte / Etalab 2.0 |
| swisstopo โ SWISSIMAGE HIST 1946 | fine-scale film content | swisstopo open data |
| GUGiK (Poland) โ Warsaw orthophoto 2025 | content at working scales | Polish geodetic open data, art. 40a(2) |
Architecture: NAFRestore, this project's own implementation in the NAFNet family โ 17.32M parameters, five-channel multi-view input, trained from scratch (no pretrained initialization; there is no base model). Architecture reference: Chen, Chu, Zhang, Sun, Simple Baselines for Image Restoration, ECCV 2022 (arXiv:2204.04676; megvii-research/NAFNet, MIT).
Licence
- Weights: CC-BY-4.0. Use them for anything, including commercially; credit "Aerial Film Restorer โ the Powidok project (powidok.waw.pl), CC-BY-4.0" and indicate modifications (e.g. fine-tuning).
- Code (
model.py,inference.py,tests.py): MIT (LICENSE-CODE).
What these panels show, exactly
Every output here is the bare model via the shipped inference.py โ no
contrast grading, no sharpening. Faithful restoration is deliberately
conservative: 1.00 means the negative, not a poster. In our own deployment a
solved per-layer contrast normalization and a labelled presentation-sharpening
pass ride on top of the model; anything similar is a downstream choice this
release leaves to you.
Provenance
The model was developed for Powidok, an interactive historical map of Warsaw 1935โ1951 โ currently under construction โ where it restores a fourteen-layer aerial fleet; the measurement methodology (reserved-pair evaluation with standard errors, selection-bias checks, deployment gauntlets) comes from that project's training record.
Citation
Grzybek, J. (2026). Aerial Film Restorer: measured-fidelity restoration of
historical aerial survey film. The Powidok project, https://powidok.waw.pl
(model: https://huggingface.co/jan-grzybek/aerial-film-restorer)
- Downloads last month
- 9




