Обзор EasyOCR: отличные результаты на чистом тексте, резкий порог по размеру и CPU‑процесс на 1 ГБ

Последнее обновление: August 17, 2026
Обзор EasyOCR: отличные результаты на чистом тексте, резкий порог по размеру и CPU‑процесс на 1 ГБ
AI-сводка
EasyOCR — готовая OCR-библиотека JaidedAI для Python: pip install easyocr, две строки кода — и текст, встроенный в изображение, возвращается в виде строк. Библиотека распространяется под лицензией Apache-2.0, заявляет поддержку 80+ языков и работает как конвейер из двух моделей PyTorch: детектор CRAFT обводит рамками всё, что считает текстом, а распознаватель читает символы внутри каждого блока. Предобученные веса скачиваются автоматически при первом запуске. По сути это self-hosted альтернатива Tesseract и PaddleOCR, а не облачный OCR API с оплатой за страницу.

EasyOCR — это готовая к работе OCR-библиотека JaidedAI для Python: pip install easyocr, две строки кода — и текст, встроенный в изображение, возвращается в виде строк. Библиотека распространяется под лицензией Apache-2.0, заявляет поддержку 80+ языков и работает как конвейер из двух моделей PyTorch: детектор CRAFT обводит рамками всё, что считает текстом, а распознаватель читает символы внутри каждого блока. Предобученные веса скачиваются автоматически при первом запуске. По сути это self-hosted альтернатива Tesseract и PaddleOCR, а не облачный OCR API с оплатой за страницу.

Базовый API очень короткий: Reader(['en']), затем readtext(). Но деплой оказывается куда тяжелее — около 2 ГБ PyTorch в этой среде и примерно 1 ГБ пикового resident memory у свежего процесса. Я отрендерил 36 английских PNG-файлов, прогнал easyocr 1.7.2 на CPU и оценивал результат посимвольно по сравнению с сгенерированным эталоном. Наибольшие провалы CER были связаны с размером текста и ориентацией; дашборд также показал проблемы с короткими токенами и распознаванием знака доллара.

Самый показательный из этих сбоев связан с параметром, который советуют чаще всего. У rotation_info на issue tracker репутация главного решения для повернутых изображений, поэтому я дал ему три копии одной и той же фразы, повернутые по ортогональным осям. При 270° он сработал именно так, как обещано: character error rate упал с 0.83 до 0.10. При 180° он сработал лишь частично: 0.85 до 0.67, при этом фраза частично пропала. При 90° стало хуже: 0.81 до 0.92, а распознаватель начал выдавать зеркальный текст. Один и тот же параметр, один и тот же список углов, три разных результата — так что включение этой опции не означает, что «поворот теперь обработан». На тех же 36 файлах также проявился жесткий порог по размеру шрифта, систематическая ошибка в распознавании $ и одно мое предсказание, которое оказалось полностью неверным.

Две модели под одним пальто

EasyOCR — это не одна модель. Это конвейер из двух, и понимание того, на каком этапе произошел сбой, меняет способ отладки.

Первый этап — CRAFT, то есть детектор. Его задача — только локализация: определить, где на изображении вообще есть текст, и вернуть рамки. Он не читает ни одного символа. Второй этап — CRNN recognizer: извлечение признаков ResNet, затем BiLSTM, затем жадное декодирование CTC — именно он читает символы внутри каждой рамки. Обе части работают на PyTorch. На CPU распознаватель по умолчанию запускается с динамической int8-квантованием, поэтому он быстрее и легче, чем подсказывает голый размер параметров.

System diagram: Detection Before Recognition

Практический вывод такой: у EasyOCR есть два совершенно разных режима отказа, и лечатся они по-разному. Если детектор вообще не нарисовал рамку, никакая настройка распознавателя не поможет — символы просто не попали в конвейер. Если рамка есть, но строка распознана неверно, это уже проблема recognition, и тут может помочь препроцессинг. Почти в каждом треде вида «EasyOCR пропустил мой текст», который я видел, эти два случая смешивают.

