Techniek · per pagina

OCR-competitie.

Elke engine levert tekst. Een heuristische score kiest de winnaar. Hoger betekent meer echte Nederlandse woorden, minder token-soep.

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.