EasyOCR je hotová OCR knihovna od JaidedAI pro Python: pip install easyocr, dva řádky kódu a text vložený do obrázku se vrátí jako řetězce. Je licencovaná pod Apache-2.0, podporuje více než 80 jazyků a funguje jako pipeline dvou modelů v PyTorch — detektor CRAFT kreslí rámečky kolem všeho, co považuje za text, a pak následně rozpoznávač přečte znaky uvnitř každého boxu. Předtrénované váhy se stáhnou samy při prvním použití. Svou povahou jde o self-hostovanou alternativu k Tesseract a PaddleOCR, ne o cloudové OCR API účtované po stránkách.
Základní API je krátké: Reader(['en']), pak readtext(). Nasazení je ale těžší — v tomto prostředí asi 2 GB PyTorch a zhruba gigabajt špičkové rezidentní paměti v čerstvém procesu. Vyrenderoval jsem 36 anglických PNG fixture souborů, spustil easyocr 1.7.2 na CPU a vyhodnotil výstupy znak po znaku proti vygenerované ground truth. Největší propady CER způsobila velikost a orientace; dashboard zároveň odhalil problémy s detekcí krátkých tokenů a s rozpoznáváním znaku dolaru.
Nejpřekvapivější z těchto selhání se týká jednoho parametru, který všichni doporučují. rotation_info má na issue trackeru pověst toho řešení pro otočené obrázky, takže dostal tři navzájem kolmo otočené kopie stejné věty. Při 270° udělal přesně to, co slibuje, a snížil character error rate z 0.83 na 0.10. Při 180° fungoval napůl: 0.85 na 0.67, s jednou vynechanou frází. Při 90° se to zhoršilo, 0.81 na 0.92, a rozpoznávač začal vracet zrcadlový text. Stejný parametr, stejný seznam úhlů, tři různé výsledky — takže když ho zapnete, rozhodně tím nezískáte záruku, že „rotace je vyřešená“. Stejných 36 fixture souborů zároveň ukázalo ostrý práh u velikosti písma, systematické špatné čtení dolaru a jednu moji předpověď, která se ukázala jako úplně chybná.
Dva modely v jednom kabátu
EasyOCR není jeden model. Je to pipeline dvou modelů a to, která fáze selhala, zásadně mění způsob ladění.
První fáze je CRAFT, tedy detektor. Jeho jediný úkol je lokalizace — rozhodnout, kde v obrázku vůbec nějaký text je, a vrátit boxy. Nečte ani jeden znak. Druhá fáze je CRNN rozpoznávač — extrakce příznaků ResNetem, pak BiLSTM a CTC greedy decoding — který čte znaky uvnitř každého boxu. Obě části běží v PyTorch. Na CPU běží rozpoznávač standardně dynamicky kvantovaný na int8, takže je rychlejší a lehčí, než by napovídal surový počet parametrů.