Текущее состояние проекта, проверено 27 июля 2026 года: 29 825 звезд, 528 открытых issues, Apache-2.0 и v1.7.2 от сентября 2024 года, а последняя отправка в master была в декабре 2025-го. Эти даты не доказывают ни архитектурной стабильности, ни здоровья поддержки. Перед внедрением проверьте совместимость с вашим Python/PyTorch-стеком, актуальность реакции мейнтейнеров и issues, относящихся к вашим входным данным.

OCR часто ассоциируют с обходом CAPTCHA, но в этом обзоре речь не о таком сценарии. Ничего не тестировалось на обходе антибот-защиты, и этот материал ничего подобного не одобряет. Здесь задача — читать текст из изображений и скриншотов, которые вам разрешено читать.

Что я измерял, и чего эти цифры не показывают

Набор тестов — это 36 PNG, которые я сгенерировал сам: 35 однострочных изображений, покрывающих семь шрифтов, восемь размеров, семь уровней контраста, семь углов наклона, три ортогональных поворота и три фона, плюс один синтетический скриншот дашборда с 19 отдельно размеченными элементами. Каждое изображение было построено из одной и той же строки (Sphinx of black quartz, judge my vow. 1234567890 — 48 символов, смешанный регистр, цифры, пунктуация) в том же проходе, где записывалась эталонная разметка, так что картинка и подпись физически не могут «разъехаться».

Точность измерялась через character error rate (CER): расстояние Левенштейна по символам, деленное на длину эталона. CER 0 означает идеальное чтение. CER 0.10 означает, что примерно каждый десятый символ ошибочен. В заголовке я привожу CER с учетом регистра, а рядом — без учета регистра, потому что выяснилось, что большая часть «ошибки» сидит именно в регистре.

Границы важнее чисел:

  • Только английский. Распознаватель english_g2. EasyOCR заявляет 80+ языков; я тестировал один. Это ничего не говорит о нелатинских письменностях, а именно там обычно и живут академические сравнения OCR.
  • Только синтетика. Отрисованный текст, не фотографии. Никакого шума камеры, JPEG-артефактов, освещения или перспективы.
  • Без рукописного текста. Сам проект прямо указывает, что handwriting пока не поддерживается.
  • Только CPU. macOS arm64, gpu=False. На машине был доступен MPS, но EasyOCR использует CPU на всем, что не CUDA. Производительность GPU не измерялась, поэтому здесь нет ни одного GPU-числа.
  • Одна машина, одна версия. easyocr 1.7.2, torch 2.13.0, Python 3.12.

Итого: это контролируемые кривые с одной переменной, которые показывают, где именно начинает ломаться качество на чистом отрисованном латинском тексте. Это не реальный производственный бенчмарк и не замена ему.

Проверить это можно не только по моим словам: генератор фикстур и точные строки лежат в tests/build_fixtures.py и tests/fixtures/ground_truth.json; распознавание, тайминг и сбор ресурсов — в tests/run_easyocr.py; а tests/metrics.py считает итоговые error rate из сырого вывода. Получившиеся записи распознавания и агрегированные метрики сохранены в artifacts/raw/. Повторный запуск полезен, чтобы проверить эту конкретную машину и версию. Но он всё равно не отвечает на вопрос, как EasyOCR поведет себя на фото с телефона, других языках, макетах или в вашем собственном пайплайне препроцессинга — для production-решения нужны репрезентативные входы, а не эти фикстуры как сертификат.

Одна ловушка в harness почти привела к неверному заголовочному числу. В первом проходе метрик я получил CER 0.375 на чистом черном Arial — ужасный результат для самого простого входа. Но проблема была не в EasyOCR. Детектор разделил одну визуальную строку на рамку со словами и рамку с цифрами, а мой наивный merge «сортировать по y, потом по x» ставил цифры впереди. После исправления на line-aware grouping (группировка рамок по вертикальному перекрытию с последующим чтением слева направо) чистые шрифты стали давать примерно 0.04–0.10. Если вы строите собственную оценку OCR, эта ловушка поджидает и вас.

