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

  1. Bolligen marriages, 1659–60 (K Bolligen 22, image 40): faded, crowded, many entries struck through, corrections between the lines. Hard.
  2. 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):

#ImageTruth
B1Bolligen”uff Montag den 1. Augusti” 1659 (1 Aug was a Monday only in 1659); Jacob [Schmutziger?] … Maria [?] … “Consistorii Bern”
B2Bolligen”uff Frytag den 23. 7bris Bendicht Zoss und Catharina Stämpfli”, Friday 23 Sep 1659
B3Bolligen”uff Frytag den 14. 8bris”: Bendicht [?] and Barbara [Zürgi?]
B4Bolligenright page: “Volgend der jenigen Eheleuten namen, die von mir Daniel [?], Predicant zu Bolligen, sind yngesegnet worden”
P1Pieterlen”den 20. Wintermonat … Infans Peter”
P2Pieterlen”Par: Conrad Sprunger, [2–3 words unread] … Elsbeth Grober von Sumiswald” (names confirmed by the 1752 marriage, K Pieterlen 2 image 175)
P3Pieterlen”Testes: Peter Grober … Catharina Grober … von Sumiswald”

Tools tested

ToolWhat it isAccessCost
Transkribus (web demo)Commercial handwriting-recognition platform (READ-COOP); public models include “German Kurrent 16th–18th” by the Bern teamtranskribus.org; demo shows ~10 lines, rest needs a free accountfree: 5 demo tries; account 50 pages a month
Leo (tryleo.ai)AI transcription servicewebnot checked
Bern TrOCR XVI–XVII: dh-unibe/trocr-kurrent-XVI-XVIIUniversity 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 locallyfree
Bern TrOCR XVI–XIX v2: dh-unibe/trocr-german-kurrent-xvi-xix-from-kurrent-v2Same team, broader period; published CER 8.9 %Hugging Face, localfree
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 timepip, localfree
Claude Opus 5.5 (medium reasoning effort), reading page images directlyAnthropic’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

CheckpointTranskribusLeoBern 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 dateday ✗ (27)✗ “29. Iuni”✓ 23. septembris✗
B2 namesclose: “Bendicht Jose und Catherine Stimpfli”✗ “Benedictus Bosch vnd Katharina Stroopsky”✗ invented textpartial: “Cathrina S…pli”
B3✓ day, “Barbara Zürgi”✓ day, “Barbara Fürst”✓ day, “Barbara Fürggeren”—
B4not shown (behind sign-up)not shown in screenshotmostly ✓ (“Volgend derjenigen ehrluten namen … Daniel Himmel predicant zu Bolligen”)—
Latin abbreviationspartly✓ expanded (“ex p[er]missio Consistorij”)partly—
Invented or repeated textnone seenone entry repeated twiceyes: Zurich phrases not on the page (“landtvogt Heidegger”, “Binzikon”)—
P1–P3 (Pieterlen)✗ stray letters onlynot 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.
  1. 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.
  2. Search it loosely (e.g. “Sprng”, “Gostl”, “Z?ss”, “Ramser”) and by date.
  3. Read every hit on the image before anything enters the tree.
  4. 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) and fgho/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 htr folder and the two models--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

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):

ReaderCER strictCER loose*Exact linesTime
Claude Opus 5.55.0 %3.6 %24/28~70 s
Claude Fable 5.19.7 %3.6 %22/28~115 s
Claude Sonnet 5.518.1 %16.5 %15/28~25 s
Bern TrOCR XVI–XIX v231.0 %24.1 %8/28~20 s (local)
Bern TrOCR XVI–XVII45.8 %35.7 %11/28~20 s (local)
Claude Haiku 5.544.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).

PageCharacters the two disagree onWords both read the same
Guggisberg baptisms 1730s12 %71 %
Eggiwil baptisms 1840s (printed form)12 %78 %
Eggiwil marriages 1650s15 %57 %
Langnau marriages 1820s16 %68 %
Mühleberg baptisms 170018 %65 %
Signau baptisms 1590s18 %60 %
Langnau baptisms 1730s18 %69 %
Guggisberg baptisms 1650s19 %60 %
Langnau Anabaptist register 1790s–25 %64 %
Langnau baptisms 1580s32 %37 %
Eggiwil deaths 1700s37 %40 %
Pieterlen marriages 175241 %45 %
Bolligen marriages 1659–60 (faded)43 %43 %
Pieterlen baptisms 1757 (heavy hand)59 %35 %
All 14 pages23 %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:

ReaderMühleberg 1700 (34 lines)Guggisberg 1730s (54 lines)
Claude Opus 5.55.2 %3.8 %
Claude Fable 5.16.3 %4.8 %
Claude Sonnet 5.520.4 %16.4 %
Bern TrOCR XVI–XIX28.8 %(running)
Bern TrOCR XVI–XVII41.1 %(running)
Claude Haiku 5.543.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.