Handwriting recognition tests (2026-11-01)
Question: can a machine read the Bern parish registers well enough to make them searchable (“boil the pond”: download every pre-1800 register of about 40 family parishes, then search the text)?
Short answer: not reliably. Machines can make a rough finding aid (dates, entry structure, name fragments). Every name they produce has to be checked on the page image. No tool tested was right on the names in the hard entries, and some invent text with confidence.
The material
- Source: Staatsarchiv Bern, series K (Reformed parish registers), downloaded as PDFs. See Bern parish registers (Staatsarchiv Bern, series K).
- Scripts: German Kurrent of the 17th and 18th centuries, with Latin formulas and abbreviations (7bris = September, 8bris = October, Wintermonat = November, ex p[er]missione Consistorii).
- The scans are bilevel (pure black and white, no grey), made from microfilm. Faint strokes are lost before any tool sees them. This limits every reader, human or machine.
- Bern used the Julian calendar until 1700, so weekdays given in the text (“uff Frytag den …”) can confirm or correct a date or year.
Test images and ground truth
- Bolligen marriages, 1659–60 (K Bolligen 22, image 40): faded, crowded, many entries struck through, corrections between the lines. Hard.
- Pieterlen baptism, 20 Nov 1757 (K Pieterlen 2, image 149): one entry in a heavy, smeared, slanted hand. Very hard.
Test copies: transkribus-test/1-Pieterlen-1757-Sprunger-baptism.jpg and 2-Bolligen-1659-60-faded-marriages.jpg (sent to Christopher 2026-11-01).
Checkpoints (established by Claude reading the images, confirmed by other records and the calendar):
| # | Image | Truth |
|---|---|---|
| B1 | Bolligen | ”uff Montag den 1. Augusti” 1659 (1 Aug was a Monday only in 1659); Jacob [Schmutziger?] … Maria [?] … “Consistorii Bern” |
| B2 | Bolligen | ”uff Frytag den 23. 7bris Bendicht Zoss und Catharina Stämpfli”, Friday 23 Sep 1659 |
| B3 | Bolligen | ”uff Frytag den 14. 8bris”: Bendicht [?] and Barbara [Zürgi?] |
| B4 | Bolligen | right page: “Volgend der jenigen Eheleuten namen, die von mir Daniel [?], Predicant zu Bolligen, sind yngesegnet worden” |
| P1 | Pieterlen | ”den 20. Wintermonat … Infans Peter” |
| P2 | Pieterlen | ”Par: Conrad Sprunger, [2–3 words unread] … Elsbeth Grober von Sumiswald” (names confirmed by the 1752 marriage, K Pieterlen 2 image 175) |
| P3 | Pieterlen | ”Testes: Peter Grober … Catharina Grober … von Sumiswald” |
Tools tested
| Tool | What it is | Access | Cost |
|---|---|---|---|
| Transkribus (web demo) | Commercial handwriting-recognition platform (READ-COOP); public models include “German Kurrent 16th–18th” by the Bern team | transkribus.org; demo shows ~10 lines, rest needs a free account | free: 5 demo tries; account 50 pages a month |
| Leo (tryleo.ai) | AI transcription service | web | not checked |
Bern TrOCR XVI–XVII: dh-unibe/trocr-kurrent-XVI-XVII | University of Bern Digital Humanities; TrOCR (Microsoft) fine-tuned on ~1.6 M words of 16th–18th-c. Kurrent, biased to Swiss documents (Zurich council minutes, Königsfelden, Einsiedeln). Published test CER 5.4 % | Hugging Face, public, run locally | free |
Bern TrOCR XVI–XIX v2: dh-unibe/trocr-german-kurrent-xvi-xix-from-kurrent-v2 | Same team, broader period; published CER 8.9 % | Hugging Face, local | free |
kraken 7.1.1 (default blla segmenter) | Open-source tool that finds the text lines on a page; the TrOCR models read one line at a time | pip, local | free |
| Claude Opus 5.5 (medium reasoning effort), reading page images directly | Anthropic’s general vision-language model, not trained specifically on Kurrent. Used for most of the register transcription in this vault so far (see below) | Claude Code session; images rendered from the PDFs with zoom.py/crop.py (high-resolution crops of one column or one entry) | part of the Claude subscription; slow per page |
Run locally on an Apple M2 (24 GB) with the Apple GPU (MPS): about one minute per page (128 lines found on the Bolligen page).
Results
| Checkpoint | Transkribus | Leo | Bern TrOCR (whole page, kraken) | Bern TrOCR (lines cut by hand) |
|---|---|---|---|---|
| B1 date | ✓ (no year) | text ✓, year wrong (“1661”) | ✓ | ✓ |
| B1 names | ”Jacob Schmutziger" | "Iacob Kuhnleÿger”, “Maria Franckmied" | "Jacob Schwertziger" | "Jacob Schintziger” |
| B2 date | day ✗ (27) | ✗ “29. Iuni” | ✓ 23. septembris | ✗ |
| B2 names | close: “Bendicht Jose und Catherine Stimpfli” | ✗ “Benedictus Bosch vnd Katharina Stroopsky” | ✗ invented text | partial: “Cathrina S…pli” |
| B3 | ✓ day, “Barbara Zürgi” | ✓ day, “Barbara Fürst” | ✓ day, “Barbara Fürggeren” | — |
| B4 | not shown (behind sign-up) | not shown in screenshot | mostly ✓ (“Volgend derjenigen ehrluten namen … Daniel Himmel predicant zu Bolligen”) | — |
| Latin abbreviations | partly | ✓ expanded (“ex p[er]missio Consistorij”) | partly | — |
| Invented or repeated text | none seen | one entry repeated twice | yes: Zurich phrases not on the page (“landtvogt Heidegger”, “Binzikon”) | — |
| P1–P3 (Pieterlen) | ✗ stray letters only | not yet tested | ✗ invented text (“metzgerknecht von St. Gallen”) | — |
Claude Opus 5.5 (medium effort), reading the images directly: B1–B3 and P1–P3 as in the ground truth, but only after targeted zooming to a single column or entry; it could not read most of the Bolligen page unaided, and the Zoss entry was found with Transkribus’s help.
Claude Opus 5.5 as the main transcriber so far
Most register readings in this vault (2026-10-30 to 11-01) were made by Claude Opus 5.5 at medium reasoning effort, reading page images rendered from the Bern PDFs, for example:
- K Langnau 26, 27 and 36 (marriages 1804–1852; the Anabaptist family register)
- K Mühleberg 1 (Christen Ramseyer’s baptism, 22 Sep 1700)
- K Bolligen 3 and 22 (Gosteli × Zoss children 1660–1676; Bendicht Zoss’s marriage, 1659)
- K Guggisberg 6, K Wahlern (Mast and Mischler searches), K Pieterlen 2 (Peter Sprunger 1757; Conrad Sprunger × Elsbeth Grober 1752)
- Printed sources in old German type (Fraktur), the Burkholder book (1804) from Christopher’s photographs, and English page images
How it works: find the right page with low-resolution strips of the page tops (dates, headings), then render the column or entry at high resolution and read it, recording uncertain words in [square brackets with ?] and saving the crop beside the transcription.
Strengths: reads ordinary 18th- and 19th-century hands well at high magnification; knows the formulas, abbreviations and calendar (7bris, Wintermonat, Julian weekdays), so it can check dates; can reason about context (godparents, places, later records) to settle a doubtful name; says when it cannot read something rather than inventing.
Limits: slow and costly per page (each image is a separate look), so not practical for whole volumes; needs heavy zooming on faint or crowded pages; still misses words in smeared or heavily corrected entries (the words after “Conrad Sprunger” are unread); names are confirmed only when another record agrees. Readings are marked documented only when the image supports them, and uncertain readings are flagged.
Best use alongside machines: a cheap reader (Transkribus, Leo, a Bern model) finds candidate entries across many pages; Claude reads and checks the candidates on the image.
How the Bendicht Zoss marriage was established: Transkribus pointed to the names; the local model got the date (23 September); Claude read the entry on a zoomed image; the Julian weekday check showed that only the 23rd of September 1659 was a Friday. No single tool got it right.
Limitations
- The scans: black-and-white microfilm images lose faint ink; nothing can recover it. Colour scans of the originals (an archive visit or an order) would read better.
- Names are the weakest point for every tool, and names are what genealogy searches on. Dates and formulas come through better.
- Invented text (hallucination): the language-model-based tools (Leo; the TrOCR models) write fluent, plausible text where they cannot read, so errors look as clean as correct readings. Leo’s output looks the most finished and is therefore the most misleading.
- Line-finding (segmentation): on slanted, crowded or smeared pages, kraken breaks lines into fragments, and the reader then fails completely. The models read clean single lines much better.
- Training bias: the Bern models were trained mostly on Zurich and other Swiss official minutes, so they drift into that vocabulary.
- Published accuracy does not transfer: the 3–9 % error rates are measured on hands the models were trained on. On these registers, expect far higher error rates on names.
- Small test: two images, no full-page scoring. These are impressions, not measured error rates.
- Calendar and dating: a tool can read a date and still give the wrong year (Leo). Weekday checks catch some of these.
Recommended approach for the pond
- Run a reader over the core volumes (baptisms and marriages of the ~15 key parishes) to make a rough, searchable index of dates and name fragments, keeping the page and line position of every reading.
- Search it loosely (e.g. “Sprng”, “Gostl”, “Z?ss”, “Ramser”) and by date.
- Read every hit on the image before anything enters the tree.
- To improve: Transkribus with a free account (its names were best); or fine-tune a Bern model on a few dozen pages corrected by hand; or try the whole-page model
b-straub/LightOnOCR-3-1B-Historic-German-Handwriting(trained mainly on 1790s–1900s material; untested here).
Other models found (Hugging Face survey, 2026-11-01)
dh-unibe/trocr-kurrent: 19th-century Kurrent, CER ~2.7 % (for 1800–1875 registers).dh-unibe/kraken-german-xix-v1,dh-unibe/qwen3vl-german-xix-v2: 19th-century line models.dh-unibe/turmbuecher-ner-v1: finds names of people and places in early German text; trained on the Bern Turmbücher (the tower books where Anabaptists were interrogated). Useful for indexing a transcription.b-straub/LightOnOCR-3-1B-Historic-German-Handwriting: reads whole pages, no line-finding; mostly 19th-century training; browser demo available.- Also seen:
fhswf/TrOCR_german_handwritten(modern handwriting) andfgho/trocr-hanse…-kurrent(Hanseatic hands): less suitable.
Files and set-up
- Environment and scripts:
../Family Tree Archive/htr/:venv/(Python 3.11; torch 2.14 with the Apple GPU, transformers 5.12, kraken 7.1.1; 1.3 GB),read_page.py(page → lines → text with x/y positions),line_test.py(reads hand-cut lines with both Bern models),test-bolligen.txt,test-pieterlen.txt(raw outputs). - Models: Hugging Face’s standard cache,
~/.cache/huggingface/hub/models--dh-unibe--…(1.2 GB each). Public; downloaded without an account. - Remove everything: delete the
htrfolder and the twomodels--dh-unibe--…folders.
Next tests
- Leo on the Pieterlen image (P1–P3) task/human
- Leo’s full Bolligen output: check the whole page for Jacob Gosteli × Anna Zoss task/human
- Transkribus with a free account: full Bolligen page task/human
- Try LightOnOCR (whole-page model) locally on both images task/ai
- Score a clearer page (e.g. K Mühleberg 1 p. 225, the 1700 Ramseyer baptism) to see how the tools do on an ordinary hand task/ai
Related
- Anna Zoss (fl. 1665) (the Bendicht Zoss marriage)
- Conrad Sprunger (fl. 1757), Peter Sprunger (1757–1840)
- Bern K Pieterlen 2 - Baptisms Marriages Deaths 1683-1758
Pilot model comparison: Mühleberg 1700 (K Mühleberg 1, image 116), 2026-11-01
Study folder: ../Family Tree Archive/htr-study/ (14 pages cut into 1,193 numbered lines with kraken; this is the first page scored). Each reader got the same 82 line images with no context. Four Claude models ran as separate blind helpers (no access to the reference or the vault). The two Bern models ran locally.
Scored on the 28 lines whose reference is sure or confirmed (496 characters):
| Reader | CER strict | CER loose* | Exact lines | Time |
|---|---|---|---|---|
| Claude Opus 5.5 | 5.0 % | 3.6 % | 24/28 | ~70 s |
| Claude Fable 5.1 | 9.7 % | 3.6 % | 22/28 | ~115 s |
| Claude Sonnet 5.5 | 18.1 % | 16.5 % | 15/28 | ~25 s |
| Bern TrOCR XVI–XIX v2 | 31.0 % | 24.1 % | 8/28 | ~20 s (local) |
| Bern TrOCR XVI–XVII | 45.8 % | 35.7 % | 11/28 | ~20 s (local) |
| Claude Haiku 5.5 | 44.8 % | 41.2 % | 10/28 | ~60 s |
*loose = ignoring case, punctuation, ß/ss and ÿ/y.
Cautions: (1) the scored lines are the easier ones (formulas, dates, confirmed entries); the hard name lines are not yet scored, so these numbers flatter every reader. (2) The reference was drafted by Claude Opus 5.5, so Opus’s lead is partly circular; Fable ties it on the loose score. (3) One page only.
What the uncertain (name) lines show: the strong readers often agree with each other and with real Mühleberg place names, which can settle a reading the reference left open: Rüplisried, Juchlishaus, Matzenried, Rosshäusern, Mauss, Gümmenen, Jaggisbach; surnames like Salvisberg (read “Salffisberg”/“Salchlisverg”), Moser (“Ulli Moser im Graben”, “Hans Moser auf der Breit”), Remund, Weibel, Mäder. Fable and Opus agree most (0.75 similarity on uncertain lines); the reference reading “Stoß” was probably wrong (“Moser”/“Moß”). Method for building the reference: agreement of the two strongest readers + a gazetteer of local places and surnames + a human check of what still disagrees.
All 14 pages: Opus 5.5 vs Fable 5.1 (2026-11-01)
Both models read all 14 pages (1,193 lines) blind, as separate helpers. Their agreement measures how hard each page is, and builds a two-reader consensus reference (htr-study/reference/*.consensus.tsv; disagreements listed in htr-study/review/*.md).
| Page | Characters the two disagree on | Words both read the same |
|---|---|---|
| Guggisberg baptisms 1730s | 12 % | 71 % |
| Eggiwil baptisms 1840s (printed form) | 12 % | 78 % |
| Eggiwil marriages 1650s | 15 % | 57 % |
| Langnau marriages 1820s | 16 % | 68 % |
| Mühleberg baptisms 1700 | 18 % | 65 % |
| Signau baptisms 1590s | 18 % | 60 % |
| Langnau baptisms 1730s | 18 % | 69 % |
| Guggisberg baptisms 1650s | 19 % | 60 % |
| Langnau Anabaptist register 1790s– | 25 % | 64 % |
| Langnau baptisms 1580s | 32 % | 37 % |
| Eggiwil deaths 1700s | 37 % | 40 % |
| Pieterlen marriages 1752 | 41 % | 45 % |
| Bolligen marriages 1659–60 (faded) | 43 % | 43 % |
| Pieterlen baptisms 1757 (heavy hand) | 59 % | 35 % |
| All 14 pages | 23 % | 59 % |
Line status across all pages: agreed 20 %, close (usually one word differs) 44 %, disputed 29 %, noise 6 %.
Reading: even the two strongest readers agree on only about three words in five. Clear 18th–19th-century hands come out well (70–78 % of words shared); faded, smeared or 16th-century pages fall to 35–45 %. The words they disagree on are mostly surnames and place names. A consensus of two models is therefore a good finding aid and a partial reference, not a transcription; the disputed words need a human expert or an independent record.
Two verified pages (2026-11-01)
Every Opus–Fable disagreement on Mühleberg 1700 and Guggisberg 1730s was settled on enlarged line images, using:
- The calendar. The Mühleberg dates carry planet symbols for the weekday (☉ Sunday, ♃ Thursday); all four agree with the Julian calendar of 1700.
- Records already in the vault. This Guggisberg page was read earlier for the Mischler search (“Christen Bilgen & Barb. Mischler”).
- Local places and surnames: Rüplisried, Juchlishaus, Matzenried, Rosshäusern, Ledi, Breit; Burri, Bilgen, Zwahlen, Stöckli, Hostettler, Binggeli, Beyeler.
Results:
- Mühleberg 1700: 34 fully verified lines, 39 verified except for flagged words, 9 noise.
- Guggisberg 1730s: 54 fully verified lines, 25 partial.
Files: htr-study/reference/*.verified.tsv.
The adjudication also corrected both models:
- Opus misread Bilgen as “Zbinden”, Burri as “Bürki”, Beyeler as “Gerhalter”, Herbstmonat as “Christmonat” and Cathar[ina] as “Balthas”.
- Fable misread Elsbeth as “Hanß” and Orzens as “Oyzens”.
- Both read the twin-birth line as nonsense; it is “haben zweÿ ehliche [Kinder]”, which the following “das Erste … das ander” entries confirm.
Character error on the fully verified lines:
| Reader | Mühleberg 1700 (34 lines) | Guggisberg 1730s (54 lines) |
|---|---|---|
| Claude Opus 5.5 | 5.2 % | 3.8 % |
| Claude Fable 5.1 | 6.3 % | 4.8 % |
| Claude Sonnet 5.5 | 20.4 % | 16.4 % |
| Bern TrOCR XVI–XIX | 28.8 % | (running) |
| Bern TrOCR XVI–XVII | 41.1 % | (running) |
| Claude Haiku 5.5 | 43.6 % | 41.3 % |
Caveat: the adjudicator was Claude Opus 5.5 (this session), so Opus’s small lead over Fable may be partly self-agreement. The two are effectively tied. The gap to every other reader is large and real.
A side find for the family research: this Guggisberg page also records Guggisberg families’ children baptised in the Vaud (Corsier 1718, Vevey 1719 and 1722, Lausanne 1725 and 1729–34, Orzens 1725). That’s the same pattern as the Mast family at Corsier and Lausanne in the 1720s–30s, recorded in Jacob Mast (1738–1808).
Training set, round 1 (2026-11-02)
The first training round for fine-tuning the Bern TrOCR model is done: 594 verified lines from 20 pages (target about 500), across 12 parishes and 1604–1843. None of its pages are test pages. Fine-tuning has not started and nothing has been uploaded.
- How lines enter: Opus 5.5 and Fable 5.1 read each page blind. A line enters when both agree, or when a difference is settled on an enlarged crop. A line that can’t be settled is left out.
- Agreement is low: about 25 % of lines match outright, mostly because of letter conventions rather than different readings.
- Agreement isn’t proof: both readers sometimes agree on a wrong reading, and the comparison ignores capital letters. Some errors may remain in agreed lines.
- Surnames and farm names stay the weak point. Unsettled examples are Krieg/Kring and Stämpfli/Stumpfli (Bolligen), Wüterich/Wütreich (Eggiwil) and Gaßstatt/Hochstatt (Wahlern).
Full details are in RESULTS.md in the study folder (Documents/Bern-HTR-Study).
Record compiled 1 November 2026.
About this research
Supporting documentation is linked throughout. This project is an exercise in AI-assisted research and development, and I haven’t manually verified every link or conclusion. All transcriptions and translations of Swiss parish records were made with AI, and their accuracy should be treated accordingly.