biglam/greetings-from-postcards
Greetings From! — historical postcard address transcription 500 handwritten address regions cropped from the backs of historical picture postcards sent within and between Belgium, France, Germany, Luxembourg, the Netherlands and the UK. Each region carries a human-corrected ground-truth transcription, the HTR output it was corrected from, and GPT-4 structured address extractions run over both. Created by Thomas Smits, Wouter Haverals, Loren Verreyen, Mona Allaert and Mike… See the full description on the dataset page: https://huggingface.co/datasets/biglam/greetings-from-postcards.
Greetings From! — historical postcard address transcription
500 handwritten address regions cropped from the backs of historical picture postcards sent within and between Belgium, France, Germany, Luxembourg, the Netherlands and the UK. Each region carries a human-corrected ground-truth transcription, the HTR output it was corrected from, and GPT-4 structured address extractions run over both.
Created by Thomas Smits, Wouter Haverals, Loren Verreyen, Mona Allaert and Mike Kestemont for *Greetings from! Extracting address information from 100,000 historical picture postcards* (CHR 2023), and deposited on Zenodo (10.5281/zenodo.10005566).
This repository is a format conversion of that deposit — the same images and transcriptions, cut into one row per postcard.
How the data was produced
The 500 are a random sample from a corpus of ~102,000 postcards hosted on Delcampe, passed through a three-stage pipeline:
Ground truth was made by five human annotators correcting the HTR output, not transcribing from scratch.
The ground truth is address-only
[!WARNING]gt_textis not a full corrected transcription. The annotators systematically corrected only the text carrying geographical address information. *49.4% of ground-truth lines (1,219 of 2,469) carry a `or@` prefix**, marking them as outside that scope — roughly half the ground truth is uncorrected HTR.
The paper states the convention:
So computing CER between gt_text and htr_text over the whole string measures partly against uncorrected HTR, and will understate the real error rate. To reproduce the paper's 7.62%, score only the unprefixed lines:
def address_lines(text):
return [l for l in text.splitlines() if not l.startswith(("*", "@"))]The rule is not absolute — some prefixed lines were corrected anyway. Card 0's addressee reads J Bath in the HTR and *J Buth in the ground truth, so a starred line was edited despite carrying no address information. Treat */@ as "outside the systematic correction pass", not as a guarantee that the line is byte-identical to the HTR output.
Structure
One row per postcard, 500 rows, single train split.
gt_text and htr_text are aligned by construction — the two source archives contain the same 5 composites (byte-identical JPEGs) with the same 100 regions each, so every row's two transcriptions describe the same pixels.
Caveats
The GPT-4 output has no fixed schema. It is free-form LLM output, not structured fields. Across the GT file 17 distinct keys appear; across the HTR file, 27 — including Message, Date, Province, State, Place of Interest, City/Village Name 2, Additional 7. That is why the full output is kept as a JSON string and only the two most consistent fields are lifted into columns. Do not assume gt_city is populated: it is empty wherever GPT-4 did not emit that key.
GPT-4 hallucinates plausible corrections. The paper documents it silently changing Junda to Zundert, and adding France as the country for Courcelles, which is in Belgium. These are LLM outputs, not verified addresses — treat them as a system's predictions, not as ground truth.
Five cards have no GPT-4 record. The deposit's GPT-4 files hold 495 entries for 500 regions. Those five rows have gpt4_order = -1 and empty address fields: c2/region_19, c2/region_89, c4/region_26, c5/region_3, c5/region_84.
The join was reconstructed, not documented. The Order field is not region_index + 1 — because five regions are missing, the offset accumulates unevenly through the sequence. A uniform per-composite shift gets 100% / 70% / 94% / 69% / 81%: close enough to look right, wrong enough to mislabel rows. The alignment here was recovered with a monotonic dynamic-programming match on normalised address tokens, giving exactly 5 skips and an 88% token-match rate at aligned positions against a ~1% rate for shifted controls. It is recomputed at build time and the build aborts if it degrades. It is still an inference, and a handful of the 12% non-matching rows may be misaligned rather than simply cases where GPT-4 emitted a garbled or empty city.
Five cards have no HTR text at all, and five have no ground truth. 472 of the 500 rows carry at least one address-bearing line on both sides — that is the subset usable for a paired transcription comparison. Median length is comparable across the two sides (60 vs 59 characters), as you would expect for a correction pass rather than a re-transcription.
These are address regions, not whole postcards. The crops are YOLOv8-detected address areas from the card backs. Picture fronts are not in the deposit, and neither is any message text outside the address region.
If you go back to the original deposit: the GT PAGE XML carries region-level TextEquiv, but the HTR export does not — its text lives only on TextLine. Reading region-level text on both sides yields 500 silently empty HTR strings. Here both sides are built by joining the line-level text, which reproduces the GT region string exactly.
Language is mixed and unlabelled. Cards span six countries and the deposit carries no per-card language field. Handwriting, spelling and place-name conventions vary accordingly — the paper attributes the relatively high CER to exactly this "hyper-diversity".
Load
from datasets import load_dataset
ds = load_dataset("biglam/greetings-from-postcards", split="train")
# HTR error on the address lines only — the part that was actually corrected
scored = ds.filter(lambda r: r["gt_text"].strip() and r["gpt4_order"] > 0)Licence
CC BY-SA 4.0, following the upstream deposit. Share-alike: anything derived from this and redistributed carries the same licence.
The postcards themselves are held by Delcampe sellers and collectors; the deposit licenses the transcriptions and the cropped regions as distributed. The authors ask that the paper be cited.
Credit
Data created by Thomas Smits (University of Amsterdam), Wouter Haverals (Princeton University), Loren Verreyen, Mona Allaert and Mike Kestemont (University of Antwerp). Note that the Zenodo deposit lists Haverals alone as creator whilst the accompanying paper has five authors; the citation below follows the paper.
Converted and repackaged for the Hub by Daniel van Strien.
@inproceedings{smits2023greetings,
author = {Smits, Thomas and Haverals, Wouter and Verreyen, Loren and
Allaert, Mona and Kestemont, Mike},
title = {{Greetings from! Extracting address information from 100,000 historical picture postcards}},
booktitle = {Proceedings of the Computational Humanities Research Conference (CHR 2023)},
series = {CEUR Workshop Proceedings},
volume = {3558},
pages = {512--529},
year = {2023},
address = {Paris, France},
url = {https://ceur-ws.org/Vol-3558/paper6180.pdf}
}
@dataset{haverals_2023_greetingsfrom,
author = {Haverals, Wouter},
title = {{Greetings From! Historical Postcards Address Transcription Dataset}},
year = {2023},
publisher = {Zenodo},
doi = {10.5281/zenodo.10005566}
}