CnOCR извлекает текст с фотографий, сканов, чеков, билетов и снимков экрана, находит отдельные строки, возвращает координаты текстовых областей и оценку уверенности, а для однострочных изображений запускает ускоренное распознавание без этапа детектирования.
Типовой процесс состоит из двух частей: детектор отмечает прямоугольники со словами и строками, после чего распознаватель преобразует каждый фрагмент в последовательность символов. На выходе остаются не только готовые строки, но и геометрия областей, поэтому результат можно сортировать по порядку чтения, заносить в таблицу, сопоставлять с полями документа или наносить обратно на изображение.
Работать можно через класс CnOcr в собственном сценарии, команду predict для отдельного файла или папки и HTTP-обработчик для обмена изображениями с другими системами. Выбор способа не меняет основную логику: сначала подбирают детектор и распознаватель под язык и тип кадра, затем проверяют порог уверенности на реальных образцах и только после этого включают пакетную обработку.
Скачать CnOCR
- Редактирование PDF
- Русский интерфейс
- Просто новичкам
- Нет готового PDF-импорта
- Нужна среда Python
- Модели скачиваются отдельно
Как устроен рабочий процесс CnOCR
Главный объект создаётся один раз, а затем применяется ко множеству изображений. При инициализации задаются модели распознавания и детектирования, вычислительный бэкенд, каталог весов, язык многоязычной модели и, при необходимости, сокращённый алфавит. Повторное создание объекта перед каждым файлом заметно ухудшает производительность, потому что веса приходится загружать и подготавливать заново. Для очереди документов правильнее поднять один экземпляр, прогреть его тестовым кадром и передавать ему изображения последовательно или небольшими пакетами.
Метод ocr() предназначен для кадров, где положение строк заранее неизвестно. Он принимает путь к файлу, объект изображения, массив NumPy или тензор, вызывает детектор, вырезает найденные области и отправляет их распознавателю. Каждый элемент результата содержит текст, числовую оценку уверенности и четырёхугольник положения. Если включить возврат вырезанного фрагмента, к записи добавляется изображение соответствующей строки; это удобно для журнала ошибок и ручной проверки сомнительных результатов.
Метод ocr_for_single_line() полезен, когда вход уже является одной строкой: номером, фамилией, кодом, подписью под кнопкой или заранее вырезанным полем формы. Детектор в этом режиме не нужен, поэтому исчезают ошибки разделения и сокращается время обработки. Для набора таких фрагментов используется ocr_for_single_lines(); он принимает список изображений и выполняет распознавание пакетно, что эффективнее последовательного вызова одиночной функции.
Точность итогового текста зависит от обоих этапов. Если нужная надпись вообще не попала в список областей, менять распознающую модель бессмысленно: сначала исправляют масштаб, контраст, порог детектора или его тип. Если рамка построена правильно, но символы перепутаны, тогда сравнивают распознаватели, язык, алфавит и качество самого фрагмента. Такое разделение причин экономит время при настройке и не позволяет лечить ошибку не тем параметром.

