4.6. 🚀 Messung der OCR-Qualität in Python#

Hinweise zur Ausführung des Notebooks

Dieses Notebook kann auf unterschiedlichen Levels erarbeitet werden (siehe Abschnitt “Technische Voraussetzungen”):

  1. Book-Only Mode: Sie lesen das Notebook hier im “Jupyter Book”, ohne den Code selbst auszuführen.

  2. Cloud Mode: Klicken Sie oben rechts in der Menüleiste auf das Raketen-Symbol 🚀 und wählen Sie “Colab”, um das Notebook auszuführen.

  3. Local Mode: Klicken Sie oben rechts in der Menüleiste auf das Download-Symbol und wählen Sie “.ipynb”, um das Notebook lokal auszuführen.

4.6.1. Übersicht#

In diesem Notebook wird die Qualität von OCR-Ergebnissen gemessen und bewertet. Ziel ist es, den OCR-Output eines historischen Zeitungsartikels (in Frakturschrift) mit einem manuell erstellten Referenztext (Ground Truth) zu vergleichen und die Güte der Texterkennung anhand standardisierter Metriken zu quantifizieren.

Dafür werden folgende Schritte durchgeführt:

  1. Durchführen der OCR auf einem Beispielbild mit Tesseract (Fraktur-Modell)

  2. Manuelle Erstellung eines Ground-Truth-Textes als Referenz

  3. Berechnung von Precision, Recall und F1-Score zum Vergleich von OCR-Output und Ground Truth

4.6.2. Installationen und Importe#

Hide code cell content
# 🚀 Install libraries
import sys
if 'google.colab' in sys.modules:
    !sudo apt install tesseract-ocr
    !sudo apt install poppler-utils
    # Das Fraktur-Modell deu_latf (früher frk) ist nicht als apt-Paket verfügbar – Modelldatei direkt laden
    !sudo wget -q https://github.com/tesseract-ocr/tessdata/raw/main/deu_latf.traineddata -P $(find /usr/share/tesseract-ocr -name tessdata -type d | head -1)
!pip install pytesseract pillow Levenshtein requests
Hide code cell content
import pytesseract
from PIL import Image
from pathlib import Path

Bevor wir Daten herunterladen, definieren wir eine kleine Hilfsfunktion download_file. Sie lädt eine Datei plattformunabhängig – also auch unter Windows – aus dem Internet in einen Zielordner herunter und ersetzt damit das Kommando wget, das nicht auf allen Systemen (z.B. Windows) nativ verfügbar ist.

# helper: download a single file (cross-platform replacement for `! wget -P`)
import requests

def download_file(url, target_dir):
    """Download the file at `url` into `target_dir`, keeping its original name."""
    target_dir = Path(target_dir)
    target_dir.mkdir(parents=True, exist_ok=True)
    target_path = target_dir / url.split("/")[-1]
    response = requests.get(url)
    response.raise_for_status()
    target_path.write_bytes(response.content)
    return target_path
Hide code cell content
# 🚀 get the image to process
if not Path("grippe.jpeg").exists():
    download_file("https://raw.githubusercontent.com/quadriga-dk/Text-Fallstudie-1/refs/heads/main/ocr/grippe.jpeg", ".")

4.6.3. Durchführen von OCR#

Wir werden denselben Beispielartikel zur Bewertung verwenden:

../_images/grippe.jpeg

Zuerst führen wir die OCR durch:

ocr_output = pytesseract.image_to_string(Image.open('grippe.jpeg'), 
                                         lang='deu_latf') # Wir verwenden das Fraktur-OCR-Modell
print(ocr_output)
7ie Grippe wüfel weiter

Zunahme der ſ<weren Fälle in Berlin.

Die Zahl der Grippefälle iſt in den leßten
be:der Tagen auc<h in Groß-Berlin noH
erf>lig zeftiegen. Die Worenhäuſer und ſon-
haen aroßen GeſHöäfte, die Krirgs- unh die prie
n Betriebe lagen, daß übermäig viele An-

"Fz 5cben krep? melden müſſen,-und an<
; .*e* Vofſt und 5ei der Straßenbahn iſt der
ſo3 der Grippelranten bedeuter) gt&

? e .*;* 2 8 1

Manuell die ‘Ground Truth’ zur Bewertung erstellen #

ground_truth = """Die Grippe wütet weiter 
Zunahme der schweren Fälle in Berlin. 
Die Zahl der Grippefälle ist in den letzten 
beiden Tagen auch in Groß-Berlin noch 
erheblich gestiegen. Die Warenhäuser und son-
stigen großen Geschäfte, die Kriegs- und die pri-
vaten Betriebe klagen, daß übermäßig viele An-
gestellte sich haben krank melden müssen und auch 
bei der Post und bei der Straßenbahn ist der 
Prozentsatz der Grippekranken bedeutend ge-
stiegen."""
print(ground_truth)
Die Grippe wütet weiter 
Zunahme der schweren Fälle in Berlin. 
Die Zahl der Grippefälle ist in den letzten 
beiden Tagen auch in Groß-Berlin noch 
erheblich gestiegen. Die Warenhäuser und son-
stigen großen Geschäfte, die Kriegs- und die pri-
vaten Betriebe klagen, daß übermäßig viele An-
gestellte sich haben krank melden müssen und auch 
bei der Post und bei der Straßenbahn ist der 
Prozentsatz der Grippekranken bedeutend ge-
stiegen.

4.6.4. Berechnung von Precision, Recall und F1-Score #

Hide code cell content
# 🚀 create folder and get the auxiliary python script to run in Colab
aux_dir = Path("auxiliary")
if not aux_dir.exists():
    aux_dir.mkdir(parents=True)
Hide code cell content
# 🚀 get the auxiliary python script
if not (aux_dir / "measure_ocr_quality.py").exists():
    download_file("https://raw.githubusercontent.com/quadriga-dk/Text-Fallstudie-1/main/ocr/auxiliary/measure_ocr_quality.py", aux_dir)
from auxiliary.measure_ocr_quality import measure_ocr_quality
precision, recall, f_score = measure_ocr_quality(ocr_output, ground_truth)

print(f'Precision: {round(precision, 4)}\nRecall: {round(recall, 4)}\nF1-score: {round(f_score, 4)}')
Precision: 0.7682
Recall: 0.8164
F1-score: 0.7916

🚀 Compare Ground Truth with OCR Output#

The block below lets you explore how character-level OCR mistakes affect Precision, Recall, and the F1-score.

The visualization highlights differences character by character:

  • 🔵 dark blue = correctly recognized (TP)

  • 🔷 medium blue = extra or incorrect characters (FP)

  • 🔹 light blue = missing characters (FN)

Below the visualization, the tool computes Precision, Recall, and F1 directly from these TP/FP/FN values.

This helps illustrate how different types of OCR errors influence each metric.

Changing the Ground Truth will also change the metrics. Go ahead and play with the GT and see how the metrics change



Legend:
correct   FP (wrong/extra)   FN (missing)

🔵 TP increases → Precision ↑ and Recall ↑
🔷 FP increases → Precision ↓
🔹 FN increases → Recall ↓