21.09.2026

Электронный текст или OCR: классификатор страниц PDF

Текстовый слой PDF читается за миллисекунды и точнее любого распознавания, но верить ему можно не всегда. Классификатор на CPU решает это для каждой страницы и объясняет, почему.

Зачем

Поток PDF неоднороден. Часть документов электронные, и текст лежит в слое. Часть — сканы. Часть — картинки с текстом поверх. Часть — экспорт из OCR-программ, где слой выглядит электронным, но доверять ему нельзя. Распознавание стоит времени GPU, а чтение слоя почти бесплатно. Поэтому первым шагом идёт классификация страницы, и распознавание вызывается только там, где слоя нет или он ненадёжен.

Главное требование — не пропустить страницу с плохим слоем как электронную. Лишний раз отправить страницу в OCR дешевле, чем молча выдать неверный текст.

Как устроено

Классификатор — детерминированные правила, а не обученная модель. Никаких Surya, Qwen и Docling на этом шаге.

  1. Признаки. PyMuPDF достаёт из PDF текст, шрифты, координаты, размещения картинок, векторы и метаданные. NumPy считает «чернила» по рендеру страницы в 96 DPI.
  2. Тип страницы. Правила проверяются по порядку, срабатывает первое: пустая страница → нет текста → растровая подложка → повреждённый текст → гибрид → невидимый текст → электронная.
  3. Маршрут. Тип плюс признаки OCR-программы в метаданных дают один из маршрутов: «только слой», «слой со сверкой», «распознавание», «пропустить». Каждое решение сопровождается списком причин.

Ключевые признаки

Признак Что ловит Порог
Доля сломанных символов (U+FFFD, служебные категории) слой с битой кодировкой > 1.5 % → слою не верить
Доля дублей (тот же текст в тех же координатах) двойной слой, «печать поверх» > 15 %
Доля текста за краем страницы спрятанный текст > 10 %
Доля символов мельче 3 pt служебный мусор в слое > 30 %
Доля невидимого текста (режим 3, прозрачность) слой OCR-программы под картинкой > 70 % → распознавание
Изменение рендера без текстового слоя текст есть в слое, но его не видно < 1.5 % чернил
Покрытие страницы картинками скан как подложка ≥ 70 %
Чернила в картинках вне текстового слоя вставки, текст которых есть только в растре > 8 % → гибрид
Доля «ж» и «й» среди кириллицы мусорная раскладка вместо русского текста грубая проверка

Самый полезный признак — контрафактивный рендер. Страница рисуется второй раз без текстового слоя, и считается, сколько чернил исчезло. Если почти ничего, слой невидим: он белый, скрыт или перекрыт картинкой. Так ловятся сканы с подложенным невидимым слоем от OCR-программы, где сам текст может быть любым.

Проверка

Набор Страниц Электронных В распознавание Ложных «электронных»
Синтетика (20 PDF) 24 12 12 0
Отложенные публичные PDF (10 файлов) 14 1 13 0

Отложенные PDF — сканы писем и договоров, скриншоты интерфейсов, расписания, страницы с ценами внутри картинок. Маршрут для каждой страницы независимо проверен глазами и Qwen. На этом наборе строгая политика осторожничает: 4 страницы, которые можно было читать из слоя, она отправила в распознавание. Ни одной ошибки в опасную сторону нет.

На контрольном корпусе из 42 страниц 22 обошлись без распознавания. Классификация всего корпуса занимает 1.4 с на CPU.

Нагрузочный прогон

Полный прогон строгой политики на 432 реальных PDF (2160 страниц): 428 страниц признаны электронными, 1727 отправлены в распознавание, 5 пустых пропущены, 9 файлов не открылись. Это проверка на падения и распределение маршрутов, а не точности: разметки у этих файлов нет.

Извлечение из слоя

Для электронных страниц из слоя собираются абзацы, порядок чтения (XY-cut), таблицы (поиск PyMuPDF плюс признак сетки без линий) и роли блоков. В распознавание уходят только области, которых нет в слое: крупные картинки и вставки с чернилами вне текста. Перед отправкой картинка уменьшается до 2048 px по ширине.

На маршруте сверки числа сравниваются точно, слова — по покрытию. Расхождение попадает в замечания к странице. На выходе — JSON, markdown и HTML, где у каждого блока указан источник: слой, распознавание страницы или распознавание области.

Насколько итоговый текст лучше, чем распознавание всей страницы, показано в статье про сверку с Surya и LLM-судьёй: 0.29 % ошибок в символах против 5.77 %.

Ограничения

  • Метаданные «создано в Excel» — только вспомогательный сигнал, а не разрешение читать слой.
  • Порядок чтения и разметка страницы оцениваются отдельно от выбора маршрута.
  • Пороги подобраны на контрольном корпусе, отложенная проверка пока маленькая.