Установка: пакет небольшой, зависимость — нет

System diagram: Setup: the install is small, the dependency is not

pip install easyocr

Вот и всё. Но это честно только наполовину. Сам пакет действительно крошечный, а вот что он тянет за собой — это PyTorch, примерно 2 ГБ. Затем при первом вызове readtext() EasyOCR незаметно скачивает веса в ~/.EasyOCR/model/ — 93.7 MiB всего, из них 79.30 MiB на детектор CRAFT (craft_mlt_25k.pth) и 14.44 MiB на английский распознаватель (english_g2.pth).

В учебниках об этом обычно не предупреждают, так что: при первом запуске нужен доступ в сеть, а каждый контейнерный деплой либо встраивает эти веса в образ, либо платит за скачивание на cold start. После кэширования всё работает офлайн.

Холодная инициализация Reader() — загрузка моделей с диска в RAM плюс проход динамической квантования int8 — занимала 1.3–1.7 секунды в разных запусках. После этого:

import easyocr
reader = easyocr.Reader(['en'], gpu=False)
result = reader.readtext('screenshot.png')

И всё работает. Две строки, ничего настраивать не нужно, не нужно искать checkpoint. Название «easy» на этом этапе вполне оправдано — вся боль сидит в весе зависимостей, а не в API.

Порог на чистом тексте: почти идеальные символы, но с ошибками в регистре

Семь системных шрифтов, черный текст на белом фоне, 32 px, одна и та же строка каждый раз:

ШрифтCER (с учетом регистра)CER (без учета регистра)
Georgia0.06250.0000
Times0.04170.0417
Comic Sans0.04170.0208
Arial0.08330.0208
Verdana0.08330.0208
Impact0.08330.0208
Courier0.10420.0417
Среднее0.07140.0238

Средний CER — 0.071, а если нормализовать регистр, то падает до 0.024. Это и есть главный вывод. EasyOCR не теряет символы на чистом латинском тексте — он правильно угадывает форму, но ошибается в регистре.

В частности, слово vow в нижнем регистре он в шести из семи шрифтов превращает в VOW (Comic Sans компромиссно дает Vow). Impact в придачу меняет of на Of. Еще одна повторяющаяся ошибка — пунктуация: финальная точка в конце предложения в нескольких шрифтах возвращается как : или _. Georgia дает идеальное чтение, если не обращать внимания на регистр.

Это действительно полезно понимать. Если дальше у вас fuzzy matching, поиск по ключевым словам или подача текста в LLM, смена регистра почти ничего не стоит. Если же следующий шаг — точное сравнение строки с ключом в базе, то это уже ломает всё. Нормализуйте регистр до сравнения, и половина кажущейся ошибки EasyOCR исчезает.

Courier оказался худшим (0.1042) тоже неслучайно: моноширинные шрифты делают интервалы между символами неестественно широкими, а CTC-декодеру, который обучался на типичном межсимвольном расстоянии, это тяжелее.

Резкий порог по размеру совпадает ровно с тем, что написано в документации

Measured results chart: Character error rate by glyph height

У readtext() есть документированный параметр min_size=10, который отбрасывает рамки высотой менее 10 пикселей. Большинство просто пролистывает его. А зря — это, пожалуй, самое важное число в API для тех, кто извлекает данные из скриншотов или PDF. Вот что происходит при изменении высоты символов:

Отрисованная высота, pxCERЧто произошло
80.7708Обвал — рамки попали ниже фильтра min_size и были отброшены; сохранились только фрагменты
100.1458Деградация — прямо на пороге детектор разбил строку на 3 рамки
120.0417Восстановление
160.0000Идеальное чтение
200.0208Чисто
280.0208Чисто
400.0625Чисто (снова проявляется ошибка регистра)
640.0625Чисто (ошибка регистра)