Подготовка изображения перед распознаванием
Лучший исходник сохраняет реальные контуры символов. Перед подачей в CnOCR стоит убрать крупные пустые поля, исправить поворот на 90 или 180 градусов и убедиться, что текст не пережат мессенджером до нескольких пикселей по высоте. Чрезмерное увеличение не создаёт отсутствующие детали: оно лишь растягивает размытие. Практический ориентир — добиться того, чтобы тонкие штрихи различались глазом при масштабе 100 %, а строки не слипались с фоном.
Для фотографии документа полезна коррекция перспективы. Если верхняя и нижняя границы страницы заметно сходятся, текстовые строки становятся трапециями, а высота символов меняется по ширине. Детектор может найти такие области, но распознавателю приходится работать с искажёнными фрагментами. Выравнивание четырёх углов листа до прямоугольника обычно даёт больший выигрыш, чем попытка подобрать более тяжёлую модель.
Контраст улучшайте умеренно. Жёсткая бинаризация иногда убирает серую бумагу и сетку, но вместе с ними способна удалить точки, тонкие горизонтальные штрихи и части иероглифов. Для чеков на термобумаге часто лучше локальное выравнивание освещения и небольшое повышение резкости. Для экранных снимков дополнительная обработка обычно не требуется: цифровые символы уже имеют стабильный фон и чёткие границы.
Массив NumPy должен содержать допустимую форму изображения и значения яркости в обычном диапазоне. Одноканальные и трёхканальные данные подходят для типовых сценариев, однако массив с плавающими значениями от нуля до единицы лучше заранее привести к ожидаемому масштабу. Ошибка в порядке каналов редко вызывает исключение, но может ухудшить контраст и тем самым снизить качество детектирования. При чтении через разные библиотеки проверяйте, не перепутаны ли RGB и BGR.
Не объединяйте в один гигантский холст десятки страниц. Детектор уменьшит его до рабочего размера, мелкий текст потеряет детали, а память будет расходоваться на пустые участки. Обрабатывайте страницы отдельно, присваивайте каждой номер и сохраняйте координаты относительно исходного кадра. Такой подход облегчает повторный запуск только проблемных страниц и последующую сборку единого результата.
Первый вызов из Python
Минимальный сценарий включает импорт класса, создание объекта и передачу пути к изображению. По умолчанию выбираются распознаватель общего назначения, детектор многоязычного семейства и ONNX-бэкенд. На первом запуске может понадобиться загрузка весов, поэтому начальный вызов обычно дольше последующих. После появления моделей в кэше повторные старты используют уже сохранённые файлы.
from cnocr import CnOcr
ocr = CnOcr()
result = ocr.ocr('scan.png')
for item in result:
print(item['text'], item['score'], item['position'])
В рабочем коде не стоит сразу объединять все строки через пробел. Сначала сохраните исходный список, координаты и уверенность. Геометрия понадобится, чтобы восстановить абзацы, колонки и пары поле — значение. Простое склеивание подходит для однотипных чеков или экранов с одной колонкой, но на билете, анкете или удостоверении оно часто меняет порядок чтения.
Значение score удобно использовать как сигнал для контроля, а не как абсолютную гарантию правильности. Порог выбирают на собственном наборе: собирают корректные и ошибочные строки, строят распределение оценок и назначают уровень, ниже которого запись отправляется на проверку. Слишком высокий порог выбросит короткие, но правильные подписи; слишком низкий пропустит уверенно распознанные замены похожих символов.
Позиция обычно представлена четырьмя точками, а не только левым верхним углом и шириной. Благодаря этому можно сохранить наклон строки и нарисовать точный многоугольник поверх исходника. Для сортировки вычисляют центр области, среднюю высоту и границы по осям. При сильном наклоне сравнение только координаты верхней точки даёт нестабильный порядок, поэтому лучше использовать центр и допуск, связанный с высотой строки.
Возврат вырезанных строк
Параметр return_cropped_image=True добавляет к каждому результату фрагмент, который реально увидел распознаватель. Это один из самых полезных режимов при отладке. Если в вырезке отсутствует начало слова, проблема находится в рамке детектора; если вырезка выглядит хорошо, а текст неверен, нужно менять распознаватель, язык или словарь. Фрагменты можно складывать по папкам верно, ошибка и сомнение, формируя набор для последующей оценки или дообучения.
При сохранении вырезок используйте уникальные имена: номер исходного файла, индекс области и округлённую уверенность. Не называйте файл самим распознанным текстом без очистки, потому что в строке могут встретиться запрещённые для файловой системы знаки, очень длинные последовательности и одинаковые значения. Рядом полезно хранить JSON с координатами и исходным текстом, чтобы проверка не теряла связь с документом.
Однострочный режим и заранее размеченные поля
Если система уже знает прямоугольники полей, повторное детектирование добавляет лишнюю причину ошибок. Вырежьте поле по шаблону или координатам формы и передайте его в ocr_for_single_line(). Такой режим особенно уместен для номера документа, даты, итоговой суммы, кода заказа и подписи на фиксированной позиции. При одинаковом масштабе полей можно пакетировать их и получать стабильную пропускную способность.
Перед распознаванием одной строки оставляйте небольшой внешний отступ. Срезанный край первой или последней буквы модель восстановить не сможет, а слишком большой отступ уменьшит относительную высоту текста после нормализации. Практический способ — расширить рамку на несколько процентов по горизонтали и вертикали, затем проверить выборку коротких и длинных значений.
Однострочный вызов не разделяет две случайно попавшие строки. Если поле иногда переносится, либо увеличьте область и используйте обычный ocr(), либо определяйте перенос до распознавания по горизонтальному профилю пикселей. Попытка пропустить двухстрочный фрагмент через режим одной строки обычно приводит к смешанным символам, а оценка уверенности не всегда достаточно низкая, чтобы автоматически заметить ошибку.
Для цифровых полей полезен специализированный распознаватель number-densenet_lite_136-fc, рассчитанный на десять цифр. Он не должен применяться к суммам с запятой, валютным знаком или буквенным префиксом: запрещённые символы будут потеряны или заменены. Если формат содержит ограниченный набор букв и знаков, разумнее оставить универсальную модель и задать собственный кандидатный алфавит.
Пакетная обработка папки и очереди файлов
Команда cnocr predict принимает путь к одному изображению или каталогу. Для быстрых проверок это удобнее отдельного скрипта: можно поменять модели, бэкенд, язык, размер детектора и режим одной строки аргументами командной строки. Флаг подробного вывода показывает оценки и геометрию, а каталог визуализации сохраняет кадры с нанесёнными рамками и текстом.
cnocr predict -i samples --show-details --draw-results-dir checked
Каталог результата должен отличаться от входного. Иначе повторный запуск может попытаться распознать собственные визуализации вместе с исходниками, удвоить объём и создать рекурсивный набор файлов. Перед пакетной обработкой также фильтруйте расширения и скрытые элементы, потому что папка нередко содержит служебные превью, JSON или временные файлы редактора.
Для надёжной очереди сохраняйте статус каждого файла: принят, распознан, пропущен, ошибка чтения, ошибка модели. После сбоя процесс должен продолжаться со следующего элемента и не терять уже готовые записи. Хэш исходного файла помогает не обрабатывать дубликат повторно, а версия набора параметров позволяет понять, почему два запуска дали разные результаты.
Большие партии лучше разбивать на контролируемые порции. После каждой порции освобождайте временные изображения, записывайте результат на диск и измеряйте время. Рост памяти от партии к партии обычно указывает на сохранение ссылок на крупные массивы или вырезки. Если cropped_img не требуется после контроля, не держите его в общем списке результатов.
Параллельность вводите после измерения одиночного процесса. Несколько процессов могут загрузить отдельные копии весов и исчерпать оперативную или видеопамять быстрее, чем ускорить очередь. Для CPU часто эффективнее один или несколько долгоживущих работников с ограниченной внутренней многопоточностью. Для GPU обычно нужен централизованный потребитель, который собирает изображения в пакеты и не допускает конкурирующих загрузок модели.
Настройка детектора текста
Детектор отвечает на вопрос, где находится текст. Базовый многоязычный вариант подходит для смешанных сцен, фотографий и документов, где строки имеют разную длину и могут быть слегка наклонены. Он выдаёт четырёхугольники, которые затем выпрямляются перед распознаванием. Для чистого скриншота с горизонтальными строками иногда выгоднее naive_det: он использует простое разбиение и работает быстрее, но гораздо чувствительнее к оформлению.
naive_det выбирают по эксперименту, а не по названию файла. Он хорошо справляется, когда фон однороден, строки не пересекаются, интервал между ними заметен и нет декоративных рамок. На фотографии вывески, чеке со столбцами, документе с печатями или вертикальном тексте простой алгоритм может объединить разные области либо потерять строку. В таких случаях возвращайтесь к полноценному детектору.
Размер входа детектора задаёт компромисс между деталями и временем. Значение около 768 пикселей используется как практическая отправная точка. Увеличение помогает мелкому тексту, но повышает расход памяти и задержку; уменьшение ускоряет обработку, но короткие штрихи исчезают после масштабирования. Сравнивать размеры нужно на самых трудных кадрах, а не на крупных заголовках, которые распознаются почти при любых настройках.
Сохранение пропорций предотвращает растяжение букв по одной оси. Если отключить его без необходимости, широкий документ может быть сжат до квадрата, и распознаватель получит непривычные формы. При сохранении пропорций свободная область дополняется, зато геометрия символов остаётся ближе к исходной. Исключение возможно для уже нормализованных фрагментов фиксированного размера, где форма заранее контролируется.
Порог оценки рамки и минимальный размер области определяют, какие кандидаты попадут в распознавание. Снижение порога возвращает бледные надписи, но добавляет фоновые детали; повышение убирает шум, но может удалить тонкий текст. Минимальный размер защищает от точек и мусора, однако слишком большое значение отсекает индексы, сноски и мелкие цифры. Меняйте один параметр за раз и сохраняйте визуализации рамок, иначе невозможно понять, какая настройка помогла.

Проверка рамок перед распознаванием
Визуализация детектора должна показывать полную строку с небольшим запасом и без соседнего текста. Если рамка режет нижние элементы, увеличьте масштаб, проверьте перспективу и не применяйте слишком агрессивную обрезку. Если одна рамка охватывает две строки, улучшите межстрочный контраст или смените детектор. Если рамок слишком много на узоре бумаги, поднимите порог и ограничьте область документа маской.
Порядок рамок не следует считать готовым порядком чтения для любой разметки. В одной колонке достаточно группировки по вертикали, но в таблице сначала определяют строки и столбцы. На билете левые и правые поля могут находиться на одной высоте, хотя логически относятся к разным блокам. Сохраняйте геометрию и применяйте собственные правила структуры после OCR.
Выбор модели распознавания
Универсальный densenet_lite_136-gru служит разумной исходной точкой для упрощённого китайского, английского и цифр. Модель scene-densenet_lite_136-gru ориентирована на фотографии и надписи в естественной обстановке, где фон и шрифт меняются. doc-densenet_lite_136-gru предназначена для более регулярных сканов и снимков документов. Название семейства задаёт предположение, но окончательный выбор делают по контрольной выборке собственного проекта.
У многоязычного семейства PP-OCRv6 есть варианты tiny, small и medium. Меньшая модель экономит память и время, средняя даёт больше вычислительной ёмкости, а small используется как сбалансированный вариант. Для него указывается конкретный язык через rec_lang_type; слово multi обозначает семейство и не является кодом языка. Детектор многоязычного семейства получает язык отдельно через дополнительные настройки.
Для чистого английского можно сравнить специализированные детектор и распознаватель английского семейства с многоязычной конфигурацией. Специализированная пара не тратит ёмкость на большой набор иероглифов, поэтому часто лучше различает латиницу в книгах и интерфейсах. Если в документе встречаются китайские названия, смешанные адреса или символы валют, тестируйте обе схемы: узкий языковой набор может начать терять допустимые знаки.

