EasyOCR ist JaidedAIs sofort einsetzbare OCR-Bibliothek für Python: pip install easyocr, zwei Zeilen Code, und der in ein Bild eingebettete Text kommt als Strings zurück. Die Bibliothek steht unter Apache-2.0-Lizenz, unterstützt laut Angaben über 80 Sprachen und arbeitet als Pipeline aus zwei PyTorch-Modellen — einem CRAFT-Detektor, der alles als Text markiert, was er dafür hält, und einem Erkenner, der die Zeichen innerhalb jedes Rahmens liest. Die vortrainierten Gewichte laden sich beim ersten Aufruf automatisch herunter. Von der Struktur her ist das eine selbst gehostete Alternative zu Tesseract und PaddleOCR, keine Cloud-OCR-API pro Seite.
Die grundlegende API ist kurz: Reader(['en']), dann readtext(). Der eigentliche Footprint ist deutlich größer — in dieser Umgebung etwa 2 GB PyTorch und in einem frisch gestarteten Prozess rund ein Gigabyte Spitzen-RAM. Ich habe 36 englische PNG-Testdateien gerendert, easyocr 1.7.2 auf der CPU ausgeführt und die Ergebnisse Zeichen für Zeichen gegen synthetische Referenzwerte bewertet. Größe und Ausrichtung verursachten die größten CER-Einbrüche; das Dashboard zeigte außerdem Probleme bei Kurzzeichen und bei der Erkennung von Dollarzeichen.
Der auffälligste dieser Ausfälle betrifft ausgerechnet den Parameter, den fast alle empfehlen. rotation_info gilt im Issue-Tracker als die Lösung für gedrehte Bilder, deshalb bekam er drei orthogonal gedrehte Kopien desselben Satzes. Bei 270° lieferte er genau das, was er verspricht, und senkte die Character Error Rate von 0,83 auf 0,10. Bei 180° funktionierte er nur halb: 0,85 auf 0,67, wobei ein Ausdruck verloren ging. Bei 90° ging es in die falsche Richtung, 0,81 auf 0,92, und der Erkenner begann Spiegeltext auszugeben. Derselbe Parameter, dieselbe Winkel-Liste, drei unterschiedliche Ergebnisse — das Einschalten allein bedeutet also noch nicht, dass „Rotation beherrscht wird“. Dieselben 36 Testdateien zeigten außerdem einen klaren Größen-Knick, einen systematischen Fehler bei Dollarzeichen und eine Prognose von mir, die sich schlicht als falsch herausstellte.
Zwei Modelle im Trenchcoat
EasyOCR ist nicht ein einziges Modell. Es ist eine Pipeline aus zwei Stufen, und zu wissen, welche Stufe versagt hat, ändert die Fehlersuche komplett.
Stufe eins ist CRAFT, der Detektor. Seine einzige Aufgabe ist Lokalisierung — also zu entscheiden, wo im Bild überhaupt Text ist, und Boxen zurückzugeben. Er liest kein einziges Zeichen. Stufe zwei ist ein CRNN-Erkenner — ResNet-Feature-Extraktion, dann ein BiLSTM und anschließend CTC-Greedy-Decoding — der die Zeichen innerhalb jeder Box ausliest. Beide laufen auf PyTorch. Auf der CPU wird der Erkenner standardmäßig dynamisch auf int8 quantisiert, weshalb er schneller und schlanker ist, als die reine Parametermenge vermuten lässt.