Прыжок с 0.04 до 0.77 между 12 px и 8 px — это не плавное ухудшение. Это фильтр, который делает именно то, что у него написано в документации, и в результате текст ниже примерно 10 px для стандартного EasyOCR фактически становится невидимым.

Оптимальная зона — 12–28 px, а полный CER 0 достигается при 16 px. Выше 40 px CER немного растет — не потому, что символы теряются, а потому, что возвращается замена vow → VOW. Большой текст не сложнее читать; он просто уже не получает выгоду от того межсимвольного расстояния, при котором 16 px срабатывали идеально.

Если вы извлекаете текст из скриншотов, сначала проверьте высоту символов, а уже потом обвиняйте модель. Дашборд, снятый в 1× на HiDPI-дисплее, или PDF-страница, растеризованная в 72 DPI, очень часто опускают основной текст ниже 10 px. Сделайте захват в 2× или увеличьте изображение перед OCR — и вы сразу избежите целого класса жалоб «EasyOCR проигнорировал половину страницы». Если это невозможно, уменьшайте min_size, но ожидайте шум, потому что сам фильтр существует именно для подавления мусорных детекций.

Поворот: 10° терпимости и несимметричное решение

Сначала — наклон. Малые углы, Arial 32 px, стандартные настройки против rotation_info=[90,180,270]:

Угол наклонаCER (по умолчанию)CER (с rotation_info)
0°0.08330.0833
5°0.04170.0417
10°0.02080.0833
15°0.29170.3750
20°0.75000.7708
30°0.89580.8750
45°0.89580.8750

Стандартный EasyOCR спокойно переваривает наклон примерно до 10° (CER ≤ 0.083), начинает шататься на 15° и разваливается уже к 20°. rotation_info не помогает при наклоне, и это логично: он просто повторяет попытку на углах из списка, а 15° — это не 90, 180 или 270. При 10° он даже немного ухудшил результат (0.021 → 0.083), потому что неверный повтор может выиграть по confidence.

А вот ортогональные повороты ведут себя странно:

ПоворотCER (по умолчанию)CER (с rotation_info)Восстановилось?
90°0.81250.9167Нет — стало хуже
180°0.85420.6667Частично
270°0.83330.1042Да

Один и тот же параметр. Один и тот же список углов. Три разных результата.

При 270° rotation_info делает ровно то, что обещает issue thread: CER падает с 0.83 до 0.10, и чтение становится реально пригодным. При 180° он работает лишь наполовину — CER улучшается до 0.67, но фраза my vow. полностью выпадает. При 90° становится хуже: с 0.81 до 0.92, и сырой вывод объясняет почему: распознаватель возвращает зеркальные строки. VOW превращается в MOA. quartz становится zuuenb. Если прочитать это в зеркале, оно корректно — забавный фокус, но бесполезный для пайплайна данных.

Я сверялся с сырыми предсказаниями, а не только с агрегированными метриками, потому что первой гипотезой было «у меня сломался порядок объединения». Но нет — именно так EasyOCR и вернул результат.

Механизм здесь — гипотеза, а не измерение; эксперимент с конвенцией поворота не проводился. Pillow рисует положительные углы против часовой стрелки, так что только изображение, отрендеренное под 270°, случайно совпадает с ориентацией повторной попытки, которую распознаватель обрабатывает хорошо, а в случае 90° лучшая по confidence повторная попытка попадает в перевернутую ориентацию. Как бы там ни было, практический вывод от этого не зависит:

Эта фикстура показывает, что rotation_info нельзя считать симметрично работающим для разных ориентаций. Проверяйте именно те повороты, которые бывают в ваших входных данных; нормализация ориентации до вызова — возможная мера, а не обязательное требование, доказанное тремя отрендеренными примерами.