Для традиционного китайского нужна модель, которая явно поддерживает этот набор знаков. В многоязычной конфигурации задаётся язык chinese_cht. Использование распознавателя для упрощённого китайского может вернуть визуально похожий, но другой иероглиф; такая ошибка особенно опасна в именах и адресах, потому что строка остаётся правдоподобной. Проверка должна сравнивать Unicode-символы, а не только внешний вид.

Вертикальный текст требует поддерживающей его пары моделей и аккуратной рамки. Многоязычные PP-OCRv6-модели рассчитаны на такой сценарий, тогда как базовые Densenet-распознаватели в таблице моделей не заявляют вертикальный режим. Не поворачивайте весь документ вслепую: горизонтальные подписи и вертикальные колонки могут сосуществовать. Лучше детектировать области, определить их ориентацию и обрабатывать отдельно.

Как проводить сравнение моделей
Соберите набор, который отражает реальные сложности: бледные чеки, разные телефоны, длинные строки, редкие символы, наклон, маленький шрифт и загрязнённый фон. Для каждой конфигурации фиксируйте точное совпадение строк, долю ошибочных символов, время, пиковую память и число пропущенных областей. Средняя точность на лёгких кадрах скрывает провал в критическом поле, поэтому отдельно считайте показатели для номера, суммы, даты и имени.
Не меняйте детектор и распознаватель одновременно. Сначала сохраните одинаковые вырезки, затем прогоните их через разные распознаватели. После выбора модели вернитесь к детектору и сравните рамки. Такая схема отделяет качество чтения символов от качества локализации и делает вывод воспроизводимым.
Ограничение алфавита и контроль формата
Параметр cand_alphabet сокращает допустимый набор символов без замены самой модели. Он полезен для полей с известным форматом: шестизначного кода, латинского артикула, регистрационного номера или набора цифр и разделителей. Чем точнее ограничение соответствует реальности, тем меньше вероятность замены на визуально похожий недопустимый знак.
Ограничение должно включать все символы, которые могут встретиться. Для суммы понадобятся цифры, десятичный разделитель, иногда минус и знак валюты; для даты — цифры, точки, дефисы или косые черты; для номера заказа — латинские буквы обоих регистров, если регистр значим. Пропущенный допустимый символ не будет восстановлен постобработкой, потому что модель изначально исключит его из кандидатов.
Кандидатный алфавит не заменяет проверку бизнес-правил. После OCR применяйте регулярное выражение, контрольную сумму, словарь допустимых кодов или проверку диапазона. Например, строка даты может состоять только из разрешённых цифр и точек, но всё равно содержать 39-й день. Комбинация ограниченного распознавания и валидации даёт заметно более надёжный результат, чем любой из способов по отдельности.
Алфавит можно менять методом set_cand_alphabet(), но в многопоточном приложении это состояние нужно контролировать. Если один общий объект попеременно обрабатывает цифровые и текстовые поля, смена набора между параллельными запросами создаёт гонку. Проще держать отдельные экземпляры для разных типов полей или сериализовать смену конфигурации.
Командная строка: полезные параметры predict
Параметры --rec-model-name и --det-model-name задают модели, а соответствующие параметры backend выбирают ONNX или PyTorch там, где нужный вариант существует. --context управляет устройством для PyTorch; указание GPU при ONNX само по себе не переключает провайдер, поэтому среда должна содержать GPU-сборку runtime. Языковые аргументы применяются к многоязычным моделям и должны совпадать с содержимым документов.
--single-line нельзя включать только ради скорости для обычной страницы. Флаг сообщает, что весь вход является одной строкой, и отключает разделение. На многострочном кадре результат получится смешанным. Используйте его для заранее вырезанных полей либо запускайте отдельную команду для каталога, где действительно лежат только однострочные изображения.
--draw-results-dir создаёт визуальные результаты, необходимые при приёмке настроек. Если подписи на изображении отображаются квадратами, укажите --draw-font-path к шрифту с нужными глифами. Ошибка шрифта влияет только на отрисовку результата, а не на сам распознанный текст; проверяйте строковый вывод отдельно, прежде чем менять модель.
--show-details выводит геометрию и уверенность, а --verbose добавляет диагностические сообщения о загрузке и работе компонентов. В производственном журнале подробный режим может создавать большой объём данных, поэтому его включают для ограниченной выборки или при ошибке. Для постоянного мониторинга лучше записывать длительность, имя конфигурации, число областей и сводку низких оценок.
cnocr predict -m multi_PP-OCRv6 -d multi_PP-OCRv6_det_small \
--rec-lang-type en --det-lang-type en \
-i english-pages --draw-results-dir english-checked
Демонстрационный интерфейс и проверка параметров
Демонстрационная страница CnOCR показывает типичную логику интерактивной проверки: выбираются модели и параметры, загружается изображение, после чего рядом появляются распознанный текст и размеченный кадр. Такой интерфейс удобен для единичного эксперимента, потому что позволяет увидеть влияние настроек без написания скрипта. Для регулярной обработки лучше перенести удачную комбинацию в код или команду и зафиксировать её вместе с тестовым набором.

