Text aus Bildern lesen
Von der Rechnung zum Datensatz: wie OCR arbeitet, warum die Vorverarbeitung über die Trefferquote entscheidet und wie man Tabellen und Belege verlässlich ausliest.
Die Idee
OCR steht für optische Zeichenerkennung. Ein Bild geht hinein, Text kommt heraus. Dazwischen liegen drei Aufgaben: herausfinden, wo überhaupt Text steht, diesen Text lesen, und ihn den richtigen Feldern zuordnen.
Wozu es gut ist
- Rechnungen und Lieferscheine in die Buchhaltung übernehmen.
- Archive durchsuchbar machen.
- Zählerstände, Typenschilder und Etiketten erfassen.
- Ausweise und Formulare vorausfüllen.
Die Kette, die funktioniert
import cv2, numpy as np
def entzerren(grau):
"""Schraeglage korrigieren, der groesste einzelne Hebel bei Belegen."""
kanten = cv2.Canny(grau, 50, 150)
linien = cv2.HoughLinesP(kanten, 1, np.pi/180, 200,
minLineLength=100, maxLineGap=10)
if linien is None:
return grau
winkel = [np.degrees(np.arctan2(y2-y1, x2-x1))
for x1, y1, x2, y2 in linien[:, 0]]
winkel = [w for w in winkel if abs(w) < 20]
if not winkel:
return grau
h, w = grau.shape
M = cv2.getRotationMatrix2D((w/2, h/2), float(np.median(winkel)), 1.0)
return cv2.warpAffine(grau, M, (w, h), flags=cv2.INTER_CUBIC,
borderMode=cv2.BORDER_REPLICATE)Darauf folgt die eigentliche Vorbereitung und die Erkennung. Die Konfidenz je Wort ist dabei die Größe, an der die Nachkontrolle ansetzt.
import pytesseract
def vorbereiten(pfad):
grau = cv2.cvtColor(cv2.imread(pfad), cv2.COLOR_BGR2GRAY)
grau = entzerren(grau)
if grau.shape[1] < 2000: # auf etwa 300 dpi bringen
grau = cv2.resize(grau, None, fx=2, fy=2, interpolation=cv2.INTER_CUBIC)
return cv2.adaptiveThreshold(grau, 255, cv2.ADAPTIVE_THRESH_GAUSSIAN_C,
cv2.THRESH_BINARY, 31, 15)
daten = pytesseract.image_to_data(vorbereiten("rechnung.jpg"), lang="deu",
output_type=pytesseract.Output.DICT)
# Die Konfidenz je Wort ist die wichtigste Groesse fuer die Nachkontrolle.
for wort, konf in zip(daten["text"], daten["conf"]):
if wort.strip() and int(konf) < 70:
print(f"unsicher: {wort!r} ({konf})")Die Werkzeuge
| Werkzeug | Stärke | Schwäche |
|---|---|---|
| Tesseract | Frei, offline, 100+ Sprachen, Wortkoordinaten | Schwach bei Layout und Handschrift |
| PaddleOCR | Sehr gut bei gedrehtem Text und Tabellen | Größere Installation |
| Cloud-OCR | Beste Quote, Layoutverständnis | Daten verlassen das Haus |
| Multimodales Modell | Versteht Bedeutung und Struktur | Teuer, keine Koordinaten, kann erfinden |
Die Fehlerfortpflanzung
Durchgerechnet für eine 22-stellige IBAN:
| Zeichengenauigkeit | Feldgenauigkeit | Fehlerhafte Belege je 1.000 |
|---|---|---|
| 0,98 | 0,641 | 359 |
| 0,99 | 0,801 | 199 |
| 0,995 | 0,895 | 105 |
| 0,999 | 0,978 | 22 |
Das ist der Grund, warum bei strukturierten Feldern nie allein auf OCR vertraut wird. Eine IBAN-Prüfsumme nach ISO 7064, ein Abgleich der Umsatzsteuer-ID gegen das MIAS-Register oder eine Plausibilitätsprüfung von Netto plus Steuer gegen Brutto senkt die Fehlerrate um mehr als jede Verbesserung der Erkennung.
Struktur statt Freitext
- Prüfsummen nutzen, wo es sie gibt: IBAN, USt-ID, EAN, Steuernummer.
- Rechnerische Konsistenz erzwingen: Summe der Positionen gleich Zwischensumme, Netto plus Steuer gleich Brutto.
- Datumsformate gegen einen Kalender prüfen, nicht nur gegen ein Muster.
- Bei Konfidenz unter einer Schwelle in eine menschliche Nachkontrolle geben statt zu raten.
- Die Rate der Nachkontrollen als Kennzahl führen, nicht die Erkennungsquote.
Der datenschutzrechtliche Punkt
Ein Beleg enthält regelmäßig personenbezogene Daten, und OCR erzeugt daraus eine maschinell auswertbare Form. Das ist eine eigenständige Verarbeitung mit eigener Rechtsgrundlage. Zwei Punkte sind in der Praxis strittig:
- Cloud-OCR ist eine Auftragsverarbeitung mit Drittlandbezug, sobald der Anbieter außerhalb der EU verarbeitet. Siehe Auftragsverarbeitung.
- Das Originalbild muss nach der Extraktion oft nicht mehr aufbewahrt werden. Wer es dennoch behält, braucht dafür einen eigenen Zweck und eine Löschfrist.