Praktický důsledek: EasyOCR má dva úplně odlišné režimy selhání a každý vyžaduje jiné řešení. Když detektor vůbec nevykreslí box, nepomůže žádné ladění rozpoznávače — znaky se do pipeline nikdy nedostaly. Když box existuje, ale řetězec je špatně, jde o problém rozpoznávání a může pomoci preprocessing. Téměř každý thread typu „EasyOCR mi přehlédl text“, který jsem četl, tyto dvě věci zaměňuje.
Aktuální stav projektu, zkontrolovaný 27. července 2026: 29 825 hvězdiček, 528 otevřených issue, Apache-2.0 a v1.7.2 ze září 2024, přičemž poslední push do masteru proběhl v prosinci 2025. Tato data sama o sobě nedokazují architektonickou stabilitu ani zdraví údržby. Před nasazením si ověřte kompatibilitu se svou Python/PyTorch verzí, nedávnou reakci maintainerů a issue související s vašimi vstupy.
OCR se často spojuje se zneužíváním CAPTCHA, ale o tohle tady nejde. Nic nebylo testováno proti a nic zde neschvaluje obcházení bot-detection výzev. Rozsah této práce je čtení textu z obrázků a screenshotů, které máte právo číst.
Co jsem měřil a co tato čísla nepokrývají
Testovací sada je 36 PNG souborů, které jsem vyrenderoval sám: 35 jednoriádkových obrázků pokrývajících sedm fontů, osm velikostí, sedm úrovní kontrastu, sedm úhlů sklonu, tři kolmé rotace a tři pozadí — plus jeden syntetický dashboard screenshot s 19 samostatně popsanými prvky. Každý obrázek vznikl ze stejného fixního řetězce (Sphinx of black quartz, judge my vow. 1234567890 — 48 znaků, smíšená velikost písmen, číslice, interpunkce) ve stejném kroku, který uložil ground-truth popisek, takže obraz a štítek se fyzicky nemohou rozjet.
Přesnost měřím jako character error rate (CER): Levenshteinovu vzdálenost ve znacích dělenou délkou ground truth. CER 0 znamená bezchybný výstup. CER 0.10 znamená zhruba jednu chybu na deset znaků. Hlavní výsledek uvádím jako case-sensitive CER a vedle toho i case-insensitive, protože se ukázalo, že většina „chyb“ je právě v kapitalizaci.
Hranice jsou důležitější než samotná čísla:
- Jen angličtina. Rozpoznávač
english_g2. EasyOCR slibuje přes 80 jazyků; testoval jsem jeden. Nic z toho nevypovídá o nelatinkových písmech, tedy přesně o oblasti, kde se objevují publikovaná akademická srovnání OCR. - Jen syntetika. Vyrenderovaný text, ne fotografie. Žádný šum z kamery, žádné JPEG artefakty, žádné světlo, žádná perspektiva.
- Bez rukopisu. Samotný projekt uvádí rukopis jako zatím nepodporovaný.
- Jen CPU. macOS arm64,
gpu=False. Na stroji bylo k dispozici MPS, ale EasyOCR používá CPU všude tam, kde nejde o CUDA. GPU výkon jsem vůbec neměřil, takže tu nenajdete žádné GPU číslo. - Jeden stroj, jedna verze. easyocr 1.7.2, torch 2.13.0, Python 3.12.
Takže: jde o řízené křivky s jednou proměnnou, které přesně ukazují, kde se věrnost láme, a to na čistě vyrenderovaném latinském textu. Není to skóre z reálného korpusu a nenahrazuje ho.
Důkazy lze kontrolovat, nejsou schované v notebooku. Generátor fixture souborů a přesné řetězce jsou v tests/build_fixtures.py a tests/fixtures/ground_truth.json; rozpoznávání, timing a sběr zdrojů běží v tests/run_easyocr.py; a tests/metrics.py počítá uvedené chybovosti ze surového výstupu. Výsledné záznamy rozpoznávání i agregované metriky jsou uložené v artifacts/raw/. Opětovné spuštění této řetězové sady je užitečné pro kontrolu tohohle stroje a téhle verze. Stále ale neodpovídá na otázku, jak se EasyOCR zachová na fotkách z vašeho telefonu, ve vašich jazycích, rozvrženích nebo preprocessing pipeline, takže produkční přijetí by mělo přidat reprezentativní vstupy místo toho, aby tyto fixture soubory bralo jako certifikační sadu.
Jeden pastový bod v harnessu stojí za zmínku, protože téměř vytvořil špatné hlavní číslo. Můj první průchod metrikami hlásil CER 0.375 u čistého černého Arialu, což je katastrofa pro nejjednodušší možný vstup. Nebyl na vině EasyOCR. Detektor rozdělil jeden vizuální řádek na box pro slova a box pro číslice a moje naivní řazení podle y a pak x dávalo číslice dopředu. Opraveno line-aware groupingem (boxy seskupit podle vertikálního překryvu a pak číst zleva doprava), po kterém čisté fonty spadly zhruba na 0.04–0.10. Pokud si budujete vlastní OCR evaluaci, čeká na vás stejná past.
Instalace je malá, závislost ne