Оценивать модель по одному красивому примеру нельзя. Загрузите несколько кадров каждого типа и специально включите плохие: размытый, тёмный, наклонённый, с редким символом и мелким текстом. Записывайте параметры рядом с результатом, иначе после нескольких экспериментов невозможно восстановить, какая комбинация дала нужную рамку.
Демонстрационный экран не является заменой теста в целевой среде. Размеры библиотек, доступный runtime, порядок каналов изображения и предобработка в вашем коде могут отличаться. После выбора модели повторите тот же набор через API, сохраните JSON и сравните строки с тем, что показано на интерактивной странице.
HTTP-обработчик для интеграции
Дополнительный набор зависимостей serve добавляет FastAPI-службу. Команда cnocr serve запускает процесс, принимает изображение как multipart-поле и возвращает структуру с результатами. Порт можно изменить аргументом, а адрес привязки — параметром хоста. Такой слой полезен, когда вызывающая система написана не на Python или когда модель нужно держать загруженной в одном процессе.
pip install 'cnocr[serve]' onnxruntime
cnocr serve -p 8501
Клиент отправляет файл в поле image и читает массив results из JSON. Перед передачей в бизнес-систему следует нормализовать числовые типы и координаты, потому что массивы библиотек машинного обучения не всегда сериализуются так, как ожидает внешний клиент. На стороне сервера ограничьте размер запроса и проверяйте MIME-тип, чтобы случайный архив или видео не попали в декодер изображения.
В производственной схеме добавьте очередь, тайм-аут и идентификатор запроса. OCR может занять больше времени на огромном кадре или при первом скачивании модели. Без ограничения один тяжёлый запрос блокирует всех клиентов. Идентификатор позволяет связать журнал сервера, исходный файл и итоговую запись, не помещая персональные данные в имя файла.
Служба не добавляет аутентификацию и правила хранения автоматически. Если она доступна из другой сети, защитите её обратным прокси, ограничьте список клиентов и удаляйте временные изображения после обработки. Модельные каталоги лучше готовить заранее: тогда первый пользовательский запрос не зависит от внешней загрузки и не получает непредсказуемую задержку.
Работа со сканированными PDF
CnOCR принимает изображения, поэтому страницы PDF сначала растеризуют. Для каждой страницы выбирают масштаб, получают PNG или массив, запускают OCR и сохраняют номер страницы вместе с координатами. Непосредственного импорта PDF, сборки текстового слоя, редактирования страниц и экспорта готового поискового документа у CnOCR нет. Эти этапы выполняет отдельная PDF-библиотека или программа.
Масштаб растеризации важнее формального DPI в метаданных. Если буквы на полученном изображении слишком малы, увеличьте разрешение страницы до распознавания. Если исходный скан уже низкого качества, повторная растеризация с огромным масштабом лишь раздует файл. Проверяйте фактическую высоту символов и ограничивайте размер по длинной стороне, чтобы детектор не тратил память на пустые поля.
После OCR можно построить JSON с полями page, text, score и position, а затем передать его модулю, который добавляет невидимый текстовый слой. Координаты нужно преобразовать из пикселей изображения в единицы страницы с учётом масштаба и поворота. Если этот пересчёт пропустить, выделение текста будет смещено относительно букв.
Для многостраничных документов сохраняйте промежуточный результат каждой страницы. При аварии не придётся повторять всё задание, а исправление одной страницы не затронет остальные. Кэш удобно привязывать к хэшу страницы и конфигурации OCR: изменение детектора, языка или масштаба должно создавать новый результат, а не случайно использовать старый.
Когда задача сводится к тому, чтобы сделать сканированный PDF доступным для поиска без программирования, специализированный инструмент вроде OCRmyPDF обычно проще. CnOCR оправдан, когда нужны собственные правила полей, китайский текст, координаты, отбор по уверенности или интеграция с внутренней обработкой изображений.
Распознавание чеков, билетов и форм
Чек содержит узкие колонки, повторяющиеся цены, разделители и бледную термопечать. Сначала выравнивают бумагу и удаляют фон за её пределами, затем проверяют, что детектор не объединяет название товара с ценой соседней строки. После OCR строки группируют по вертикальной координате, а правые числовые области относят к цене по положению, а не только по пробелам в распознанном тексте.
Итоговую сумму нельзя выбирать как последнюю цифру документа: ниже могут находиться номер терминала, дата, налоговые реквизиты и рекламный код. Ищите подпись поля, геометрическую близость и формат значения. Для критичных сумм применяйте арифметическую проверку по позициям товаров, скидкам и налогам; расхождение отправляйте на ручную проверку даже при высокой уверенности модели.
Билет сочетает крупные заголовки, мелкие служебные подписи, коды и несколько логических блоков. Координаты помогают отделить станцию отправления от прибытия, номер поезда от места и дату от времени. Не собирайте билет в одну строку: сначала создайте карту областей, затем присвойте им поля по шаблону или ближайшей подписи.
У форм с фиксированной разметкой выгодно один раз определить зоны интереса и применять однострочное распознавание. Но шаблон должен учитывать небольшое смещение скана. Сначала найдите опорные элементы страницы, выровняйте её, затем вырезайте поля. Жёсткие координаты на невыровненном снимке будут постепенно уходить и обрезать значения.

Удостоверения и анкеты содержат персональные данные, поэтому исходники, вырезки и логи уверенности должны храниться по правилам вашей системы. Для отладки достаточно обезличенной выборки или синтетических значений в тех же шрифтах. Не оставляйте реальные документы в общей папке с визуализациями только потому, что они удобны для сравнения моделей.
Снимки экрана и интерфейсные надписи
Скриншоты обычно имеют ровный фон и стабильный масштаб, поэтому CnOCR хорошо подходит для извлечения подписей кнопок, сообщений и табличных значений. Если экран содержит одну колонку текста, можно проверить naive_det. Если есть карточки, всплывающие окна и разноцветные панели, полноценный детектор надёжнее отделяет независимые блоки.
Перед OCR убирайте системные панели и области, которые не относятся к задаче. Они создают повторяющиеся строки времени, сети и уведомлений, засоряющие результат. Для автоматизированного тестирования интерфейса полезно хранить маски постоянных элементов и распознавать только изменяемую область.
Текст на экране может быть масштабирован операционной системой. Один и тот же элемент при разных коэффициентах получит разную высоту символов и положение. Нормализуйте размер окна или записывайте коэффициент масштаба вместе с эталоном. Сравнение только координат без допуска приводит к ложным ошибкам даже при правильном тексте.

