Skip to content
BotServBotServ
RAGPDFOCRTesseractTextextraktionLokale KIDokumente

PDF und OCR: Gescannte Dokumente für RAG

PDFs und gescannte Dokumente für RAG nutzbar machen: Textextraktion, OCR mit Tesseract, Layout-Erkennung und Best Practices. Praxisguide mit Beispielen.

S

schutzgeist

12 min read
PDF und OCR für RAG

PDF und OCR: Gescannte Dokumente für RAG

Was dieser Artikel über PDF und OCR behandelt

  • Welche Arten von PDFs es gibt und warum manche OCR brauchen und andere nicht
  • Wie Du mit PyPDF2, pdfplumber und PyMuPDF Text aus digitalen PDFs extrahierst
  • Wie Du Tesseract und pytesseract nutzt, um gescannte Dokumente in Text zu verwandeln
  • Warum Layout-Erkennung und Preprocessing die OCR-Qualität massiv verbessern
  • Ein vollständiges Praxisbeispiel: ein gescanntes Handbuch von Scan bis durchsuchbarem Text

Einleitung: PDF und OCR verständlich erklärt

Du baust ein lokales RAG-System auf und hast Deine Dokumente gesammelt. Da sind Handbücher als PDF, alte Verträge als Scans, Notizen als Fotos. Du versuchst, den Text zu extrahieren, und stellst fest: Bei vielen Dateien kommt nichts Brauchbares heraus. Die PDF enthält keinen Text, sondern nur Bilder.

Genau hier kommen PDF-Verarbeitung und OCR ins Spiel. In diesem Artikel zeige ich Dir, wie Du PDFs und gescannte Dokumente so aufbereitest, dass sie in Deiner RAG-Pipeline nutzbar werden. Wenn Du die Grundlagen der Dokumentvorbereitung noch nicht kennst, lies Dir zuerst diesen Artikel durch. Hier gehen wir einen Schritt tiefer und kümmern uns um die PDF-spezifischen Herausforderungen.

Warum brauche ich PDF- und OCR-Verarbeitung?

Stell Dir vor, Du hast einen Ordner voller alter Verträge, Bedienungsanleitungen und technischer Dokumentationen. Die meisten davon sind gescannte PDFs, also eigentlich Fotos von Papierseiten, in einer PDF-Datei zusammengefasst. Es gibt keine Textebene, nichts ist durchsuchbar, nichts lässt sich kopieren.

Du versuchst, diese Dokumente in Dein RAG-System zu laden. Die Extraktion liefert leere Seiten oder wirft Fehler. Dein RAG-System findet keine Antworten, weil schlicht kein Text vorhanden ist. Die Dokumente sind da, aber für die KI unsichtbar.

Ohne OCR bleiben all diese gescannten Dokumente ungenutzt. Du sitzt auf einem Berg von Informationen, kannst aber nicht darauf zugreifen. Mit OCR wandelst Du die Bilder in durchsuchbaren Text um und machst sie für RAG verfügbar. Das ist der entscheidende Schritt, wenn Deine Dokumentensammlung gescannte Materialien enthält.

PDF und OCR kurz erklärt

Die Analogie: Stell Dir einen Kopierer vor, der nicht nur kopiert, sondern auch lesen kann, was er kopiert. Ein normaler Kopierer erzeugt ein Bild der Seite. OCR ist wie ein Kopierer, der das Bild nimmt und gleichzeitig den Text darauf erkennt, als würde jemand die Seite abtippen.

Bei digitalen PDFs ist das nicht nötig. Dort ist der Text bereits als Text gespeichert, wie in einem Textverarbeitungsdokument. Du kannst ihn direkt herausziehen. Bei gescannten PDFs besteht jede Seite nur aus einem Bild. Dort muss OCR den Text aus dem Bild erkennen, Zeichen für Zeichen, Wort für Wort.

Für wen ist dieser Artikel gedacht?

Dieser Artikel richtet sich an Einsteiger, die ein lokales RAG-System aufbauen und gescannte Dokumente oder PDFs verarbeiten wollen. Du brauchst keine Vorkenntnisse in OCR, solltest aber grundlegend verstehen, was lokale KI ist und wie RAG funktioniert. Die Codebeispiele sind in Python geschrieben und so erklärt, dass Du sie auch ohne tiefe Programmierkenntnisse nachvollziehen kannst.