pip install easyocr
To je celé a je fér říct, že toho mnoho neskrývá. Samotný balíček je maličký; to, co přitahuje, je PyTorch, zhruba 2 GB. Až při prvním volání readtext() se EasyOCR tiše stáhne váhy do ~/.EasyOCR/model/ — celkem 93.7 MiB, z toho 79.30 MiB pro detektor CRAFT (craft_mlt_25k.pth) a 14.44 MiB pro anglický rozpoznávač (english_g2.pth).
V tutoriálech na to nikdo neupozorňuje, takže: první běh potřebuje přístup k síti a kvůli stahování se pozastaví, a každé kontejnerové nasazení tyto váhy buď zabalí přímo do image, nebo je stáhne při cold startu. Jakmile jsou uložené v cache, jede všechno offline.
Cold inicializace Reader() — načtení modelů z disku do RAM a navíc průchod int8 kvantizací — trvala napříč běhy 1.3–1.7 sekundy. Poté:
import easyocr
reader = easyocr.Reader(['en'], gpu=False)
result = reader.readtext('screenshot.png')
A funguje to. Dva řádky, nic ke konfiguraci, žádné shánění checkpointu. „Easy“ v názvu si tahle etapa zaslouží; tření je celé v hmotnosti závislostí, ne v API.
Čistý text: skoro dokonalé znaky, ne zcela dokonalá kapitalizace
Sedm systémových fontů, černá na bílé, 32 px, pokaždé stejný řetězec:
| Font | CER (case-sensitive) | CER (case-insensitive) |
|---|---|---|
| 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 |
| Mean | 0.0714 | 0.0238 |
Průměrná CER 0.071, po normalizaci velikosti písmen klesá na 0.024. A právě to je hlavní zjištění. EasyOCR na čistém latinském textu neztrácí znaky — správně zachytí tvar, ale plete case.
Konkrétně lowercase slovo vow vrací jako VOW v šesti ze sedmi fontů (Comic Sans se spokojí s Vow). Impact si navíc přihodí of → Of. Další opakovaná chyba je interpunkce: závěrečná tečka se v několika fontech vrací jako : nebo _. Georgia je po ignorování kapitalizace naprosto přesná.
To je velmi užitečný profil chování. Pokud je váš navazující krok fuzzy matching, fulltextové vyhledávání nebo předání textu jazykovému modelu, změna case téměř nic nestojí. Pokud ale děláte přesné porovnání proti klíči v databázi, stojí vás to všechno. Před porovnáním normalizujte case a polovina zdánlivé chybovosti EasyOCR zmizí.
To, že Courier dopadl nejhůř (0.1042), také dává smysl: monospace fonty mají nepřirozeně široké mezery, což je pro CTC dekodér, který se naučil běžné rozestupy písmen, těžší.
Prah velikosti je přesně tam, kde ho popisuje dokumentace