Предсказание, в котором я ошибся

Изначально я ожидал, что слабый контраст станет ахиллесовой пятой EasyOCR. Бледно-серый текст на белом фоне — классический сценарий OCR-ошибок, и для него даже есть описанный способ спасения: contrast_ths=0.1 с adjust_contrast=0.5, который заново прогоняет низкоконтрастные блоки через усиленную копию и оставляет более уверенный результат.

Но этот механизм ни разу не включился — просто потому, что в нем не было необходимости.

Серый цвет текстаКонтраст ВебераCER (по умолчанию)CER (adjust_contrast=1.0)
0 (черный)1.0000.08330.0833
640.7490.08330.0833
1100.5690.08330.0833
1500.4120.10420.1042
1800.2940.06250.0625
2000.2160.04170.0417
2200.1370.04170.0417

CER ни разу не выходит из «чистой» зоны, вплоть до Weber 0.14 — серый 220 на белом, настолько бледный, что мне пришлось прищуриться, чтобы убедиться, что текст вообще есть. И колонка с усилением контраста везде идентична колонке по умолчанию, потому что по умолчанию всё уже и так сработало.

Фоны показали ту же картину. Черный текст везде:

ФонCER
Однотонная светло-синяя панель0.083
Вертикальный градиент0.021
Гауссов шум (μ200, σ22)0.000

Идеальное чтение на самой шумной фикстуре из набора.

Но область применения здесь узкая: это низкий контраст на однотонном фоне без шума, а не сфотографированный чек с шумом сенсора и JPEG-сжатием. В этом наборе сильнее всего ломали систему геометрия и короткие токены; протестированные варианты по цвету и синтетическому шуму — нет.

Реальный сценарий: вытаскиваем числа из скриншота дашборда

Именно так обычно выглядит основная масса OCR-задач в Python. Кто-то присылает скриншот внутреннего дашборда, или вы строите Python scraping pipeline для аналитической страницы с графиками, где числа существуют только как отрисованные пиксели, и вам нужны значения как данные.

Я отрендерил окно «Sales Dashboard» — темный хедер с заголовком и круглым бейджем-аватаром, три KPI-панели, три кнопки, таблицу 2×3 — и разметил все 19 текстовых элементов их точными строками и пиксельными рамками, после чего сопоставил вывод EasyOCR с этими объектами по пересечению рамок.

Recall детекции: 16 из 19. Три пропуска:

  • однобуквенный бейдж «A»
  • ячейка таблицы «Q1»
  • ячейка таблицы «Q2»

А вот «Q3» детектировался. Один и тот же шрифт, один и тот же размер, один и тот же столбец — детектор оставил один двухсимвольный токен и пропустил два других. Детекция в визуально очень похожих ячейках была непоследовательной. Поскольку в этих прогонах результаты были детерминированными, это не похоже на случайный эффект «подброса монетки». Схожая проблема качества скриншотов обсуждается в #460.

На тех 16 элементах, которые он все-таки нашел, текст был почти идеальным: средний CER 0.027, при этом 13 из 16 были распознаны без ошибок. Заголовки, подписи, кнопки («Save», «Cancel», «Export CSV»), заголовки столбцов и числа с запятыми возвращались с CER 0. 1,284 было распознано правильно, включая запятую.

Три неточных результата — это одна и та же ошибка. Суммы в долларах:

ЭталонEasyOCR прочитал
$57,912S57,912
$18,330S18,330
$25,178S25,178
$12,004$12,004 (верно)

Три из четырех знаков доллара превратились в заглавную S. Визуально это можно понять, но для извлечения данных это означает, что каждое валютное поле находится в одном символе от мусора, а наивный float() на этом упадет.