Wichtige Begriffe rund um PDF und OCR

BegriffErklärung
PDFEin Dokumentformat, das Text und Bilder enthalten kann. Nicht jede PDF enthält auswählbaren Text.
Text LayerDie Textebene in einer PDF. Bei digitalen PDFs vorhanden, bei gescannten fehlt sie.
OCROptical Character Recognition. Technologie, die Text aus Bildern erkennt.
TesseractEine Open-Source-OCR-Engine, die lokal läuft und viele Sprachen unterstützt.
LayoutDie Anordnung von Text, Bildern und Tabellen auf einer Seite. Wichtig für die Lesereihenfolge.
DPIDots per Inch. Die Auflösung eines Bildes. Höhere DPI bedeuten mehr Detail für OCR.
BildformatDas Format des Bildes in einer PDF, etwa JPEG oder PNG. Beeinflusst Qualität und Dateigröße.
SeiteEine einzelne Seite einer PDF. Wird bei der Verarbeitung einzeln behandelt.
SpalteEin vertikaler Textbereich in einem mehrspaltigen Layout. Verwirft die Lesereihenfolge, wenn ignoriert.
AbsatzEin zusammenhängender Textblock. Wird später zu einem Chunk für RAG.
TokenEin Textfragment, das von Modellen verarbeitet wird. Relevant für Chunking und Embeddings.

Arten von PDFs

Bevor Du loslegst, musst Du verstehen, welche Art von PDF Du vor Dir hast. Die Verarbeitung unterscheidet sich grundlegend.

Textbasierte PDFs (born digital)

Diese PDFs wurden aus einem Textverarbeitungsprogramm oder einer Software exportiert. Der Text ist als Text gespeichert, nicht als Bild. Du kannst ihn markieren, kopieren und durchsuchen. Die Extraktion ist einfach und erfordert kein OCR. Beispiele: PDFs aus Word, LaTeX, HTML-Exporte.

Gescannte PDFs (image only)

Diese PDFs bestehen aus Bildern von Papierseiten. Jede Seite ist ein Foto, es gibt keine Textebene. Du kannst den Text nicht markieren oder durchsuchen. Hier brauchst Du OCR, um den Text zu extrahieren. Beispiele: eingescannte Verträge, alte Handbücher, archivierte Dokumente.

Gemischte PDFs

Manche PDFs enthalten sowohl Text als auch gescannte Seiten. Etwa ein Handbuch, dessen erste Seiten digital erstellt wurden, aber angehängte alte Anhänge als Scans vorliegen. Hier musst Du pro Seite prüfen, ob Text vorhanden ist, und OCR nur dort anwenden, wo nötig.

So prüfst Du in Python, ob eine Seite Text enthält:

from pypdf import PdfReader

reader = PdfReader("dokument.pdf")
for i, page in enumerate(reader.pages):
    text = page.extract_text()
    if text and text.strip():
        print(f"Seite {i+1}: Text vorhanden ({len(text)} Zeichen)")
    else:
        print(f"Seite {i+1}: Kein Text, OCR nötig")

Mit diesem Check am Anfang sparst Du Dir OCR-Verarbeitung auf Seiten, die sie nicht brauchen.

Textbasierte PDFs extrahieren

Für textbasierte PDFs gibt es mehrere gute Python-Bibliotheken. Hier sind die drei wichtigsten mit ihren Stärken.

PyPDF2 (pypdf)

PyPDF2 ist die einfachste Option. Es extrahiert reinen Text, ignoriert aber Layout-Informationen.

from pypdf import PdfReader

reader = PdfReader("handbuch.pdf")
text = ""
for page in reader.pages:
    text += page.extract_text() + "\n"
print(text[:500])

PyPDF2 ist schnell und zuverlässig für einfache PDFs. Bei mehrspaltigen Layouts kann die Lesereihenfolge durcheinander geraten, weil das Layout nicht berücksichtigt wird.

pdfplumber