Der praktische Effekt: EasyOCR hat zwei völlig unterschiedliche Fehlerbilder, und dafür braucht man unterschiedliche Gegenmaßnahmen. Wenn der Detektor nie eine Box zeichnet, hilft jedes Feintuning des Erkenners nichts — die Zeichen waren nie in der Pipeline. Wenn die Box vorhanden ist, aber die Zeichenkette falsch zurückkommt, ist das ein Erkennungsproblem und Preprocessing kann helfen. Nahezu jeder Thread nach dem Muster „EasyOCR hat meinen Text übersehen“, den ich gelesen habe, vermischt diese beiden Dinge.
Aktueller Stand des Projekts, geprüft am 27. Juli 2026: 29.825 Sterne, 528 offene Issues, Apache-2.0, und v1.7.2 von September 2024, mit dem letzten Push auf master im Dezember 2025. Diese Daten belegen weder architektonische Stabilität noch gesunde Pflege. Vor dem Einsatz sollte man die Kompatibilität mit dem eigenen Python-/PyTorch-Stack, die Reaktionszeit der Maintainer und relevante Issues für die eigenen Eingaben prüfen.
OCR wird oft mit CAPTCHA-Bescheinigung assoziiert, und darum geht es hier nicht. Es wurde nichts gegen Bot-Schutzsysteme getestet, und hier wird auch nichts empfohlen, was solche Hürden umgeht. Im Fokus steht das Auslesen von Text aus Bildern und Screenshots, die man berechtigt lesen darf.
Was ich gemessen habe — und was diese Zahlen nicht abdecken
Der Testdatensatz besteht aus 36 von mir gerenderten PNGs: 35 Einzelzeilen-Bilder, die sieben Schriftarten, acht Größen, sieben Kontraststufen, sieben Schräglagen, drei orthogonale Rotationen und drei Hintergründe abdecken — plus ein synthetischer Dashboard-Screenshot mit 19 einzeln beschrifteten Elementen. Jedes Bild wurde aus einem festen String (Sphinx of black quartz, judge my vow. 1234567890 — 48 Zeichen, Groß-/Kleinschreibung, Ziffern und Satzzeichen gemischt) im selben Durchlauf erzeugt, in dem auch das Ground-Truth-Label geschrieben wurde. Bild und Beschriftung können also nicht auseinanderdriften.
Die Genauigkeit wird als Character Error Rate (CER) gemessen: Levenshtein-Distanz in Zeichen geteilt durch die Länge des Ground Truth. CER 0 bedeutet eine perfekte Erkennung. CER 0,10 bedeutet grob gesagt, dass etwa jedes zehnte Zeichen falsch ist. Ich nenne die groß-/kleinschreibungssensitive CER als Hauptwert und zusätzlich die case-insensitive Variante, weil sich zeigt, dass sich der Groß-/Kleinschreibung der Großteil des „Fehlers“ zuschreiben lässt.
Die Grenzen sind wichtiger als die bloßen Zahlen:
- Nur Englisch. Der
english_g2-Erkenner. EasyOCR bewirbt über 80 Sprachen; ich habe eine getestet. Das sagt nichts über nicht-lateinische Schriftsysteme aus, also genau jene Fälle, in denen die veröffentlichten akademischen OCR-Vergleiche üblicherweise stattfinden. - Nur synthetisch. Gerenderter Text, keine Fotos. Kein Kamerarauschen, keine JPEG-Artefakte, kein Licht, keine Perspektive.
- Keine Handschrift. Das Projekt selbst nennt Handschrift als derzeit nicht unterstützt.
- Nur CPU. macOS arm64,
gpu=False. MPS war auf dem Rechner verfügbar, aber EasyOCR verwendet CPU, wenn es nicht CUDA ist. GPU-Performance wurde nicht gemessen; daher taucht hier kein GPU-Wert auf. - Eine Maschine, eine Version. easyocr 1.7.2, torch 2.13.0, Python 3.12.
Kurz: Das sind kontrollierte Kurven mit jeweils nur einer variierenden Größe, die genau zeigen, wo die Erkennungsqualität einbricht — und zwar bei sauber gerendertem lateinischem Text. Es ist kein Real-World-Korpus-Benchmark und ersetzt einen solchen auch nicht.
Die Belege sind nachprüfbar und nicht in einem Notebook eingeschlossen. Der Generator der Testdateien und die exakten Strings liegen in tests/build_fixtures.py und tests/fixtures/ground_truth.json; Erkennung, Timing und Ressourcenmessung finden sich in tests/run_easyocr.py; und tests/metrics.py berechnet die berichteten Fehlerraten aus der Roh-Ausgabe. Die resultierenden Erkennungsdaten und Aggregatmetriken liegen unter artifacts/raw/. Ein erneuter Lauf hilft, diese Maschine und Version zu prüfen. Er beantwortet aber nicht, wie EasyOCR auf Smartphone-Fotos, anderen Sprachen, Layouts oder in einer eigenen Preprocessing-Pipeline reagiert. Für den produktiven Einsatz braucht es daher repräsentative Eingaben statt dieser Testdateien als vermeintliches Zertifikat.
Eine Falle im Testaufbau sollte man erwähnen, weil sie beinahe zu einer falschen Kernaussage geführt hätte. Mein erster Messdurchlauf meldete auf sauberem schwarzem Arial eine CER von 0,375 — für den einfachsten denkbaren Input katastrophal. Das Problem lag nicht bei EasyOCR. Der Detektor hatte eine visuelle Zeile in eine Wörter-Box und eine Ziffern-Box aufgeteilt, und meine naive Sortierung nach y, dann x, setzte die Ziffern vor die Wörter. Mit zeilenbewusster Gruppierung behoben (Boxen nach vertikaler Überlappung gruppieren, dann von links nach rechts lesen), lagen die sauberen Schriften danach bei etwa 0,04–0,10. Wer eigene OCR-Benchmarks baut, läuft genau in dieselbe Falle.
Setup: Die Installation ist klein, die Abhängigkeit nicht