Если в вашем screenshot-пайплайне есть короткие подписи или валюты, проверьте возможные меры: увеличение масштаба, padding у crop, ограничения по ожидаемому формату поля или постобработку с учетом символов. Здесь ничего из этого не бенчмаркалось, и regex, который заменяет начальную S, может испортить корректные значения. Исправления применяйте только там, где это безопасно по схеме и правилам валидации.

Сколько стоит запуск

Цифры на той же машине (macOS arm64, CPU, один хост, измерение под возможной параллельной нагрузкой — воспринимайте это как форму, а не как универсальный бенчмарк):

МетрикаЗначение
Веса модели на диске93.7 MiB (79.30 детектор + 14.44 распознаватель)
Пиковый resident memory, свежий CPU-процесс984.5 MiB
Холодная инициализация Reader()1.3–1.7 с
Теплая задержка, одна чистая строка из 48 символов (p50)~0.062 с (p25–p75: 0.059–0.067 с, n=20)
detail=0 против detail=1почти одинаково (0.062 против 0.063 с по медиане)

Главная цена здесь не в 94 МБ весов, а в примерно 1 ГБ resident memory на каждый worker-процесс поверх примерно 2 ГБ установки torch. Именно это решает, влезет ли всё в контейнер, и именно это обычно никто не озвучивает.

Скорость на простом кейсе нормальная. Warm-режим ниже 0.1 с для чистой однострочной строки на CPU — это вполне рабочий сценарий. Но это и есть простой кейс: одна короткая высококонтрастная строка. Жалобы вида "EasyOCR takes tens of seconds on CPU" относятся к большим многообластным документам в полном размере canvas, и я этого не воспроизводил — это другой workload, и я просто ссылаюсь на него, а не утверждаю, что повторил.

Небольшой миф, который стоит развеять: detail=0 не ускоряет EasyOCR. Он просто убирает из результата рамки и confidence-score. Вычисления уже выполнены. Разница в медиане — около миллисекунды, то есть шум.

Плюсы и минусы

Плюсы

  • Распознавание символов на чистом отрисованном латинском тексте практически идеальное — средний CER 0.071 с учетом регистра и 0.024 без учета, а полный CER 0 достигается уже при 16 px.
  • По-настоящему двухстрочный API. Reader(['en']), затем readtext(), без настройки и выбора моделей.
  • Намного устойчивее к низкому контрасту, чем принято думать: на чистом тексте не было обвала даже при Weber 0.14, а шумный/градиентный/цветной фон не ухудшал результат (файл с гауссовым шумом был прочитан идеально).
  • Почти идеален на элементах скриншота, которые удалось детектировать: средний CER 0.027, 13 из 16 без ошибок, включая числа с запятыми.
  • Детерминированность. Все численные результаты здесь были байт-в-байт одинаковыми в двух независимых прогонах процесса; менялось только время.
  • Apache-2.0 и self-hosted, без платы за использование у вендора; расходы — это вычисления, память, хранение и очереди.

Минусы

  • Жесткий провал ниже документированного порога min_size=10 — CER 0.77 при 8 px. Мелкий UI-текст по умолчанию просто не виден.
  • Устойчивость к наклону заканчивается примерно на 10° и рушится к 20°.
  • rotation_info — несимметричное решение: 270° восстанавливается, 180° — частично, а 90° становится хуже и возвращает зеркальный текст.
  • Детектор теряет изолированные короткие токены — однобуквенный бейдж и две ячейки по 2 символа, хотя соседние блоки остаются.
  • Систематическая ошибка $ → S на валютных значениях (3 из 4).
  • Около 1 ГБ resident memory на процесс плюс зависимость torch примерно на 2 ГБ.
  • Последний релиз — сентября 2024 года; проект скорее стабилен, чем активно развивается.

Кому стоит использовать, а кому лучше отказаться

Проверяйте EasyOCR, если ваши входы — это чистый, ровный, отрисованный текст разумного размера: скриншоты, UI-кадры, растеризованные PDF или сгенерированные отчеты, и вам нужен self-hosted Python-пайплайн без платы за использование у вендора. Результаты на синтетическом английском CPU относятся именно к этому сценарию; фотографии, рукописный текст и другие письменности требуют отдельного тестирования.