pdfplumber ist besser geeignet für komplexe Layouts. Es erkennt Spalten und Tabellen und gibt Dir mehr Kontrolle über die Extraktion.

import pdfplumber

with pdfplumber.open("handbuch.pdf") as pdf:
    for page in pdf.pages:
        text = page.extract_text()
        if text:
            print(text[:500])

pdfplumber bietet zusätzlich Methoden wie extract_tables(), um Tabellen strukturiert auszulesen. Das ist wertvoll, wenn Deine PDFs tabellarische Daten enthalten.

PyMuPDF (fitz)

PyMuPDF ist die schnellste Option und extrahiert Text mit Layout-Informationen.

import fitz  # PyMuPDF

doc = fitz.open("handbuch.pdf")
for page in doc:
    text = page.get_text()
    print(text[:500])

PyMuPDF gibt Dir auch Metadaten wie Schriftgröße und Position, was bei komplexen Layouts hilft, Überschriften von Fließtext zu unterscheiden.

Welche Bibliothek Du nutzt, hängt von Deinen Dokumenten ab. Für einfache PDFs reicht PyPDF2. Für komplexe Layouts nimm pdfplumber oder PyMuPDF.

Gescannte PDFs mit OCR

Wenn eine PDF keine Textebene hat, brauchst Du OCR. Die beste Open-Source-Option für lokale Verarbeitung ist Tesseract.

Tesseract installieren

Unter Ubuntu oder Debian:

sudo apt install tesseract-ocr tesseract-ocr-deu

Unter macOS mit Homebrew:

brew install tesseract tesseract-lang

Unter Windows lade Dir den Installer von github.com/UB-Mannheim/tesseract herunter.

Das Paket tesseract-ocr-deu installiert das deutsche Sprachmodell. Für Englisch ist tesseract-ocr-eng zuständig. Du kannst mehrere Sprachen gleichzeitig installieren.

pytesseract installieren

pip install pytesseract Pillow pdf2image

pytesseract ist die Python-Schnittstelle für Tesseract. Pillow brauchst Du für die Bildverarbeitung, pdf2image wandelt PDF-Seiten in Bilder um.

PDF in Bilder umwandeln und OCR ausführen

from pdf2image import convert_from_path
import pytesseract

# PDF in Bilder umwandeln, 300 DPI für gute OCR-Qualität
images = convert_from_path("scan.pdf", dpi=300)

full_text = ""
for i, image in enumerate(images):
    # OCR mit deutschem Sprachmodell
    text = pytesseract.image_to_string(image, lang="deu")
    full_text += f"--- Seite {i+1} ---\n{text}\n"

print(full_text[:500])

Die Angabe lang="deu" sagt Tesseract, dass der Text auf Deutsch ist. Für englische Dokumente nutze lang="eng". Du kannst auch mehrere Sprachen angeben: lang="deu+eng".

Layout-Erkennung

Einfaches OCR erkennt Zeichen, versteht aber nichts von der Struktur einer Seite. Bei mehrspaltigen Layouts, Tabellen oder eingebetteten Bildern gerät die Lesereihenfolge durcheinander. Der Text wird unbrauchbar für RAG, weil zusammengehörige Sätze auseinandergerissen werden.

Warum Layout wichtig ist

Stell Dir eine Zeitungsseite mit drei Spalten. Einfaches OCR liest Zeile für Zeile über alle Spalten hinweg. Der Text ist dann ein unverständliches Durcheinander. Die erste Spalte muss vollständig gelesen werden, bevor die zweite beginnt. Nur so bleibt der Sinn erhalten.

LayoutLM

LayoutLM ist ein Modell von Microsoft, das Text und Layout-Informationen gemeinsam verarbeitet. Es erkennt, welche Textblöcke zusammengehören und in welcher Reihenfolge sie gelesen werden müssen. LayoutLM ist leistungsfähig, aber anspruchsvoller in der Einrichtung.

PaddleOCR

PaddleOCR ist eine weitere Open-Source-Option, die Layout-Erkennung und OCR kombiniert. Es ist einfacher einzurichten als LayoutLM und liefert gute Ergebnisse bei mehrspaltigen Layouts und Tabellen.

from paddleocr import PaddleOCR