pip install easyocr
Mehr ist es nicht — und das sagt ehrlich gesagt nur wenig aus. Das Paket selbst ist winzig; was tatsächlich mitgezogen wird, ist PyTorch, ungefähr 2 GB. Beim ersten Aufruf von readtext() lädt EasyOCR seine Gewichte stillschweigend nach ~/.EasyOCR/model/ herunter — insgesamt 93,7 MiB, aufgeteilt in 79,30 MiB für den CRAFT-Detektor (craft_mlt_25k.pth) und 14,44 MiB für den englischen Erkenner (english_g2.pth).
Das wird in Tutorials selten erwähnt: Der erste Lauf braucht Netzverbindung und pausiert für den Download, und jede containerisierte Bereitstellung muss diese Gewichte entweder ins Image einbacken oder den Download beim Kaltstart bezahlen. Sobald der Cache gefüllt ist, läuft alles offline.
Der kalte Reader()-Start — Modelle von der Platte in den RAM plus der int8-Quantisierungsschritt — dauerte über die Läufe hinweg 1,3 bis 1,7 Sekunden. Danach gilt:
import easyocr
reader = easyocr.Reader(['en'], gpu=False)
result = reader.readtext('screenshot.png')
Und es funktioniert. Zwei Zeilen, keine Konfiguration, kein Modell zum Herumsuchen. Das „Easy“ im Namen verdient sich die Bibliothek an dieser Stelle — die Reibung steckt vollständig im Gewicht der Abhängigkeiten, nicht in der API.
Die Text-Qualitätsgrenze: fast perfekte Zeichen, aber nicht perfekte Großschreibung
Sieben Systemschriften, schwarz auf weiß, 32 px, jedes Mal derselbe String:
| Schriftart | CER (mit Groß-/Kleinschreibung) | CER (ohne Groß-/Kleinschreibung) |
|---|---|---|
| Georgia | 0.0625 | 0.0000 |
| Times | 0.0417 | 0.0417 |
| Comic Sans | 0.0417 | 0.0208 |
| Arial | 0.0833 | 0.0208 |
| Verdana | 0.0833 | 0.0208 |
| Impact | 0.0833 | 0.0208 |
| Courier | 0.1042 | 0.0417 |
| Mittelwert | 0.0714 | 0.0238 |
Der mittlere CER liegt bei 0,071 und sinkt auf 0,024, sobald die Groß-/Kleinschreibung ignoriert wird. Genau das ist die eigentliche Erkenntnis. EasyOCR verliert bei sauberem lateinischem Text nicht die Zeichen — es trifft die Form, aber nicht immer die Schreibweise.
Konkret wird das Wort vow in Kleinbuchstaben in sechs von sieben Schriften als VOW ausgegeben (Comic Sans macht daraus Vow). Impact macht zusätzlich aus of → Of. Der andere wiederkehrende Fehler betrifft Satzzeichen: Der Punkt am Satzende erscheint in mehreren Schriften als : oder _. Georgia ist ein perfektes Ergebnis, sobald man die Groß-/Kleinschreibung nicht mehr beachtet.
Das ist ein sehr brauchbares Muster. Wenn der nächste Schritt Fuzzy Matching, Keyword-Suche oder die Übergabe an ein Sprachmodell ist, kostet ein Groß-/Kleinbuchstaben-Flip fast nichts. Wenn danach ein exakter String-Vergleich mit einem Datenbank-Schlüssel kommt, kostet er alles. Case vor dem Vergleich normalisieren, und die scheinbar hohe Fehlerquote von EasyOCR verschwindet zu einem großen Teil.
Dass Courier am schlechtesten abschneidet (0,1042), passt ebenfalls: Monospace-Schriften setzen Zeichenabstände unnatürlich weit, was für einen CTC-Decoder schwieriger ist, der normale Buchstabenabstände gelernt hat.
Der Größen-Knick liegt genau dort, wo die Doku ihn vermuten lässt

