De scheidsrechter
_score_text_quality (Python) en score_ocr_text (C++) zijn dezelfde formule.
Plus: confidence, aandeel letters, aantal “echte” woorden (≥ 3 tekens), Nederlandse stopwoorden (de, het, een, van…).
Min: 1-letter-rommel, te korte tokens, te weinig letters.
RapidOCR is vaak te zelfverzekerd op krabbel. Bij een vergelijking print versus handschrift wordt die confidence afgetopt (max 0,40), zodat soep niet wint op bravoure.
Op stderr zie je dat als ensemble scores / compare print=… hw=….
Competitie per pagina
Default is auto: vijf rondes, daarna geen extra wedstrijd tenzij de print nog steeds als cursieve soep oogt.
Ronde 0 — Tesseract intern
Meerdere page-segmentation-modes. De hoogste score wint.
Ronde 1 — Print versus print
C++, OCR_QUALITY default. Tesseract (NL) en de sidecar (meestal RapidOCR) draaien allebei. De hoogste score wint. HTR-soep mag bruikbare print niet vervangen. Bij Tesseract-soep krijgt HTR een kleine marge (−8).
OCR_QUALITY=fast slaat deze dubbele run over.
Ronde 2 — Mag handschrift meedoen?
Eerst classificatie zonder mapnamen: inkt en regelmaat, plus of print-OCR al leesbaar is. Uitkomsten: print, handwriting, mixed, newspaper, form.
HTR en VLM blijven weg als de print al “dicht” is: krant, lange getypte pagina, hoge score. Ze doen wel mee bij soep, een gefragmenteerde body, of --archive handwriting|historic|modern|mixed. Lege pagina’s slaan HTR over.
OCR_HTR=always betekent “vergelijk als het kan helpen”, niet “TrOCR op elke krantenpagina”.
Ronde 3 — Print versus VLM/HTR
Eerst bij voorkeur Qwen2.5-VL. Is die bruikbaar (score ≥ 18, geen soep), dan wint die op een handschriftpagina en slaan TrOCR en ARletta over. Anders volgt het HTR-ensemble.
Winregel in _pick_better_ocr: geen HTR-soep over bruikbare print. Dichte print blijft print, tenzij HTR duidelijk beter is. Bij vermoed cursief mag HTR winnen als die coherent is. Optioneel: RapidOCR-briefhoofd plus HTR-body.
Ronde 4 — Historisch versus modern HTR
Default OCR_HTR_ENGINE=auto:
| Pagina | Eerst | Tweede engine |
|---|---|---|
| Schrift met lijntjes | TrOCR | ARletta alleen als modern niet bruikbaar is |
| Archief / geen lijnen | ARletta | TrOCR alleen als historisch niet bruikbaar is |
ensemble / both |
beide altijd | — |
Daarna _pick_htr_ensemble. ARletta krijgt een hallucinatie-straf: losse D/B, „ƒ—, weinig woordvariatie plus veel stopwoorden. Op gelinieerd schrift wint modern, tenzij historisch ná die straf nog duidelijk beter is.
Ronde 5 — Per regel (modern HTR)
TrOCR versus RapidOCR versus Tesseract (PSM 7/13/6). De hoogste regelscore wint. Op GPU altijd ensemble. Op CPU extra engines alleen als TrOCR zwak is (OCR_HTR_LINE_ENSEMBLE).
Daarna: geen tweede wedstrijd
Als de sidecar al vergeleken of bewust overgeslagen heeft (htr_attempted), forceert C++ geen extra HTR-pass. Alleen als print nog steeds als cursieve soep oogt, kan C++ alsnog een fallback starten.
Sturen
| Vlag | Effect |
|---|---|
--archive print / newspaper |
geen HTR |
--archive handwriting |
VLM, anders HTR |
--exclude historic |
geen ARletta |
OCR_HTR=0 |
alleen print |
OCR_HTR_ENGINE=trocr / arletta |
één HTR-kamp |
De wedstrijd is dus: meerdere kandidaten, dezelfde taalscore, één winnaar per pagina — met extra regels zodat overmoedige print-OCR en hallucerende ARletta niet stiekem winnen.
De commando’s staan op de man-page. Wat erin zit, staat op de stack.