Лучше отказаться, если ваши входы описываются чем-то из этого. Фотографии — мои числа относятся к синтетическому отрисованному тексту и ничего не говорят о шуме камеры, перспективе или освещении. Рукописный текст — сам проект этого не обещает. Нелатинские письменности — EasyOCR поддерживает 80+ языков, но я тестировал один, а академические сравнения здесь важнее синтетического английского sweep. Как угодно повернутые входы — если только вы не делаете собственную нормализацию ориентации заранее. Деплой с жестким ограничением памяти — гигабайт на worker быстро превращается в проблему.

Перед выбором OCR сначала посмотрите на DOM и сетевые ответы. Если нужные значения уже существуют как структурированный текст, извлечение из исходника избавляет вас от ошибок детекции и распознавания OCR. OCR нужен там, где единственное доступное представление — пиксели.

Альтернативы и место нашего стека

EasyOCR — Apache-2.0 и self-hosted, без платы за использование у вендора, но с реальной стоимостью вычислений и эксплуатации. PaddleOCR, Tesseract и vision-language-модели через этот бенчмарк не прогонялись, поэтому сравнения лоб-в-лоб здесь нет.

Более интересное сравнение — не OCR против OCR, а вопрос, нужен ли OCR вообще.

Большая часть работы по извлечению данных из скриншотов, которую я вижу, — это обходной путь вокруг страницы, которую сложно спарсить: таблица, отрисованная JavaScript, дашборд за логином, сайт, который сопротивляется. Делать скриншот и прогонять его через OCR кажется самым простым путем, но на деле вы выбрасываете нормально структурированные данные, а затем еще и платите «налог на знак доллара», чтобы получить их худшую версию обратно.

Примечание автора: Thunderbit — наш managed-вариант для извлечения данных со страниц. Через эти image fixtures он не прогонялся. Важная граница здесь — форма исходных данных: если на веб-странице есть структурированные данные, используйте DOM/network extraction; если же источник только пиксели, тогда оценивайте OCR.

Связанное чтение из того же тестового стенда: полное сравнение open-source scraper-ов, обзор Crawl4AI и более широкий взгляд на AI-driven extraction для страниц, которые сопротивляются селекторам.

Попробовать Thunderbit для извлечения веб-данных

Вердикт

Стоит ли использовать EasyOCR? Да, если ваши изображения ровные, символы высотой хотя бы 12 пикселей, а текст — на латинице. В этих границах он очень хорош: средний CER 0.071 на чистом тексте, 0.024 после нормализации регистра, идеальное чтение при 16 px и лучшая устойчивость к контрасту, чем подсказывает его репутация. API действительно в две строки, а вывод детерминирован, что при отладке пайплайна важнее, чем многие признают.

За пределами этих границ он ломается предсказуемо и в конкретных местах. Текст ниже 10 px исчезает в фильтре min_size. Наклон больше 20° рушит чтение. rotation_info исправляет одно ортогональное положение, частично другое и делает третье хуже, выдавая зеркальный текст. Одиночные буквы и двухсимвольные токены выпадают из детектора, хотя соседние блоки остаются. Знаки доллара превращаются в букву S.

Ошибки в фикстурах возникали на обоих этапах: и из-за пропущенных или неправильно ориентированных рамок на стороне геометрии, и из-за путаницы со знаком доллара на стороне распознавания. Считайте увеличение масштаба, нормализацию ориентации, padded crops и исправление символов с учетом схемы не универсальными решениями, а кандидатами на проверку.

Только не тестируйте это так, как едва не сделал я, — с поломанным evaluation harness и числом, смысл которого вы не понимаете. Генерируйте собственные фикстуры, точно знайте свой ground truth и найдите свой собственный обрыв.