readtext() hat einen dokumentierten Parameter, min_size=10, der erkannte Boxen unter 10 Pixel Höhe verwirft. Die meisten lesen daran vorbei. Für alle, die Screenshots oder PDFs auslesen, ist das die wichtigste Zahl in der API — und hier sieht man, was passiert, wenn man die Zeichenhöhe systematisch variiert:
| Gerenderte px | CER | Was passiert ist |
|---|---|---|
| 8 | 0.7708 | Eingeknickt — Boxen fallen unter den min_size-Filter und werden verworfen; nur Fragmente bleiben übrig |
| 10 | 0.1458 | Deutlich schlechter — genau an der Grenze zerlegt der Detektor die Zeile in 3 Boxen |
| 12 | 0.0417 | Erholt |
| 16 | 0.0000 | Perfekte Erkennung |
| 20 | 0.0208 | Sauber |
| 28 | 0.0208 | Sauber |
| 40 | 0.0625 | Sauber (der Case-Flip taucht wieder auf) |
| 64 | 0.0625 | Sauber (Case-Flip) |
Der Sprung von 0,04 auf 0,77 zwischen 12 px und 8 px ist kein allmählicher Qualitätsverlust. Es ist ein Filter, der genau das tut, was er laut Doku tun soll — und das Ergebnis ist, dass Text unter etwa 10 px für EasyOCR praktisch unsichtbar wird.
Der beste Bereich liegt bei 12–28 px, mit einer vollständigen CER von 0 bei 16 px. Oberhalb von 40 px steigt die CER wieder leicht an — nicht, weil die Zeichen schlechter lesbar würden, sondern weil der Flip von vow zu VOW zurückkommt. Große Schrift ist nicht schwerer zu lesen; sie profitiert einfach nicht mehr von jener Abstandssituation, die 16 px perfekt gemacht hat.
Wer Text aus Screenshots extrahiert, sollte deshalb zuerst die gerenderte Zeichenhöhe prüfen und erst dann das Modell beschuldigen. Ein Dashboard, das auf einem HiDPI-Display in 1× aufgenommen wurde, oder eine PDF-Seite, die auf 72 DPI gerastert wurde, liegt oft mit dem Fließtext unter 10 px. Bei 2× aufnehmen oder vor dem OCR hochskalieren — und schon umgeht man die ganze Klasse von „EasyOCR ignoriert die Hälfte meiner Seite“-Fehlern. Wenn das nicht geht, kann man min_size senken — aber dann ist mit mehr Rauschen zu rechnen, denn der Filter soll eben Fehl-Boxen unterdrücken.
Rotation: 10° Toleranz und eine Lösung, die nicht symmetrisch ist
Zuerst die Schräglage. Kleine Winkel, Arial 32 px, Standardmodus gegen rotation_info=[90,180,270]:
| Schrägwinkel | CER (Standard) | CER (mit rotation_info) |
|---|---|---|
| 0° | 0.0833 | 0.0833 |
| 5° | 0.0417 | 0.0417 |
| 10° | 0.0208 | 0.0833 |
| 15° | 0.2917 | 0.3750 |
| 20° | 0.7500 | 0.7708 |
| 30° | 0.8958 | 0.8750 |
| 45° | 0.8958 | 0.8750 |
Der Standardmodus von EasyOCR kommt bis etwa 10° ohne Probleme zurecht (CER ≤ 0,083), wackelt bei 15° und bricht bei 20° ein. rotation_info hilft bei Schräglage überhaupt nicht — was logisch ist, wenn man weiß, was der Parameter tut: Er probiert nur die angegebenen Winkel erneut, und 15° ist eben weder 90, 180 noch 270. Bei 10° wurde es sogar etwas schlechter (0,021 → 0,083), weil ein falscher Rotationsversuch die Konfidenzstimmung gewinnen kann.
Bei den orthogonalen Rotationen wird es merkwürdig:
| Rotation | CER (Standard) | CER (mit rotation_info) | Wiederhergestellt? |
|---|---|---|---|
| 90° | 0.8125 | 0.9167 | Nein — schlechter |
| 180° | 0.8542 | 0.6667 | Teilweise |
| 270° | 0.8333 | 0.1042 | Ja |
Derselbe Parameter. Dieselbe Winkel-Liste. Drei verschiedene Ergebnisse.
Bei 270° tut rotation_info genau das, was der Issue-Thread verspricht: Die CER fällt von 0,83 auf 0,10, also auf ein wirklich brauchbares Ergebnis. Bei 180° arbeitet der Mechanismus halbwegs — die CER verbessert sich auf 0,67, aber die Phrase my vow. fällt komplett heraus. Bei 90° geht es rückwärts, von 0,81 auf 0,92, und die Roh-Ausgabe erklärt warum: Der Erkenner liefert gespiegelte Zeichenketten zurück. VOW wird zu MOA, quartz wird zu zuuenb. Im Spiegel gelesen wäre das korrekt — als Datenpipeline ist es nutzlos.
Ich habe das anhand der Roh-Ergebnisse überprüft und nicht nur über die aggregierten Metriken, weil meine erste Vermutung war, dass die Zusammenführung die Reihenfolge zerstört hat. Das ist kein Join-Artefakt — genau das hat EasyOCR tatsächlich zurückgegeben.
Der Mechanismus ist eine Hypothese, keine Messung; ein Experiment zu Rotationskonventionen wurde nicht durchgeführt. Pillow rendert positive Winkel gegen den Uhrzeigersinn, daher passt nur das bei 270° gerenderte Bild zufällig zu einer Wiederholungsorientierung, mit der der Erkenner gut zurechtkommt, während im 90°-Fall der bestbewertete Retry auf einer gespiegelten Orientierung landet. Wie auch immer die Ursache im Detail aussieht — für den praktischen Einsatz ändert das nichts:
Dieses Testbild zeigt, dass rotation_info nicht als symmetrische Lösung über alle Orientierungen hinweg angenommen werden darf. Prüfen Sie die Rotationen, die in Ihren Eingaben tatsächlich vorkommen; eine vorgelagerte Orientierungskorrektur ist eine mögliche Maßnahme, aber keine durch diese drei Beispiele bewiesene Notwendigkeit.
Die Prognose, mit der ich danebenlag
Ich war mit der Erwartung gestartet, dass geringer Kontrast die Schwachstelle von EasyOCR sein würde. Blasse graue Schrift auf Weiß ist der klassische OCR-Fehlerfall, und es gibt dafür sogar einen dokumentierten Rettungsweg: contrast_ths=0.1 zusammen mit adjust_contrast=0.5, wodurch niedrig kontrastierte Boxen noch einmal mit einer verstärkten Kopie durchlaufen werden und das Ergebnis mit höherer Konfidenz gewählt wird.
Es griff nie, weil es nie nötig war.
| Vordergrundgrau | Weber-Kontrast | CER (Standard) | CER (adjust_contrast=1.0) |
|---|---|---|---|
| 0 (schwarz) | 1.000 | 0.0833 | 0.0833 |
| 64 | 0.749 | 0.0833 | 0.0833 |
| 110 | 0.569 | 0.0833 | 0.0833 |
| 150 | 0.412 | 0.1042 | 0.1042 |
| 180 | 0.294 | 0.0625 | 0.0625 |
| 200 | 0.216 | 0.0417 | 0.0417 |
| 220 | 0.137 | 0.0417 | 0.0417 |
Die CER verlässt die saubere Zone nicht — selbst bis hinunter zu Weber 0,14, also Grau 220 auf Weiß, so schwach, dass ich die Testdatei anstrengen musste, um zu bestätigen, dass der Text überhaupt da ist. Und die Kontrast-Spalte ist durchgehend identisch mit der Standard-Spalte, weil der Standard schon erfolgreich war.
Die Hintergründe erzählten dieselbe Geschichte. Schwarzer Text in allen Fällen:
| Hintergrund | CER |
|---|---|
| Einheitliche hellblaue Fläche | 0.083 |
| Vertikaler Verlauf | 0.021 |
| Gaussian Noise (μ200, σ22) | 0.000 |
Perfekte Erkennung auf der lautesten Testdatei im Set.
Der Geltungsbereich ist eng: Es geht um gleichfarbige, rauschfreie Niedrigkontraste, nicht um ein fotografiertes Kassenbonbild mit Sensorrauschen und JPEG-Kompression. In diesem Testset verursachten Geometrie und kurze Tokens die größten Fehler; die getesteten Farb- und synthetischen Rauschvarianten taten das nicht.
Ein realistisches Szenario: Zahlen aus einem Dashboard-Screenshot ziehen
Das ist der Fall, in dem sich Python-OCR in der Praxis meist wiederfindet. Jemand schickt einen Screenshot aus einem internen Dashboard, oder man betreibt eine Python-Scraping-Pipeline gegen eine stark diagrammbasierte Analytics-Seite, auf der Zahlen nur als gerenderte Pixel existieren, und man möchte die Werte als Daten haben.
Ich habe ein „Sales Dashboard“-Fenster gerendert — dunkle Kopfzeile mit Titel und rundem Avatar-Badge, drei KPI-Panels, drei Buttons, eine 2×3-Tabelle — und alle 19 Textelemente mit ihren exakten Strings und Pixel-Boxen versehen. Anschließend habe ich EasyOCRs Ausgabe über Box-Überlappung zugeordnet.
Detektions-Recall: 16 von 19. Die drei Ausfälle:
- das einzelne Badge-Zeichen „A“
- die Tabellenzelle „Q1“
- die Tabellenzelle „Q2“
Und „Q3“ wurde erkannt. Gleiches Font, gleiche Größe, gleiche Spalte — der Detektor behielt einen zweistelligen Token und ließ zwei andere fallen. Die Erkennung war bei optisch sehr ähnlichen Zellen inkonsistent. Da die Ausgaben in diesen Läufen deterministisch waren, ist das kein Hinweis auf zufälliges „Münzwurf“-Verhalten. Ein verwandtes Screenshot-Qualitätsproblem ist in #460 dokumentiert.
Bei den 16 Elementen, die er gefunden hat, war der Text nahezu perfekt: mittlere CER 0,027, davon 13 von 16 exakt. Titel, Labels, Buttons („Save“, „Cancel“, „Export CSV“), Spaltenüberschriften und Zahlen mit Tausendertrennzeichen kamen alle mit CER 0 zurück. 1,284 wurde korrekt gelesen, inklusive Komma.
Die drei ungenauen Treffer sind alle derselbe Fehler. Dollarbeträge:
| Ground Truth | EasyOCR-Lesung |
|---|---|
$57,912 | S57,912 |
$18,330 | S18,330 |
$25,178 | S25,178 |
$12,004 | $12,004 (korrekt) |
Drei von vier Dollarzeichen wurden zu einem großen S. Visuell ist das nachvollziehbar — praktisch heißt das aber, dass jedes Währungsfeld in der Extraktion nur ein Zeichen vom Müll entfernt ist, und ein naives float() würde bei allen scheitern.
Wenn Ihre Screenshot-Pipeline kurze Labels oder Währungswerte enthält, testen Sie mögliche Gegenmaßnahmen wie Hochskalieren, gepolsterte Zuschnitte, engere Feld-Erwartungen oder symbolbewusste Nachverarbeitung. Keine davon wurde hier benchmarked, und eine Regex, die führende S-Zeichen einfach ersetzt, kann legitime Werte beschädigen. Korrigieren Sie nur dort, wo Schema und Validierungsregeln das sicher erlauben.
Was der Betrieb kostet
Messwerte auf derselben Maschine (macOS arm64, CPU, ein Host, unter möglicher Parallelbelastung gemessen — diese Zahlen zeigen die Größenordnung, kein universelles Benchmark-Ergebnis):
| Metrik | Wert |
|---|---|
| Modellgewichte auf der Platte | 93,7 MiB (79,30 Detektor + 14,44 Erkenner) |
| Spitzen-RAM, frischer CPU-Prozess | 984,5 MiB |
Kalter Reader()-Start | 1,3–1,7 s |
| Warme Latenz, eine saubere 48-Zeichen-Zeile (p50) | ~0,062 s (p25–p75: 0,059–0,067 s, n=20) |
detail=0 vs. detail=1 | nahezu gleich (Median 0,062 vs. 0,063 s) |
Die Hauptkosten sind nicht die 94 MB Gewichte — es sind etwa ein Gigabyte Resident Memory pro Worker-Prozess, zusätzlich zu rund 2 GB Torch. Diese Zahl entscheidet, ob das in Ihren Container passt, und genau diese Zahl wird selten genannt.
Die Geschwindigkeit ist für den einfachen Fall in Ordnung. Unter 0,1 s warm für eine saubere einzelne Zeile auf CPU ist durchaus brauchbar. Aber das ist auch der einfache Fall: eine kurze Zeile mit hohem Kontrast. Die häufigen „EasyOCR braucht auf CPU Dutzende Sekunden“-Beschwerden beziehen sich auf große Dokumente mit mehreren Regionen in voller Canvas-Größe, und die habe ich nicht reproduziert — anderer Workload, hier nur als Verweis erwähnt.
Ein kleiner Mythos lässt sich noch ausräumen: detail=0 macht EasyOCR nicht schneller. Es entfernt nur Boxen und Confidence-Werte aus dem Rückgabewert. Die Berechnung ist da bereits passiert. Die Mediane unterscheiden sich nur um eine Millisekunde — also praktisch Rauschen.
Vor- und Nachteile
Vorteile
- Zeichen-Recall auf sauber gerendertem lateinischem Text ist nahezu perfekt — mittlere CER 0,071 mit Groß-/Kleinschreibung, 0,024 ohne, und eine vollständige CER von 0 ist bei 16 px erreichbar.
- Wirklich eine Zwei-Zeilen-API.
Reader(['en']), dannreadtext(), ohne Konfiguration und ohne Modellauswahl. - Deutlich robuster gegen Kontrastprobleme, als der Ruf vermuten lässt: Kein Zusammenbruch bis Weber 0,14 bei sauberem Text, und Hintergrundvarianten mit Rauschen, Verlauf oder Farbe verschlechterten das Ergebnis nicht (die Gaussian-Noise-Datei wurde perfekt gelesen).
- Nahezu perfekt bei Screenshot-Elementen, die erkannt werden: mittlere CER 0,027, 13 von 16 exakt, inklusive Zahlen mit Komma.
- Deterministisch. Jeder Genauigkeitswert hier war über zwei vollständig unabhängige Prozessläufe byte-identisch; nur die Timing-Werte bewegten sich.
- Apache-2.0 und self-hosted, ohne Nutzungsgebühren an einen Anbieter; Kosten entstehen durch Rechenleistung, Speicher, Storage und Queueing.
Nachteile
- Harter Einbruch unter der dokumentierten
min_size=10-Schwelle — CER 0,77 bei 8 px. Kleine UI-Texte sind standardmäßig unsichtbar. - Die Schräglagen-Toleranz endet bei etwa 10° und bricht bei 20° ein.
rotation_infoist keine symmetrische Lösung: 270° wird gerettet, 180° nur teilweise, 90° wird schlechter und liefert Spiegeltext.- Der Detektor lässt isolierte kurze Tokens fallen — ein einzelnes Badge-Zeichen und zwei 2-Zeichen-Zellen, während eine dritte, gleich formatierte Zelle erhalten bleibt.
- Systematischer Fehler
$→Sbei Währungswerten (3 von 4). - Rund 1 GB Resident Memory pro Prozess, plus eine ~2 GB Torch-Abhängigkeit.
- Die letzte Version stammt aus September 2024; das Projekt ist eher stabil als aktiv im Umbau.
Für wen es geeignet ist — und wer lieber Abstand nimmt
EasyOCR eignet sich, wenn Ihre Eingaben saubere, aufrechte, gerenderte Texte in brauchbarer Größe sind — Screenshots, UI-Captures, gerasterte PDFs oder generierte Reports — und Sie eine selbst gehostete Python-Pipeline ohne Vendor-Gebühren wollen. Die synthetischen CPU-Ergebnisse für Englisch gelten genau für dieses Szenario; Fotos, Handschrift und andere Schriftsysteme müssen separat getestet werden.
Lieber nicht einsetzen, wenn eines davon auf Ihre Eingaben zutrifft. Fotos — meine Messwerte beziehen sich auf synthetisch gerenderten Text und sagen nichts über Kamerarauschen, Perspektive oder Licht aus. Handschrift — das Projekt behauptet das selbst nicht. Nicht-lateinische Schriftsysteme — EasyOCR unterstützt zwar 80+ Sprachen, aber ich habe nur eine getestet, und bei solchen Fällen sind die veröffentlichten akademischen Vergleiche der richtige Referenzpunkt, nicht ein synthetischer Englisch-Durchlauf. Beliebig gedrehte Eingaben — außer Sie korrigieren die Orientierung vorher selbst. Speicherknappe Deployments — ein Gigabyte pro Worker summiert sich schnell.
Bevor Sie sich für OCR entscheiden, prüfen Sie DOM und Netzwerkantworten. Wenn die gewünschten Werte bereits als strukturierter Text vorhanden sind, vermeidet das Extrahieren an dieser Quelle die Erkennungs- und Lokalisierungsfehler von OCR. OCR ist dort sinnvoll, wo Pixel die einzige verfügbare Darstellung sind.
Alternativen und wo unser Stack passt
EasyOCR ist Apache-2.0 und self-hosted, ohne Nutzungsgebühr, aber mit echten Kosten für Rechenleistung und Betrieb. PaddleOCR, Tesseract und Vision-Language-Modelle wurden in diesem Benchmark nicht mitgemessen, daher folgt hier kein direkter Vergleich.
Die interessantere Frage ist ohnehin nicht OCR gegen OCR. Sie lautet: Sollten Sie überhaupt OCR einsetzen?
Ein Großteil der Screenshot-Extraktion, die ich sehe, ist nur ein Workaround für eine Website, die schwer zu scrapen war — eine per JavaScript gerenderte Tabelle, ein Dashboard hinter Login, eine Seite, die sich wehrt. Screenshotten und OCR darüberlegen wirkt wie der Weg des geringsten Widerstands, aber dabei werfen Sie sauber strukturierte Textdaten weg und zahlen am Ende noch den Dollarzeichen-Aufschlag, um eine schlechtere Version davon zurückzubekommen.
Hinweis der Autoren: Thunderbit ist unsere verwaltete Option für das Extrahieren aus Webseiten. Sie wurde nicht mit diesen Bilddateien getestet. Die relevante Grenze ist die Quellrepräsentation: Nutzen Sie DOM-/Netzwerk-Extraktion, wenn strukturierte Webdaten vorhanden sind, und bewerten Sie OCR nur dann, wenn Pixel die einzige Quelle sind.
Verwandte Lektüre aus demselben Testumfeld: der vollständige Vergleich Open-Source-Scraper, der Crawl4AI-Test und ein breiterer Blick auf KI-gestützte Extraktion für Seiten, die Selektoren blockieren.
Thunderbit für Web-Datenextraktion testen
Fazit
Sollte man EasyOCR verwenden? Ja — wenn Ihre Bilder aufrecht sind, die Glyphen mindestens 12 Pixel hoch sind und Sie lateinische Schrift lesen. In diesem Bereich ist das Tool sehr gut: mittlere CER 0,071 auf sauberem Text, 0,024 nach Normalisierung der Groß-/Kleinschreibung, perfekte Erkennung bei 16 px und eine bessere Robustheit gegenüber Kontrast, als sein Ruf vermuten lässt. Die API ist wirklich nur zwei Zeilen lang, und die Ausgabe ist deterministisch — was beim Debuggen einer Pipeline wichtiger ist, als viele zugeben.
Außerhalb dieses Bereichs scheitert es auf konkrete, erlernbare Weise. Text unter 10 px verschwindet im min_size-Filter. Schräglagen jenseits von 20° zerstören die Erkennung. rotation_info repariert eine orthogonale Orientierung, repariert eine zweite nur halb und macht die dritte mit Spiegeltext sogar schlechter. Einzelne Buchstaben und Zwei-Zeichen-Tokens fallen aus dem Detektor, während Nachbarn überleben. Dollarzeichen werden zu S.
Die Testfehler kamen aus beiden Stufen: übersehene oder falsch ausgerichtete Boxen auf der Geometrie-Seite und Dollarzeichen-Verwechslungen auf der Erkennungsseite. Hochskalierung, Orientierungskorrektur, gepolsterte Zuschnitte und schema-bewusste Symbolkorrektur sollte man als Kandidaten prüfen, nicht als universell sichere Fixes behandeln.
Testen Sie es einfach nicht so, wie ich es fast getan hätte — mit einem kaputten Evaluations-Setup und einer Zahl, die Sie nicht verstehen. Rendern Sie eigene Testdateien, kennen Sie Ihr Ground Truth exakt, und finden Sie Ihren eigenen Knickpunkt.
Thunderbit für Web-Datenextraktion testen Get Started Free
FAQs
Ist EasyOCR genau genug für die Produktion bei der Extraktion von Screenshot-Text?
Im synthetischen Dashboard lag die mittlere CER der gematchten Elemente bei 0,027, 13 von 16 waren exakt. Drei von 19 Elementen wurden nicht erkannt, und drei von vier Dollarzeichen wurden zu S. Ob das akzeptabel ist — und ob Hochskalierung oder schema-bewusste Korrektur hilft — muss für das Ziel-Layout separat getestet werden.
Welche Mindest-Schriftgröße kann EasyOCR lesen?
Praktisch etwa 12 Pixel gerenderter Glyphenhöhe. Der readtext()-Parameter min_size=10 verwirft erkannte Boxen unter 10 px, und der Effekt ist ein harter Knick statt eines sanften Verlaufs: CER 0,77 bei 8 px, 0,15 bei 10 px, 0,04 bei 12 px und 0 bei 16 px. Der saubere Bereich in meinem Sweep lag bei 12–28 px. Wenn Ihre Quelle ein HiDPI-Screenshot in 1× oder ein auf 72 DPI gerastertes PDF ist, skalieren Sie vor dem OCR hoch, statt min_size zu senken, denn dieser Filter existiert, um Fehl-Erkennungen zu unterdrücken.
Repariert rotation_info gedrehte Bilder in EasyOCR?
Nicht zuverlässig und nicht symmetrisch. Mit rotation_info=[90,180,270] auf drei orthogonal gedrehte Kopien desselben Satzes wurde das 270°-Bild sauber gerettet (CER 0,83 → 0,10), das 180°-Bild nur teilweise (0,85 → 0,67, mit verlorenem Ausdruck), und das 90°-Bild wurde schlechter (0,81 → 0,92) und lieferte Spiegeltext wie VOW → MOA. Für kleine Schräglagen hilft der Parameter ebenfalls nicht, weil er nur die angegebenen Winkel erneut versucht. Korrigieren Sie die Orientierung vor dem Aufruf von EasyOCR, statt sich auf diesen Parameter zu verlassen.
Wie viel Speicher und Festplatte braucht EasyOCR?
Die Gewichte sind 93,7 MiB und werden beim ersten Einsatz nach ~/.EasyOCR/model/ geladen — 79,30 MiB für den Detektor plus 14,44 MiB für den englischen Erkenner. Der Spitzen-RAM im gemessenen frischen CPU-Prozess lag bei 984,5 MiB, zusätzlich zu einer etwa 2 GB großen Torch-Installation. Der kalte Reader-Start dauerte 1,3–1,7 Sekunden; eine saubere einzelne Zeile lief auf dieser Maschine anschließend mit einem p50 von etwa 0,062 Sekunden. detail=0 änderte nur die Form der Rückgabe, nicht die gemessene Laufzeit.
Ist EasyOCR für kommerzielle Nutzung kostenlos, und wird es noch gepflegt? Ja, es steht unter Apache-2.0 und ist damit permissiv und kommerziell gut nutzbar. Am 27. Juli 2026 hat das Repository 29.825 Sterne und 528 offene Issues, die neueste Version ist v1.7.2 aus September 2024, und der letzte Push auf master war im Dezember 2025. Das spricht eher für Stabilität als für Aufgabe — die Architektur hat sich seit einiger Zeit kaum verändert, während sich Aktivität und Diskussionen stärker in den Issue-Tracker verlagert haben. Prüfen Sie die aktuelle Lizenz und den Release-Stand selbst, bevor Sie darauf aufbauen.