Производительность: ONNX, PyTorch, CPU и GPU
Для распознавания и детектирования можно выбирать ONNX или PyTorch там, где модель предоставлена в обоих форматах. Документация отмечает, что ONNX-вариант той же модели обычно работает примерно вдвое быстрее PyTorch, но реальный выигрыш зависит от процессора, размера партии и операций предобработки. Измеряйте полный путь от чтения файла до готового JSON, а не только время нейросети.
Параметр context относится к PyTorch-бэкенду. Указание gpu при ONNX не заменяет установку соответствующего runtime. Для GPU-режима ONNX удаляют CPU-пакет onnxruntime и устанавливают onnxruntime-gpu; одновременное наличие конфликтующих сборок часто приводит к выбору не того провайдера. После установки проверьте список доступных провайдеров в самом runtime.
GPU раскрывается на партиях и более тяжёлых моделях, но передача маленького изображения и запуск служебных операций имеют собственную стоимость. Для единичной строки CPU может оказаться быстрее по общей задержке. Для высокой нагрузки собирайте фрагменты в rec_batch_size, контролируя память и время ожидания первого элемента очереди.
Параметр пакетного распознавания не равен числу одновременно загруженных полных документов. Детектор сначала создаёт набор строк, а распознаватель объединяет их в партии. Чек на сто строк может заполнить пакет сам. Если одновременно держать много таких страниц, возрастут память и задержка. Ограничивайте очередь по суммарному числу областей, а не только по числу файлов.
Первый вызов включает загрузку весов, построение сессии и выделение буферов. Для честного теста выполните несколько прогревочных проходов, затем измеряйте медиану и высокие процентили на одинаковом наборе. Отдельно записывайте холодный старт, если процесс часто запускается по расписанию и завершается после одного документа.
Не используйте максимальный размер изображения без причины. Детектор масштабирует кадр, а очень большие исходники увеличивают стоимость декодирования, копирования и хранения. Обрезка пустых полей и разумный предел по длинной стороне обычно дают больше пользы, чем переход на более мощное устройство.
Модели, кэш и работа без доступа к сети
При первом использовании выбранные веса скачиваются и распаковываются в каталоги CnOCR и CnSTD. Распознаватель обычно находится в ~/.cnocr, детектор — в ~/.cnstd; в Windows эти каталоги располагаются в профиле пользователя. Поэтому установка самого wheel-файла ещё не означает, что все модели уже присутствуют.
Для закрытого контура заранее определите точные имена моделей, скачайте соответствующие архивы из официального хранилища и разложите их в ожидаемую структуру. После этого выполните тестовый вызов без сети. Просто положить ZIP рядом со скриптом недостаточно: библиотека ищет веса в каталоге и структуре, соответствующих её соглашениям.
Каталоги можно переназначить параметрами rec_root и det_root. Это полезно на сервере, где домашняя папка эфемерна, или в контейнере, где модели подключаются отдельным томом. Процессу нужны права на чтение распакованных файлов, а при автоматической загрузке — ещё и на запись. Ошибка прав часто выглядит как повторная попытка скачивания при каждом старте.
Не обновляйте модели незаметно для производственного процесса. Храните их как часть конфигурации, фиксируйте хэш и прогоняйте контрольную выборку перед заменой. Даже более точная в среднем модель может иначе разделять редкий шрифт или менять визуально похожий символ в критичном поле.
В контейнере модели лучше поместить в отдельный неизменяемый слой или примонтированный каталог. Это сокращает холодный старт и исключает зависимость первого запроса от внешнего хранилища. Если образ предназначен для разных архитектур, используйте подходящий вариант и не переносите бинарные runtime-пакеты между несовместимыми платформами.
Установка и изоляция зависимостей
Для запуска требуется Python 3.8 или новее. Создайте отдельное виртуальное окружение, чтобы версии OpenCV, PyTorch, ONNX Runtime и вспомогательных библиотек не пересекались с другими задачами. После активации установите CPU-набор cnocr[ort-cpu] либо GPU-набор cnocr[ort-gpu]. Для обучения используется набор dev, а для HTTP-службы — serve.
python -m venv .venv
# активируйте окружение подходящей для вашей системы командой
python -m pip install --upgrade pip
python -m pip install 'cnocr[ort-cpu]'
Кавычки вокруг имени с квадратными скобками особенно важны в оболочках, где скобки интерпретируются как шаблон. Если команда установила только базовый пакет без runtime, импорт может пройти, но первый вызов ONNX завершится ошибкой отсутствующей зависимости. Проверяйте установку коротким сценарием, который создаёт объект и распознаёт тестовую строку.
На машине, где ранее не было PyTorch или OpenCV, установка может занять заметное время и потребовать совместимых бинарных колёс. Не смешивайте системный Python с пакетами, установленными от администратора и от обычного пользователя. Команды python -m pip и python должны указывать на одно окружение; это проверяется путём к интерпретатору и списком установленных пакетов.
Для воспроизводимости сохраните файл зависимостей после успешного теста. Фиксировать нужно не только CnOCR, но и runtime, OpenCV, NumPy и другие компоненты, влияющие на чтение и вычисления. При переносе на другую ОС используйте отдельный lock-файл или заново разрешайте платформенные зависимости, потому что бинарные колёса различаются.
Типовые ошибки установки и запуска
Команда установилась, но модуль не импортируется
Чаще всего pip и запускаемый python относятся к разным окружениям. Выполните установку через python -m pip, затем выведите путь sys.executable. В редакторе кода выберите тот же интерпретатор. Если используется Jupyter, ядро ноутбука также должно быть создано из нужного окружения.
ONNX не видит видеокарту
Проверьте, что установлен onnxruntime-gpu, а CPU-вариант удалён. Затем запросите список провайдеров runtime. Отсутствие CUDA-провайдера означает проблему уровня драйвера, CUDA-библиотек или несовместимой сборки, а не параметров CnOCR. Пока провайдер не появился, смена context не исправит ONNX-сеанс.
Модель скачивается при каждом старте
Проверьте путь rec_root или det_root, права записи, сохранность каталога между запусками и структуру распакованных файлов. В контейнере домашняя папка может уничтожаться после завершения. Подключите постоянный том и выполните один прогревочный вызов во время подготовки образа.
Загрузка весов завершается ошибкой
Скачайте архив модели отдельно и сравните контрольную сумму, если она предоставлена хранилищем. Не переименовывайте внутренние каталоги произвольно. Если сеть использует прокси или проверку сертификатов, настройте их для процесса загрузки либо перенесите веса через разрешённый канал. После ручного размещения протестируйте запуск при отключённой сети.
Изображение не читается
Убедитесь, что файл действительно является изображением, а не страницей ошибки с расширением PNG или JPG. Откройте его Pillow или OpenCV до вызова OCR и проверьте размеры. Пустой массив, повреждённый файл, неподдерживаемое кодирование и путь к каталогу вместо файла должны отсеиваться на входе. Для путей с нелатинскими символами используйте актуальную реализацию чтения и передавайте объект изображения, если сторонняя библиотека не справляется.
Возвращается пустой список
Сначала сохраните вход и визуализацию детектора. Увеличьте рабочий размер для мелкого текста, снизьте порог рамки или минимальный размер и проверьте контраст. Если это заранее вырезанная строка, используйте однострочный метод и исключите детектор. Если надпись вертикальная, выберите модель, которая поддерживает её ориентацию.
Рамки есть, но текст неверен
Просмотрите вырезанные области. Убедитесь, что язык и словарь соответствуют символам, а рамка содержит всю строку. Сравните универсальную, документную, сценическую или многоязычную модель на одинаковых вырезках. Для поля строгого формата задайте кандидатный алфавит и добавьте валидацию после OCR.
Текст на визуализации превратился в квадраты
Укажите шрифт с китайскими и другими нужными глифами параметром отрисовки. Сам результат в памяти может быть правильным: проблема находится в шрифте, которым подписывается изображение. Не оценивайте модель по квадратам в PNG, пока не проверили строку JSON или консольный вывод.
Не хватает памяти
Уменьшите размер детектора, партию распознавания и число параллельных работников. Не возвращайте и не храните вырезки, если они не нужны. Обрабатывайте страницы последовательно, а результаты сразу сериализуйте. На GPU проверьте, не созданы ли несколько копий модели в разных процессах.
Порядок строк перепутан
Это задача постобработки геометрии. Сгруппируйте области по близкой вертикальной координате с допуском, основанным на высоте строк, затем сортируйте внутри группы слева направо. Для колонок сначала разделите страницу на блоки. В формах используйте зоны полей, а не общий порядок детектора.
Результаты меняются после обновления среды
Зафиксируйте версии зависимостей, модели и параметры предобработки. Сравните контрольный набор до и после изменения. Различие может появиться из-за нового runtime, OpenCV, алгоритма изменения размера или самих весов. Обновляйте компоненты по одному, чтобы определить причину изменения.
Постобработка текста и координат
Первый этап постобработки — нормализация пробелов и переносов без изменения значимых символов. Китайский текст часто не требует пробела между иероглифами, английские слова требуют. Нельзя одинаково соединять все фрагменты. Используйте язык строки, расстояние между рамками и размер символов, чтобы решить, нужен ли пробел.
Сортировка одной колонки начинается с центров рамок. Области считают одной строкой, если их вертикальные диапазоны достаточно перекрываются или центры различаются меньше доли средней высоты. Затем элементы сортируют по горизонтали. После объединения группы переходят к следующему уровню сверху вниз. Такой алгоритм устойчивее простого сравнения координаты y одного угла.
Для таблицы сначала ищут повторяющиеся вертикальные границы или строят кластеры центров по оси X. Каждую распознанную область относят к ячейке по пересечению. Если линия таблицы разрезает символы, удалите линии до OCR либо увеличьте внутренний отступ ячейки. Восстановление таблицы только по последовательности строк почти всегда теряет пустые ячейки.
Оценку уверенности агрегируйте осмысленно. Минимум по строке выявляет один очень слабый фрагмент, среднее скрывает его, а произведение быстро уменьшается с числом строк. Для документа полезно хранить долю областей ниже порога, минимальное значение в критичных полях и отдельный статус проверок формата.
Нормализация похожих символов допустима только в известном контексте. В цифровом поле букву O можно заменить на ноль, но в имени такая замена повредит текст. Создавайте правила для конкретных полей и записывайте, какое преобразование применено. Исходная строка должна оставаться доступной для аудита.
При экспорте в CSV экранируйте запятые, кавычки и переводы строк. Для JSON преобразуйте массивы координат в обычные списки чисел. Не сериализуйте объект изображения внутри результата; сохраняйте вырезку отдельным файлом и указывайте путь или идентификатор.
Контроль качества на реальном наборе
Разделите данные на настройку и независимую проверку. На первом наборе выбирают модель, пороги и предобработку; второй используется только для итоговой оценки. Если постоянно подгонять параметры под одни и те же документы, результат будет выглядеть лучше, чем на новых снимках.
Для строк считайте точное совпадение и символьную ошибку. Точное совпадение важно для кодов и реквизитов, а символьная метрика показывает степень ошибки в длинном тексте. Для детектора отдельно измеряйте пропущенные и лишние области. Итоговое качество полного конвейера нельзя вывести только из точности распознавателя на идеальных вырезках.
Сформируйте категории сложности: язык, тип документа, камера, освещение, ориентация, высота текста и наличие фона. Сводный процент может быть высоким, хотя одна категория полностью проваливается. Категорийный отчёт показывает, где нужна другая модель или отдельная предобработка.
Порог ручной проверки выбирайте по стоимости ошибки. Для суммы платежа лучше показать оператору больше сомнительных строк; для поиска по архиву допустима более мягкая фильтрация. Автоматическое принятие должно опираться не только на score, но и на формат, словарь и согласованность с соседними полями.
Сохраняйте небольшую выборку неудач каждого запуска. По ней видно, ухудшилась ли система после изменения модели или входных данных. При этом обезличивайте документы и соблюдайте срок хранения. Цель журнала — воспроизводимая диагностика, а не накопление всего потока.
Обучение и дообучение распознавателя
Набор cnocr[dev] устанавливает зависимости для обучения. Команда cnocr train принимает имя архитектуры, каталог с индексами train.tsv и dev.tsv, а также JSON-конфигурацию. Индекс связывает путь к изображению строки с правильной текстовой меткой. Данные должны представлять те же шрифты, фон, высоту и искажения, которые встречаются в целевой задаче.
Встроенные модели обучались на более чем пяти миллионах текстовых изображений, поэтому дообучение имеет смысл не из-за малого общего набора, а из-за специфического домена: редкого шрифта, производственной маркировки, узкого алфавита или повторяющегося качества камеры. Сначала проверьте предобработку и готовые модели. Дообучение не исправит рамку, которая обрезает символы.
Для продолжения прерванного обучения используется checkpoint с состоянием оптимизатора и эпохи. Параметр предварительной модели задаёт только начальные веса и имеет меньший приоритет, если указан checkpoint продолжения. Не путайте эти режимы: запуск с начальными весами начинает новую историю оптимизации, а возобновление должно точно восстановить прежнее состояние.
В режиме тонкой настройки применяют более мягкие преобразования и меньшую скорость обучения. В документации приведён ориентир 3e-5 с косинусным расписанием и прогревом. Это не универсальная гарантия: следите за отдельной проверочной выборкой и прекращайте обучение, когда её ошибка начинает расти. Слишком долгое дообучение на узком наборе ухудшит общие символы.
Новый словарь передаётся через файл rec_vocab_fp. Порядок символов должен соответствовать обученным выходам модели. Нельзя заменить словарь после обучения произвольным набором той же длины: индексы начнут обозначать другие символы. Храните словарь вместе с весами и конфигурацией.
Команда cnocr evaluate оценивает распознаватель на подготовленном наборе и использует простой режим детектирования, поэтому для полного конвейера дополнительно проверяйте обычный ocr() на исходных страницах. Метрика идеальных строк показывает потенциал распознавателя, но не учитывает потерю и обрезку областей детектором.
Экспорт и перенос моделей
Командная строка включает операции сохранения и экспорта PyTorch-модели в ONNX. Экспорт нужен, когда обучение завершено в PyTorch, а рабочая среда использует ONNX Runtime. После преобразования обязательно сравните выходы обеих моделей на контрольных строках: различия в операциях, динамических размерах и численной точности могут проявиться только на отдельных примерах.
Сохраняйте рядом имя архитектуры, словарь, размер входа, параметры нормализации и хэш файла. Один ONNX-файл без этих сведений трудно воспроизвести. Если модель использует собственный набор символов, стандартный словарь CnOCR ей не подходит.
При переносе между процессорами проверяйте доступность операторов runtime. Универсальность формата не означает, что любая сборка поддерживает все ускорители одинаково. Начните с CPU-провайдера, подтвердите корректность, затем включайте GPU и сравнивайте результаты.
Форматы входных данных и проверка массива
Метод ocr() принимает строковый путь, объект Pillow, тензор PyTorch или массив NumPy. Это позволяет читать файл обычным способом, передавать кадр прямо из камеры и не создавать временный PNG между этапами обработки. При выборе формы входа важно сохранить исходную ориентацию и размер: автоматическое вращение в библиотеке чтения должно быть одинаковым во всех средах, иначе координаты окажутся привязаны к уже повёрнутой копии.
Для массива допустим серый кадр или изображение с одним либо тремя каналами. Значения яркости ожидаются в диапазоне от нуля до 255. Если предыдущий этап выдаёт float-массив от нуля до единицы, его следует масштабировать и привести к подходящему типу, а не просто менять dtype: прямое преобразование превратит почти все пиксели в нули или единицы. Перед OCR полезно вывести минимум, максимум, форму и тип данных одного тестового массива.
Альфа-канал следует обработать до распознавания. Прозрачный текст может выглядеть корректно в просмотрщике, который подставляет белый фон, но массив RGBA содержит отдельную прозрачность. Скомпонуйте изображение на реальном фоне и передайте трёхканальный результат. Для белых букв на прозрачном слое неверная композиция способна сделать строку практически невидимой.
При чтении кадра OpenCV обычно возвращает BGR, а Pillow — RGB. Детектор текста в первую очередь использует контуры и контраст, поэтому ошибка каналов иногда остаётся незаметной на чёрно-белом документе, но проявляется на цветной вывеске или интерфейсе. Выберите единое соглашение внутри конвейера и выполняйте преобразование ровно один раз. Повторное BGR–RGB преобразование вернёт исходный порядок и затруднит диагностику.
Путь к файлу удобен для простого сценария, но массив даёт больше контроля: можно выровнять перспективу, вырезать область, закрыть персональные зоны и только затем вызвать OCR. При этом координаты результата относятся к переданному массиву. Если нужна привязка к исходному снимку, сохраняйте матрицу преобразования и обратным преобразованием переносите четыре точки каждой области.
Для тензора проверьте порядок измерений, число каналов и диапазон значений до вызова. Тензор, подготовленный для другой нейросети, может уже содержать нормализацию со средним и стандартным отклонением; такой объект не следует подавать как обычное изображение. Надёжнее хранить ненормализованную копию кадра для CnOCR и применять модельную нормализацию внутри самого распознавателя.
Параметры метода ocr и их влияние
Параметр rec_batch_size определяет, сколько найденных строк распознаётся за один пакет. Небольшое значение уменьшает пиковую память и подходит для непредсказуемых длин строк, большое лучше использует вычислитель на массовой задаче. Начинайте с единицы для проверки корректности, затем увеличивайте на контрольном наборе, одновременно записывая скорость и память. Ошибка нехватки памяти требует уменьшить пакет, а не размер исходной страницы, если детектор уже завершил работу.
return_cropped_image следует включать для диагностики и выключать в основном потоке, если вырезки не сохраняются. Каждый фрагмент занимает память, а в чеке или длинной странице их может быть много. Компромиссный вариант — возвращать вырезки только для строк ниже порога либо повторно вырезать их по сохранённым координатам при формировании отчёта.
Дополнительные аргументы детектора передаются через вызов ocr(). К типовым относятся resized_shape, preserve_aspect_ratio, min_box_size, box_score_thresh и batch_size. Их точная поддержка зависит от выбранного детектора, поэтому перед массовым запуском проверьте сигнатуру используемой реализации. Неизвестный параметр должен приводить к заметной ошибке настройки, а не молча теряться в обёртке.
resized_shape задаёт рабочий размер для поиска текста. Квадратное значение удобно как единая настройка, но вытянутые документы следует оценивать с сохранением пропорций. Если после масштабирования высота мелкой строки стала слишком низкой, детектор её пропустит независимо от качества распознавателя. Измеряйте итоговую высоту текста после преобразования, а не только исходное разрешение файла.
min_box_size отсеивает очень маленькие области. Это уменьшает число ложных рамок на точках, фактуре бумаги и разделителях, однако может убрать надстрочные индексы, мелкие номера и подписи. Значение восемь служит базовым ориентиром в параметрах детектирования, но его нельзя считать универсальным. Для маленького текста сначала увеличьте размер входа, затем снижайте минимум, чтобы не превращать весь фон в кандидатов.
box_score_thresh фильтрует области по уверенности детектора. Базовое значение около 0,3 сохраняет достаточно слабые кандидаты. На чистом скане порог можно повысить и сократить шум, на выцветшем чеке — осторожно снизить. Изменение оценивайте по числу пропущенных нужных строк и числу лишних рамок; качество уже распознанных символов не показывает, сколько текста детектор потерял.
Параметр batch_size детектора и rec_batch_size распознавателя относятся к разным этапам. Увеличение одного не обязательно ускоряет другой. Записывайте время чтения, детектирования, вырезания и распознавания отдельно. Если основная задержка находится в детекторе, настройка пакета строк почти не изменит общую производительность.
Подключение собственных файлов моделей
Параметры rec_model_fp и det_model_fp позволяют указать конкретный файл вместо автоматического выбора встроенного имени. Это нужно для дообученных весов, экспериментального ONNX-файла или модели, размещённой в контролируемом каталоге. Бэкенд должен соответствовать формату: checkpoint предназначен для PyTorch, ONNX-файл — для ONNX Runtime.
Собственный распознаватель часто требует собственного словаря через rec_vocab_fp. Файл словаря является частью модели, а не свободной настройкой оформления. Если набор символов или их порядок не совпадает с обучением, числовые выходы будут декодироваться в другие знаки. При развёртывании храните веса, словарь и конфигурацию как единый пакет с общей контрольной суммой манифеста.
rec_more_configs и det_more_configs передают дополнительные параметры конкретной реализации. Для многоязычного детектора язык задаётся в словаре детектора, тогда как распознаватель получает rec_lang_type. Ошибка, при которой язык установлен только на одном этапе, проявляется по-разному: детектор может хуже находить строки, либо рамки будут правильными, но символы распознаются не тем набором.
Каталоги rec_root и det_root удобны для нескольких окружений на одной машине. Можно держать проверенный набор весов в каталоге только для чтения, а экспериментальные модели — в отдельном месте. Не направляйте два процесса, одновременно распаковывающих один архив, в пустой общий каталог: сначала подготовьте веса атомарно, затем запускайте работников.
Перед заменой пользовательской модели выполните тест загрузки, один однострочный пример и полный кадр с детектором. Так отдельно проверяются словарь, форма входа и связка двух этапов. После этого прогоните зафиксированную выборку и сравните все критичные поля, а не только отсутствие исключений.
Запуск в контейнере
Официальные инструкции предлагают образы breezedeus/cnocr и отдельный ARM64-вариант. Контейнер полезен, когда требуется повторяемая среда с уже установленными библиотеками и HTTP-службой. Архитектуру образа выбирают по процессору: образ x86-64 нельзя считать взаимозаменяемым с вариантом для Apple Silicon или другого ARM-устройства.
docker pull breezedeus/cnocr
docker run -it -p 8501:8501 breezedeus/cnocr bash
Порт контейнера публикуют только в нужной сети. Для одиночного рабочего места достаточно привязки к интерфейсу хоста, недоступному извне; для серверной схемы доступ контролирует обратный прокси. Открытый порт OCR без аутентификации позволяет отправлять произвольные файлы и расходовать вычислительные ресурсы.
Модельные каталоги подключайте томом или включайте в подготовленный слой. Если веса скачиваются в изменяемый слой временного контейнера, они исчезнут после пересоздания и холодный старт повторится. Том также позволяет обновить приложение без повторной передачи больших моделей, но права пользователя внутри контейнера должны разрешать чтение и, при первичной подготовке, запись.
После старта проверьте процесс HTTP-службы. В некоторых средах контейнер может открыть оболочку, но служба не запустится автоматически; тогда её вызывают командой cnocr serve. Проверка должна включать реальную отправку небольшого изображения и чтение массива результатов, а не только наличие процесса в списке.
Для GPU контейнеру нужно передать устройство и совместимые библиотеки драйвера. Наличие CUDA в образе не гарантирует доступ к видеокарте хоста. Сначала подтвердите провайдер runtime внутри контейнера, затем измеряйте OCR. Если GPU недоступен, сервис может незаметно работать на CPU и не выдавать ошибку, но задержка окажется существенно выше ожидаемой.
Практические ограничения CnOCR
CnOCR не открывает PDF как страницы и не создаёт готовый редактируемый или поисковый PDF. Для такого процесса нужен этап растеризации и отдельный этап сборки. Пользователь, ожидающий кнопку открыть документ — сохранить с текстовым слоем, столкнётся с необходимостью написать или подключить дополнительный конвейер.
Графический демонстрационный экран подходит для теста, но основные рабочие сценарии строятся через Python, командную строку или HTTP. Настройка моделей и обработка координат требуют технических навыков. Это преимущество для интеграции, однако оно делает инструмент менее удобным для разовой ручной оцифровки без кода.
Вес базового пакета невелик, но выбранные модели скачиваются отдельно и занимают дополнительное место. Для закрытой сети и контейнера их нужно подготовить заранее. Если этого не сделать, первый запуск зависит от соединения и может завершиться ошибкой ещё до обработки изображения.
Поддержка языка определяется конкретной моделью. Наличие многоязычного семейства не означает, что один и тот же параметр одинаково хорош для всех письменностей. Для традиционного китайского, английского, японского и вертикального текста выбирают совместимый язык и проверяют собственные примеры.
Распознавание возвращает строки и геометрию, но не понимает смысл документа автоматически. Определение поля сумма, восстановление таблицы, объединение абзацев, проверка реквизитов и формирование структуры остаются задачей вызывающей системы. Без этой постобработки результат представляет собой список текстовых областей, а не готовую карточку документа.
Сравнение CnOCR с аналогами
| Программа | Лучше подходит для | Главное ограничение |
|---|---|---|
| CnOCR | Встраивания китайско-английского OCR в Python-конвейеры, получения координат и настройки собственных моделей | Нет прямого импорта PDF и требуется программная сборка процесса |
| PDF Commander | Ручного редактирования, объединения, разбиения и подготовки готовых PDF-документов | Не является библиотекой для пакетного OCR по координатам |
| Tesseract OCR | Распознавания множества языков через классический движок и командную строку | Разметку страницы и предобработку часто приходится настраивать отдельно |
| PaddleOCR | Полного детектирования и распознавания документов и сцен на множестве языков | Стек и конфигурация заметно сложнее для небольшого сценария |
| EasyOCR | Быстрого запуска многоязычного OCR из Python с простым вызовом | Меньше специализированных средств обучения и моделей CnOCR для китайских сценариев |
| OCRmyPDF | Автоматического добавления поискового текстового слоя в сканированные PDF | Ориентирован на PDF, а не на произвольный API полей и изображений |
CnOCR разумно выбирать, когда нужны китайский и английский текст, координаты областей, собственная постобработка и возможность подобрать модель под сцену или документ. PDF Commander удобнее для пользователя, которому нужно открыть и изменить сам PDF без написания конвейера. Tesseract подходит как широко распространённый языковой движок, PaddleOCR — для более крупной многоязычной системы, EasyOCR — для простого старта в Python, а OCRmyPDF — для превращения сканов в поисковые PDF.
Рекомендованный порядок внедрения
- Соберите 50–200 реальных изображений разных типов и вручную отметьте правильный текст для критичных полей.
- Запустите конфигурацию по умолчанию, сохраните строки, оценки, координаты и визуализацию рамок.
- Разделите ошибки детектора и распознавателя по сохранённым вырезкам.
- Сравните модели и языки на неизменных фрагментах, затем отдельно настройте размер и пороги детектора.
- Добавьте кандидатный алфавит и проверку формата только для полей с заранее известными правилами.
- Зафиксируйте зависимости, веса, параметры и контрольный набор; подготовьте модели в рабочем каталоге.
- Включите пакетную очередь с журналом, тайм-аутом и повтором только неуспешных файлов.
- Настройте ручную проверку низкой уверенности и бизнес-проверки для сумм, дат и идентификаторов.
- Перед каждым изменением прогоняйте независимую выборку и сравнивайте не только среднюю точность, но и критичные поля.
Такой порядок не требует сразу обучать свою сеть или строить сложный сервер. Он сначала показывает, где находится реальное ограничение: в качестве снимка, рамках, модели, языке или правилах структуры. После этого улучшение становится измеримым, а не сводится к случайной смене параметров.
Короткие ответы на практические вопросы
Можно ли распознавать фотографию целой страницы?
Да, обычный ocr() сначала найдёт области. Перед вызовом выровняйте перспективу, обрежьте фон и убедитесь, что мелкие символы не исчезают после уменьшения. Для страницы с колонками сохраните координаты и восстанавливайте порядок чтения отдельно.
Как ускорить обработку готовых полей?
Не запускайте детектор. Используйте ocr_for_single_line() или пакетный вариант для списка строк, держите объект загруженным и подбирайте размер партии по памяти. Для строго цифрового поля сравните числовую модель и ограниченный алфавит.
Почему высокая уверенность не гарантирует правильный номер?
Модель может уверенно выбрать визуально похожий символ. Проверяйте длину, регулярное выражение, контрольную сумму и допустимые значения. Для критичного номера сохраняйте исходную вырезку и отправляйте несогласованный результат оператору.
Что делать с вертикальными надписями?
Выбирайте модель, в таблице возможностей которой заявлен вертикальный текст, например многоязычное семейство PP-OCRv6. Не применяйте к смешанному документу один общий поворот; разделяйте области по ориентации.
Как обрабатывать PDF из архива?
Растеризуйте каждую страницу, распознавайте отдельно и храните координаты вместе с номером страницы. Добавление текстового слоя и сборка PDF выполняются другим инструментом. Масштаб преобразования должен сохранять читаемую высоту символов.
Нужен ли GPU?
Для единичных изображений и лёгких моделей CPU часто достаточен. GPU полезен при больших партиях и тяжёлых конфигурациях, но требует совместимого runtime и даёт выигрыш только после учёта передачи данных и пакетирования. Измеряйте полную задержку на своём потоке.
Как понять, что проблема в детекторе?
Включите возврат вырезок или визуализацию. Если нужной рамки нет, она обрезана или содержит соседнюю строку, исправляйте детектор и подготовку изображения. Если рамка правильная, сравнивайте распознаватели и язык.
Можно ли запретить лишние символы?
Да, через cand_alphabet или set_cand_alphabet(). Набор должен включать все допустимые знаки. После OCR всё равно применяйте проверку формата, потому что ограничение алфавита не проверяет смысл и диапазон значения.
Как избежать загрузки весов на рабочем сервере?
Подготовьте архивы моделей заранее, разместите их в каталогах rec_root и det_root, выполните прогревочный вызов и протестируйте запуск без сети. В контейнере закрепите каталоги в слое или постоянном томе.
Итоговый рабочий сценарий
Для устойчивого результата CnOCR следует рассматривать как управляемый конвейер: подготовить изображение, выбрать детектор, распознать строки, сохранить координаты и уверенность, восстановить структуру и проверить поля правилами предметной области. Быстрый одиночный вызов показывает возможности, но надёжность появляется после контрольного набора и раздельного анализа двух этапов.
На документах с китайским, английским, цифрами и вертикальными надписями инструмент даёт выбор специализированных и многоязычных моделей, позволяет перейти от полного кадра к заранее вырезанным строкам и масштабируется от скрипта до HTTP-службы. Главные практические затраты связаны с подготовкой Python-среды, хранением весов и построением PDF- или табличной постобработки.
Перед массовым запуском зафиксируйте модель, язык, размер детектора, пороги, алфавит и версии зависимостей, а затем сохраните эталонные результаты. Тогда изменение можно проверить воспроизводимо, сомнительные строки — направить на контроль, а ошибки — проследить от исходной рамки до окончательного поля без догадок.