Попробовать Thunderbit для извлечения веб-данных Get Started Free

Часто задаваемые вопросы

Достаточно ли точен EasyOCR для продакшн-извлечения текста со скриншотов? На синтетическом дашборде совпавшие элементы дали средний CER 0.027, причем 13 из 16 были распознаны без ошибок. Три из 19 элементов не были детектированы, а три из четырех знаков доллара превратились в S. Приемлемо ли это — и помогут ли увеличение масштаба или исправление по схеме — нужно проверять на ваших макетах.

Какой минимальный размер шрифта читает EasyOCR? Практически — примерно 12 пикселей высоты символа. Параметр readtext() min_size=10 отбрасывает рамки ниже 10 px, и эффект здесь не плавный, а ступенчатый: CER был 0.77 при 8 px, 0.15 при 10 px, 0.04 при 12 px и 0 при 16 px. В моем sweep чистая зона была 12–28 px. Если у вас скриншот с HiDPI, снятый в 1×, или PDF, растеризованный в 72 DPI, лучше увеличить изображение до OCR, чем уменьшать min_size, потому что этот фильтр нужен именно для подавления мусорных детекций.

Исправляет ли rotation_info повернутые изображения в EasyOCR? Не всегда и несимметрично. При rotation_info=[90,180,270] на трех копиях одной и той же фразы, повернутых по ортогональным осям, изображение 270° восстановилось почти идеально (CER 0.83 → 0.10), 180° — лишь частично (0.85 → 0.67, при этом фраза частично пропала), а 90° стало хуже (0.81 → 0.92) и вернуло зеркальный текст вроде VOW → MOA. На небольшие углы наклона он тоже не влияет, потому что повторяет попытку только на указанных углах. Лучше сначала выровнять ориентацию, а уже потом вызывать EasyOCR.

Сколько памяти и диска нужно EasyOCR? Веса занимают 93.7 MiB и при первом использовании скачиваются в ~/.EasyOCR/model/ — 79.30 MiB на детектор и 14.44 MiB на английский распознаватель. Пиковый resident memory в измеренном свежем CPU-процессе был 984.5 MiB, поверх примерно 2 ГБ установки torch. Холодная инициализация reader-а занимала 1.3–1.7 секунды; одна чистая строка затем обрабатывалась с p50 около 0.062 секунды на этой машине. detail=0 меняет форму ответа, но не измеренное время выполнения.

Бесплатен ли EasyOCR для коммерческого использования и поддерживается ли он сейчас? Да, он под лицензией Apache-2.0, а значит разрешен и для коммерческого использования. По состоянию на 27 июля 2026 года в репозитории 29 825 звезд и 528 открытых issues, последний релиз — v1.7.2 от сентября 2024 года, а последняя отправка в master была в декабре 2025-го. Это скорее признак стабильности, чем заброшенности — архитектура давно не менялась, а активность сместилась в issue tracker. Перед использованием обязательно проверьте актуальные лицензию и состояние релизов сами.

Ke
Ke
Технический директор в Thunderbit | Senior Data Scientist и эксперт по ML Имея почти десятилетний опыт в машинном обучении и data science, Кэ Шэнь — выпускник Колумбийского университета и бывший Senior Data Scientist в Walmart Labs. Обладая глубокой, признанной коллегами экспертизой в Python, R, Java и статистике, он делится проверенными на практике наблюдениями о том, как переводить сложные AI-алгоритмы из теории в production-grade архитектуру.
Содержание
Thunderbit · AI-агент для веб-данных

Извлекай данные с любой страницы за 1 клик

Нам доверяют более 250 000 пользователей
доступен бесплатный тариф
От веб-страницы к таблице
Опиши, что тебе нужно, — AI-агент Thunderbit соберет это и экспортирует в Excel, Google Sheets, Airtable или Notion. Старт бесплатный.
Chrome Store Rating
PRODUCT HUNT#1 Product of the Week