ocr = PaddleOCR(use_angle_cls=True, lang="german")
result = ocr.ocr("scan.png", cls=True)

for line in result[0]:
    print(line[1][0])

Für einfache Dokumente reicht Tesseract. Wenn Deine Dokumente komplexe Layouts haben, lohnt sich der Aufwand für PaddleOCR oder LayoutLM.

Qualität verbessern

Die OCR-Qualität hängt stark von der Qualität des Eingabebilds ab. Mit Preprocessing verbesserst Du die Erkennungsrate erheblich.

DPI erhöhen

Scanne mit mindestens 300 DPI, besser 600 DPI für kleine Schrift. Niedrigere Auflösung führt zu Fehlern, weil Tesseract die Zeichen nicht sauber erkennen kann.

Binarisierung

Binarisierung wandelt das Bild in Schwarz-Weiß um, was Tesseract die Arbeit erleichtert.

from PIL import Image, ImageOps

image = Image.open("scan.png")
# In Graustufen umwandeln
gray = ImageOps.grayscale(image)
# Binarisierung mit Schwellwert
bw = gray.point(lambda x: 0 if x < 128 else 255, "1")
bw.save("scan_bw.png")

Deskew (Gerade richten)

Schiefe Scans verschlechtern die OCR-Qualität. Mit deskew richtest Du das Bild aus.

from skimage import io
from skimage.transform import rotate
from skimage.color import rgb2gray
import numpy as np
from scipy.ndimage import interpolation

def deskew(image_path):
    image = io.imread(image_path, as_gray=True)
    # Schwellwert für Binarisierung
    binary = image < 0.5
    # Winkel schätzen
    angles = np.linspace(-10, 10, 41)
    scores = []
    for angle in angles:
        rotated = interpolation.rotate(binary, angle, reshape=False)
        scores.append(np.sum(rotated))
    best_angle = angles[np.argmax(scores)]
    # Bild ausrichten
    corrected = rotate(image, best_angle, resize=True)
    io.imsave("scan_deskewed.png", corrected)

deskew("scan.png")

Diese drei Schritte, höhere DPI, Binarisierung und Deskew, können die OCR-Fehlerquote drastisch senken. Investiere Zeit ins Preprocessing, es zahlt sich in jeder späteren RAG-Abfrage aus.

Beispiel: Ein gescanntes Handbuch verarbeiten

Wir gehen jetzt ein vollständiges Beispiel durch. Du hast ein gescanntes Handbuch als PDF und willst es für RAG aufbereiten.

Schritt 1: PDF in Bilder umwandeln

from pdf2image import convert_from_path

images = convert_from_path("handbuch_scan.pdf", dpi=300)
print(f"{len(images)} Seiten geladen")

Schritt 2: Preprocessing anwenden

from PIL import Image, ImageOps, ImageFilter

def preprocess(image):
    # Graustufen
    gray = ImageOps.grayscale(image)
    # Kontrast erhöhen
    gray = ImageOps.autocontrast(gray)
    # Leichtes Sharpening
    gray = gray.filter(ImageFilter.SHARPEN)
    # Binarisierung
    bw = gray.point(lambda x: 0 if x < 140 else 255, "1")
    return bw

processed_images = [preprocess(img) for img in images]

Schritt 3: OCR ausführen

import pytesseract

pages = []
for i, img in enumerate(processed_images):
    text = pytesseract.image_to_string(img, lang="deu")
    pages.append({"text": text, "page": i + 1})
    print(f"Seite {i+1}: {len(text)} Zeichen erkannt")

Schritt 4: Text bereinigen

import re

def clean_ocr_text(text):
    # Leerzeichen normalisieren
    text = re.sub(r"[ \t]+", " ", text)
    # Leerzeilen reduzieren
    text = re.sub(r"\n{3,}", "\n\n", text)
    # Häufige OCR-Fehler korrigieren
    text = text.replace("|", "l")
    text = text.replace("0", "o")  # Vorsicht, nur bei Bedarf!
    return text.strip()

for page in pages:
    page["text"] = clean_ocr_text(page["text"])

Achtung bei der automatischen Fehlerkorrektur: Ersetzungen wie 0 zu o können auch richtige Zeichen verändern. Prüfe die Ergebnisse und passe die Korrekturen an Deine Dokumente an.