readtext() má zdokumentovaný parametr min_size=10, který zahazuje detekované boxy kratší než 10 pixelů. Většina lidí ho přejede pohledem. Pro kohokoli, kdo extrahuje screenshoty nebo PDF, je to nejdůležitější číslo v API, a tady je vidět, co dělá při sweepu výšky vykreslených glyphů:
| Rendered px | CER | Co se stalo |
|---|---|---|
| 8 | 0.7708 | Kolaps — boxy spadnou pod filtr min_size a jsou zahozena; přežijí jen fragmenty |
| 10 | 0.1458 | Degradace — přesně na hraně detektor rozseká řádek na 3 boxy |
| 12 | 0.0417 | Obnovení |
| 16 | 0.0000 | Bezchybný výstup |
| 20 | 0.0208 | Čisté |
| 28 | 0.0208 | Čisté |
| 40 | 0.0625 | Čisté (vrací se flip case vow → VOW) |
| 64 | 0.0625 | Čisté (flip case) |
Skok z 0.04 na 0.77 mezi 12 px a 8 px není postupná degradace. Je to filtr, který dělá přesně to, co slibuje dokumentace, a výsledkem je, že text pod zhruba 10 px je pro výchozí EasyOCR prakticky neviditelný.
Nejlepší rozsah je 12–28 px, přičemž plné CER 0 vychází při 16 px. Nad 40 px CER zase mírně roste — ne proto, že by se znaky hůř četly, ale protože se vrací flip vow → VOW. Velký text není hůř čitelný; jen už neprofituje z rozmístění, které při 16 px vyšlo dokonale.
Pro každého, kdo vytahuje text ze screenshotů: zkontrolujte výšku glyphů ještě předtím, než budete vinit model. Dashboard zachycený v 1× na HiDPI displeji nebo PDF stránka rasterizovaná na 72 DPI často dostane tělo textu pod 10 px. Zachyťte ve 2× nebo obraz před OCR zvětšete a vyhnete se celé kategorii hlášení typu „EasyOCR ignoroval polovinu stránky“. Pokud to nejde, snižte min_size — ale počítejte s šumem, protože ten filtr existuje právě proto, aby potlačil odpadní detekce.
Rotace: tolerance kolem 10° a oprava, která není symetrická
Nejprve sklon. Malé úhly, Arial 32 px, výchozí nastavení versus rotation_info=[90,180,270]:
| Úhel sklonu | CER (default) | CER (s 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 |
Výchozí EasyOCR zvládá sklon až asi 10° bez potíží (CER ≤ 0.083), ve 15° už zakolísá a kolem 20° je mimo hru. rotation_info se sklonem nic nedělá, což dává smysl, když víte, jak funguje — pouze zkouší znovu úhly, které mu zadáte, a 15° sklon není 90, 180 ani 270. Při 10° to dokonce lehce zhoršil (0.021 → 0.083), protože špatně natočený retry může vyhrát hlasování podle confidence.
Kolmé rotace jsou divné:
| Rotace | CER (default) | CER (s rotation_info) | Obnovení? |
|---|---|---|---|
| 90° | 0.8125 | 0.9167 | Ne — horší |
| 180° | 0.8542 | 0.6667 | Částečně |
| 270° | 0.8333 | 0.1042 | Ano |
Stejný parametr. Stejný seznam úhlů. Tři různé výsledky.
Při 270° rotation_info dělá přesně to, co slibuje issue thread: CER spadne z 0.83 na 0.10, což je skutečně použitelné čtení. Při 180° funguje jen napůl — CER se zlepší na 0.67, ale fráze my vow. úplně vypadne. Při 90° se to obrátí proti vám, z 0.81 na 0.92, a surový výstup ukazuje proč: rozpoznávač vrací zrcadlové řetězce. VOW se vrátí jako MOA. quartz se vrátí jako zuuenb. Když to přečtete v zrcadle, je to správně, což je sice roztomilý trik, ale k datové pipeline nepoužitelný.
Kontroloval jsem to proti surovým predikcím, ne jen proti agregované metrike, protože „promíchalo se pořadí spojování“ byla moje první podezřelá příčina. Není to artefakt joinu — takhle to EasyOCR skutečně vrátil.
Mechanismus je hypotéza, ne měření; žádný experiment s konvencí rotace jsem nedělal. Pillow vykresluje kladné úhly proti směru hodinových ručiček, takže jen obraz vykreslený na 270° se náhodou potká s retry orientací, kterou rozpoznávač zvládne dobře, zatímco u 90° dopadne nejlepší retry na převrácenou orientaci. Ať je důvod jakýkoliv, provozní závěr na tom nestojí:
Tato sada ukazuje, že u rotation_info nelze předpokládat symetrické chování napříč orientacemi. Ověřte rotace, které vaše vstupy skutečně používají; normalizace orientace předem je kandidát na mitigaci, ne požadavek odvozený ze tří vyrenderovaných příkladů.
Předpověď, kterou jsem trefil špatně
Předpokládal jsem, že slabý kontrast bude slabým místem EasyOCR. Bledě šedý text na bílém je klasický OCR problém a existuje k tomu i dokumentovaná záchranná cesta: contrast_ths=0.1 s adjust_contrast=0.5, která znovu spustí boxy s nízkým kontrastem na zesílené kopii a vybere výsledek s vyšší jistotou.
Nikdy se nespustila, protože nebyla potřeba.
| Šedá popředí | Weberův kontrast | CER (default) | CER (adjust_contrast=1.0) |
|---|---|---|---|
| 0 (černá) | 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 |
CER neopustí čistý pás ani při Weberově kontrastu 0.14 — šedá 220 na bílém, což je tak slabé, že jsem na fixture musel mhouřit oči, abych si potvrdil, že text tam opravdu je. A sloupec s boostem kontrastu je na každém kroku identický s defaultním sloupcem, protože default už uspěl.
Stejný příběh vyprávěla i pozadí. Černý text po celou dobu:
| Pozadí | CER |
|---|---|
| Jednolitý světle modrý panel | 0.083 |
| Vertikální gradient | 0.021 |
| Gaussovský šum (μ200, σ22) | 0.000 |
Dokonalé čtení na nejšumovějším fixture v celé sadě.
Rozsah je úzký: jde o nízký kontrast v jednobarevném, bezšumovém prostředí, ne o vyfocený účtenkový papír se šumem senzoru a JPEG kompresí. V této sadě způsobily největší chyby geometrie a krátké tokeny; testované varianty barvy a syntetického šumu ne.
Reálný scénář: vytahování čísel z dashboard screenshotu
Tohle je případ, který v Python OCR práci ve skutečnosti nejčastěji nastává. Někdo pošle screenshot interního dashboardu, nebo běžíte Python scraping pipeline proti analytické stránce plné grafů, kde čísla existují jen jako vyrenderované pixely, a vy chcete hodnoty jako data.
Vyrenderoval jsem okno „Sales Dashboard“ — tmavá hlavička s názvem a kruhovým avatar badge, tři KPI panely, tři tlačítka, tabulku 2×3 — a všech 19 textových prvků jsem označil přesnými řetězci a pixelovými boxy, pak jsem výstup EasyOCR přiřazoval podle překryvu boxů.
Recall detekce: 16 ze 19. Tři přehlédnutí:
- jednopísmenný badge, „A“
- buňka tabulky „Q1“
- buňka tabulky „Q2“
A „Q3“ detekováno bylo. Stejný font, stejná velikost, stejný sloupec — detektor nechal projít jeden dvouznakový token a dva jiné zahodil. Detekce byla nekonzistentní napříč vizuálně podobnými buňkami. Protože výstupy byly v těchto bězích deterministické, nejde o důkaz náhodného „hodu mincí“. Podobný problém kvality screenshotů je sledován v #460.
Na 16 prvcích, které našel, byl text téměř dokonalý: průměrná CER 0.027, s 13 z 16 přesně. Titulky, popisky, tlačítka („Save“, „Cancel“, „Export CSV“), záhlaví sloupců i čísla s oddělovači tisíců se vrátily s CER 0. 1,284 bylo přečteno správně, včetně čárky.
Tři nedokonalé čtení jsou všechny stejná chyba. Částky v dolarech:
| Ground truth | EasyOCR read |
|---|---|
$57,912 | S57,912 |
$18,330 | S18,330 |
$25,178 | S25,178 |
$12,004 | $12,004 (správně) |
Tři ze čtyř znaků dolaru se změnily na velké S. Vizuálně je to skoro pochopitelné, ale znamená to, že každé měnové pole ve vašem extrakčním výstupu je jeden znak od zmetku a naivní float() na tom spadne.
Pokud vaše screenshot pipeline obsahuje krátké popisky nebo měnu, ověřte kandidátní mitigace jako zvětšení, přidání okrajů, omezená očekávání polí nebo symbol-aware postprocessing. Nic z toho jsem zde nebenchmarkoval a regex, který přepisuje počáteční S, může poškodit legitimní hodnoty. Opravy aplikujte jen tam, kde je schéma a validační pravidla činí bezpečnými.
Kolik stojí provoz
Čísla na stejném stroji (macOS arm64, CPU, jeden host, měřeno při možné souběžné zátěži — berte je jako tvar, ne jako univerzální benchmark):
| Metrika | Hodnota |
|---|---|
| Váhy modelu na disku | 93.7 MiB (79.30 detektor + 14.44 rozpoznávač) |
| Špičková rezidentní paměť, čerstvý CPU proces | 984.5 MiB |
Cold init Reader() | 1.3–1.7 s |
| Warm latency, jeden čistý řádek 48 znaků (p50) | ~0.062 s (p25–p75: 0.059–0.067 s, n=20) |
detail=0 vs detail=1 | ~stejné (medián 0.062 vs 0.063 s) |
Hlavní náklad nejsou 94 MB vah — je to zhruba gigabajt rezidentní paměti na worker proces, navíc k asi 2 GB instalaci torch. To je číslo, které rozhodne, jestli se to vejde do vašeho kontejneru, a je to číslo, které nikdo necituje.
Rychlost je pro snadný případ v pohodě. Warm pod 0.1 s pro čistý jednorádkový text na CPU je úplně použitelný. Ale to je snadný případ: jeden krátký řádek s vysokým kontrastem. Opakované stížnosti typu „EasyOCR na CPU trvá desítky sekund“ se týkají velkých dokumentů s více regiony v plné velikosti plátna, a to jsem nereprodukoval — jiný workload, a uvádím to jako citaci, ne jako tvrzení.
Jeden malý mýtus: detail=0 nezrychlí EasyOCR. Jen odstraní z návratové hodnoty boxy a confidence skóre. Výpočet už proběhl. Mediány se liší o milisekundu, což je šum.
Klady a zápory
Klady
- Na čistě vyrenderovaném latinském textu je záchyt znaků v podstatě perfektní — průměrná CER 0.071 case-sensitive, 0.024 case-insensitive, a při 16 px lze dosáhnout plně nulové CER.
- Opravdu dvouřádkové API.
Reader(['en'])a pakreadtext(), bez konfigurace, bez výběru modelu. - Mnohem robustnější vůči kontrastu, než se traduje: žádný kolaps až do Weber 0.14 na čistém textu a barevná/gradientní/šumová pozadí výkon nezhoršila (fixture s gaussovským šumem byla přečtena bezchybně).
- Téměř dokonalý na prvcích screenshotu, které detekuje: průměrná CER 0.027, 13 z 16 přesně, včetně čísel s oddělovači tisíců.
- Deterministický. Všechna přesnostní čísla zde byla byteově identická ve dvou zcela nezávislých bězích procesu; měnil se jen čas.
- Apache-2.0 a self-hosted, bez poplatku za použití u vendorů; náklady jsou jen výpočet, paměť, úložiště a frontování.
Zápory
- Tvrdý kolaps pod dokumentovanou hranicí
min_size=10— CER 0.77 při 8 px. Malý UI text je defaultně neviditelný. - Tolerance sklonu končí zhruba na 10° a kolem 20° se to láme.
rotation_infonení symetrická oprava: 270° obnoví, 180° částečně, 90° zhorší situaci a vrací zrcadlový text.- Detektor zahazuje izolované krátké tokeny — jednopísmenný badge a dvě dvouznakové buňky, přestože třetí buňku se stejným formátem nechá projít.
- Systematické špatné čtení
$jakoSu měnových hodnot (3 ze 4). - Zhruba 1 GB rezidentní paměti na proces, plus asi 2 GB závislosti torch.
- Nejnovější release je ze září 2024; projekt je spíš stabilní než aktivně se vyvíjející.
Kdo by to měl použít a kdo by měl jít dál
EasyOCR má smysl testovat, když jsou vaše vstupy čisté, správně natočené a vykreslené v rozumné velikosti — screenshoty, UI výřezy, rastrové PDF nebo generované reporty — a chcete self-hostovanou Python pipeline bez poplatku za vendor usage. Syntetické anglické CPU výsledky platí právě pro tuto oblast; fotografie, rukopis a jiné skripty vyžadují samostatné testování.
Dejte od toho ruce pryč, pokud vaše vstupy vypadají jinak. Fotografie — moje čísla jsou pro synteticky vyrenderovaný text a nic neříkají o šumu kamery, perspektivě nebo světle. Rukopis — samotný projekt to netvrdí. Nelatinkové skripty — EasyOCR podporuje přes 80 jazyků, ale testoval jsem jeden a publikovaná akademická srovnání jsou zde relevantnější než syntetický anglický sweep. Libovolně otočené vstupy — pokud si nejdřív neuděláte vlastní korekci orientace. Nasazení s omezenou pamětí — gigabajt na worker se rychle nasčítá.
Než zvolíte OCR, zkontrolujte DOM a network response. Pokud požadované hodnoty už existují jako strukturovaný text, extrakce z tohoto zdroje obejde detekční i rozpoznávací chyby OCR. OCR patří tam, kde jsou pixely jedinou dostupnou reprezentací.
Alternativy a kam zapadá náš stack
EasyOCR je Apache-2.0 a self-hosted, bez poplatku za vendor usage, ale s reálnými náklady na výpočet a provoz. PaddleOCR, Tesseract ani vision-language modely tímto benchmarkem neprošly, takže zde nedělám žádný přímý head-to-head závěr.
Zajímavější než OCR proti OCR je otázka, jestli byste OCR vůbec měli dělat.
Většina práce s extrakcí ze screenshotů, kterou vidím, je workaround pro web, který se špatně scrapoval — JavaScriptem renderovaná tabulka, dashboard za loginem, web, který se brání. Udělat screenshot a pak z něj OCR působí jako nejjednodušší cesta, ale zahodíte tím perfektně použitelný strukturovaný text a pak platíte „daň“ v podobě dolaru navíc za horší verzi téhož.
Poznámka autora: Thunderbit je naše spravovaná možnost pro extrakci z webových stránek. Nebyla testována na těchto image fixtures. Rozhodující hranice je reprezentace zdroje: použijte DOM/network extrakci, když strukturovaná webová data existují, a OCR testujte až tehdy, když jsou pixely jediným zdrojem.
Související čtení ze stejného testovacího prostředí: úplné srovnání open-source scraperů, recenze Crawl4AI a širší pohled na AI-driven extraction pro stránky, které se brání selektorům.
Vyzkoušejte Thunderbit pro extrakci webových dat
Verdikt
Máte používat EasyOCR? Ano, pokud jsou vaše obrázky správně natočené, glyphy mají alespoň 12 pixelů na výšku a čtete latinku. V těchto podmínkách je velmi dobrý — průměrná CER 0.071 na čistém textu, 0.024 po normalizaci case, bezchybný výstup při 16 px a lepší odolnost vůči kontrastu, než se o něm tvrdí. API je opravdu na dva řádky a výstup je deterministický, což je při ladění pipeline důležitější, než se běžně přiznává.
Mimo tyto hranice selhává konkrétními, naučitelnými způsoby. Text pod 10 px zmizí do filtru min_size. Sklon nad 20° čtení rozbije. rotation_info opraví jednu kolmou orientaci, druhou jen napůl a třetí zhorší zrcadlovým textem. Jednopísmenné a dvouznakové tokeny vypadnou z detektoru, zatímco sousedé přežijí. Znak dolaru se mění na písmeno S.
Selhání v této sadě přišla z obou fází: chybějící nebo špatně orientované boxy na geometrické straně a záměna dolaru na straně rozpoznávání. Zvětšení, normalizaci orientace, přidání okrajů a symbol-aware opravy schématu berte jako kandidáty k ověření, ne jako univerzálně bezpečné fixy.
Jen to netestujte tak jako já téměř — s rozbitým eval harness a číslem, kterému nerozumíte. Vyrenderujte si vlastní fixture soubory, přesně znáte ground truth a najděte si vlastní práh.
Vyzkoušejte Thunderbit pro extrakci webových dat Get Started Free
FAQ
Je EasyOCR dost přesný pro produkční extrakci textu ze screenshotů?
Na syntetickém dashboardu měly porovnané prvky průměrnou CER 0.027 a 13 z 16 bylo přesně. Tři z 19 prvků nebyly detekovány a tři ze čtyř znaků dolaru se změnily na S. Jestli je to přijatelné — a jestli pomůže zvětšení nebo schema-aware oprava — je potřeba ověřit na cílových layoutových vzorcích.
Jaká je nejmenší velikost písma, kterou EasyOCR přečte?
V praxi zhruba 12 pixelů výšky glyphu. Parametr min_size=10 v readtext() zahazuje detekované boxy kratší než 10 px a efekt je spíš skok než pozvolný pád: CER byla 0.77 při 8 px, 0.15 při 10 px, 0.04 při 12 px a 0 při 16 px. Čisté pásmo v mém sweepu bylo 12–28 px. Pokud je váš zdroj HiDPI screenshot pořízený v 1× nebo PDF rasterizované na 72 DPI, před OCR raději zvětšete obraz, než abyste snižovali min_size, protože ten filtr existuje kvůli potlačení odpadních detekcí.
Opraví rotation_info v EasyOCR otočené obrázky?
Ne spolehlivě a ne symetricky. S rotation_info=[90,180,270] na třech kolmo otočených kopiích téže věty se obraz v 270° obnovil čistě (CER 0.83 → 0.10), 180° jen částečně (0.85 → 0.67, s vynechanou frází) a 90° se zhoršil (0.81 → 0.92) a vracel zrcadlový text jako VOW → MOA. Navíc to nedělá nic pro malé úhly sklonu, protože zkouší jen úhly, které mu zadáte. Správnou orientaci proto opravte ještě před voláním EasyOCR, nespoléhejte na tento parametr.
Kolik paměti a místa na disku EasyOCR potřebuje?
Váhy mají 93.7 MiB a při prvním použití se stáhnou do ~/.EasyOCR/model/ — 79.30 MiB pro detektor a 14.44 MiB pro anglický rozpoznávač. Špičková rezidentní paměť v měřeném čerstvém CPU procesu byla 984.5 MiB, navíc k přibližně 2 GB instalaci torch. Cold inicializace readeru trvala 1.3–1.7 sekundy; čistý jednorádkový text pak běžel na tomto stroji s p50 kolem 0.062 sekundy. detail=0 změnil tvar návratové hodnoty, ne naměřený čas běhu.
Je EasyOCR zdarma pro komerční použití a je pořád udržovaný? Má licenci Apache-2.0, která je permisivní a komerčně přívětivá. K 27. červenci 2026 má repozitář 29 825 hvězdiček a 528 otevřených issue, nejnovější release je v1.7.2 ze září 2024 a poslední push do masteru proběhl v prosinci 2025. Čtěte to jako stabilní, ne jako opuštěné — architektura se už nějakou dobu nemění a aktivita se přesunula hlavně do issue trackeru. Před použitím si sami ověřte aktuální licenci a stav releasů.