Schritt 5: Metadaten hinzufügen und Chunks erstellen

chunks = []
for page in pages:
    paragraphs = page["text"].split("\n\n")
    for para in paragraphs:
        if len(para.strip()) > 50:
            chunks.append({
                "text": para.strip(),
                "metadata": {
                    "source": "handbuch_scan.pdf",
                    "page": page["page"],
                    "method": "ocr"
                }
            })

print(f"{len(chunks)} Chunks erstellt")

Ab hier geht es weiter wie im Artikel zur Dokumentvorbereitung: Du generierst Embeddings und lädst die Chunks in Deine Vektordatenbank.

OCR-Alternativen

Tesseract ist nicht die einzige Option. Hier sind Alternativen, besonders wenn Du höhere Qualität brauchst.

Ollama mit Vision-Modellen

Mit Ollama kannst Du Vision-Modelle wie LLaVA lokal ausführen. Diese Modelle können Bilder “lesen” und Text daraus extrahieren. Sie sind flexibler als Tesseract, besonders bei handschriftlichen Notizen oder ungewöhnlichen Layouts, aber langsamer.

# Pseudocode, Details siehe Ollama-Dokumentation
import ollama

response = ollama.chat(
    model="llava",
    messages=[{
        "role": "user",
        "content": "Extrahiere den Text aus diesem Bild.",
        "images": ["scan.png"]
    }]
)
print(response["message"]["content"])

Vision-Modelle sind eine gute Ergänzung zu Tesseract, wenn klassisches OCR an Grenzen stößt.

Cloud-OCR

Cloud-Dienste wie Google Cloud Vision oder AWS Textract bieten exzellente OCR-Qualität. Der Nachteil: Deine Dokumente verlassen Deinen Rechner. Für sensible Dokumente ist das oft nicht akzeptabel. Wenn Du den Artikel hier liest, interessiert Du Dich vermutlich für lokale KI, also bleiben wir bei lokalen Lösungen.

Typische Stolpersteine bei PDF und OCR

  1. DPI zu niedrig: Scans unter 200 DPI führen zu massiven OCR-Fehlern. Nutze mindestens 300 DPI.
  2. Falsche Sprache eingestellt: Wenn Tesseract mit englischem Modell auf deutsche Texte losgelassen wird, ist das Ergebnis unbrauchbar. Prüfe die Spracheinstellung.
  3. Layout ignoriert: Mehrspaltige Dokumente ohne Layout-Erkennung ergeben einen unverständlichen Textwurst. Nutze PaddleOCR oder LayoutLM für komplexe Layouts.
  4. Kein Preprocessing: Roh-Scans ohne Binarisierung und Deskew verschlechtern die Qualität erheblich. Investiere Zeit ins Preprocessing.
  5. OCR-Fehler nicht korrigiert: OCR ist nie perfekt. Häufige Fehler wie rn statt m oder 1 statt l verschlechtern die RAG-Qualität. Prüfe und korrigiere.
  6. Seitenzahlen und Header nicht entfernt: Auch bei OCR-Text musst Du Header und Footer bereinigen, wie im Artikel zur Dokumentvorbereitung beschrieben.
  7. Zu große Bilder im Speicher: 600-DPI-Scans einer A4-Seite brauchen viel RAM. Verarbeite Seiten einzeln, nicht alle gleichzeitig.
  8. Gemischte PDFs nicht erkannt: Wenn Du OCR auf textbasierte Seiten anwendest, verschlechtert das Ergebnis. Prüfe zuerst, ob Text vorhanden ist.

Hardware, Kosten und Sicherheit bei PDF und OCR

OCR ist rechenintensiv, aber nicht extrem. Tesseract läuft problemlos auf einem normalen Laptop ohne GPU. Die Verarbeitung von 100 Seiten dauert auf einer durchschnittlichen CPU etwa 5 bis 15 Minuten, je nach DPI und Komplexität.

Kosten entstehen praktisch keine, da Tesseract Open Source ist und lokal läuft. Du brauchst keine API-Schlüssel und keine Cloud-Abos. Speicherplatz für die verarbeiteten Bilder ist der einzige Ressourcenfaktor.

Sicherheit ist ein großer Vorteil von lokalem OCR. Deine Dokumente verlassen nie Deinen Rechner. Das ist besonders wichtig bei Verträgen, medizinischen Unterlagen oder anderen sensiblen Dokumenten. Du brauchst Dir keine Gedanken um Datenabfluss zu machen, was bei Cloud-OCR-Diensten anders wäre.

FAQ: PDF und OCR - Typische Fragen

Brauche ich OCR für jede PDF?

Nein. Nur für gescannte PDFs, die keine Textebene haben. Digitale PDFs, die aus Textverarbeitungsprogrammen exportiert wurden, enthalten auswählbaren Text. Prüfe zuerst mit PyPDF2, ob Text extrahierbar ist.

Was ist besser: Tesseract oder ein Vision-Modell?

Für standardisierte gedruckte Texte ist Tesseract schneller und ausreichend. Für handschriftliche Notizen, ungewöhnliche Layouts oder Texte mit vielen Sonderzeichen kann ein Vision-Modell wie LLaVA über Ollama bessere Ergebnisse liefern, ist aber langsamer.

Welche DPI ist optimal für OCR?

300 DPI ist ein guter Standardwert. Für kleine Schrift oder feine Details nutze 600 DPI. Unter 200 DPI steigt die Fehlerquote deutlich an.

Wie gehe ich mit mehrspaltigen Layouts um?

Nutze ein Tool mit Layout-Erkennung wie PaddleOCR oder LayoutLM. Einfaches Tesseract liest zeilenweise über alle Spalten hinweg und erzeugt unbrauchbaren Text.

Kann Tesseract Handschrift erkennen?

Tesseract ist auf gedruckten Text optimiert. Handschrift erkennt es sehr unzuverlässig. Für handschriftliche Notizen sind Vision-Modelle besser geeignet.

Wie korrigiere ich OCR-Fehler?

Vergleiche OCR-Ergebnisse mit dem Original, prüfe häufige Fehlermuster und nutze gezielte Ersetzungen. Für große Mengen kannst Du ein Sprachmodell zur Nachkorrektur einsetzen, das offensichtliche Fehler im Kontext erkennt.

Wie lange dauert OCR für 100 Seiten?

Auf einer durchschnittlichen CPU etwa 5 bis 15 Minuten bei 300 DPI. Mit GPU geht es deutlich schneller. Die Dauer hängt auch von der Komplexität der Seiten ab.

Brauche ich eine GPU für OCR?

Nein, Tesseract läuft auf der CPU. Für Vision-Modelle über Ollama ist eine GPU empfehlenswert, aber nicht zwingend nötig. Die Verarbeitung ist dann nur langsamer.

Was mache ich mit Tabellen in gescannten Dokumenten?

Tabellen sind eine Herausforderung für OCR. PaddleOCR und LayoutLM können Tabellen erkennen. Alternativ kannst Du Tabellen als Bild beibehalten und mit einem Vision-Modell extrahieren. Für RAG ist es oft besser, Tabellen als strukturierte Metadaten zu speichern statt als Fließtext.

Kann ich mehrere Sprachen gleichzeitig verarbeiten?

Ja, Tesseract unterstützt mehrere Sprachen gleichzeitig mit lang="deu+eng". Das ist nützlich für Dokumente, die deutsche und englische Texte gemischt enthalten. Die Erkennungsrate kann aber etwas sinken, verglichen mit einsprachiger Verarbeitung.

Quellen und weiterführende Literatur

  • Tesseract Dokumentation: github.com/tesseract-ocr/tesseract
  • pytesseract Dokumentation: github.com/madmaze/pytesseract
  • pdfplumber Dokumentation: github.com/jsvine/pdfplumber
  • PyMuPDF Dokumentation: pymupdf.readthedocs.io
  • PaddleOCR: github.com/PaddlePaddle/PaddleOCR
  • LayoutLM: github.com/microsoft/unilm
  • Artikel zu Dokumente vorbereiten in dieser Reihe
  • Artikel zu RAG Grundlagen in dieser Reihe
Zurück zum KI Blog
Share:

Ähnliche Beiträge