LayoutParser

LayoutParser помогает разбирать страницы PDF и изображений на текстовые блоки, заголовки, списки, таблицы и иллюстрации, связывать найденные области с OCR, фильтровать их по координатам и сохранять результат в JSON, CSV или объектную структуру для дальнейшей обработки.

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

Вместо окон, панелей и меню используются классы Python и короткие вызовы API: модель выбирается по идентификатору из каталога, метод detect выполняет разметку страницы, а функции draw_box и draw_text показывают результат поверх оригинала либо на отдельном текстовом холсте. Такой подход удобен для автоматизации больших коллекций, но предполагает работу в скрипте, блокноте Jupyter или собственном приложении.

Скачать LayoutParser

Оценка 9.7 Рекомендуем
  • Редактирование PDF
  • Русский интерфейс
  • Просто новичкам
Скачать бесплатно на Windows
Лучшая альтернатива
LayoutParser
Оценка 8.5
  • Нет готового интерфейса
  • Сложная установка моделей
  • Нужны внешние OCR-модули
Скачать LayoutParser
Загрузка начнётся после нажатия

Как устроен рабочий процесс LayoutParser

Основная единица работы — страница документа, представленная изображением. Ее можно получить из JPEG, PNG, TIFF, кадра сканера, массива OpenCV или из PDF. После загрузки изображение передается детектору макета. Детектор не читает содержимое абзацев: он локализует области и присваивает им классы, например Text, Title, List, Table или Figure. Конкретный набор классов зависит от обучающего набора и карты меток, поэтому один и тот же код нельзя без проверки переносить между моделями PubLayNet, HJDataset, PRImA, Newspaper Navigator и TableBank.

Результат метода detect — объект Layout, похожий на список. Внутри находятся элементы TextBlock, а геометрия каждого элемента хранится в объекте Rectangle, Quadrilateral или Interval. К блоку можно присоединить текст, идентификатор, тип, оценку уверенности и служебные связи. Благодаря этому детекция, OCR и логика чтения не превращаются в несколько несогласованных массивов координат.

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

Пример обработки разных документов через API LayoutParser

Унифицированный API особенно полезен, когда в одном проекте встречаются журнальные страницы, научные статьи и исторические сканы. Сценарий остается одинаковым, но модель и карта классов подбираются под тип документов. Это снижает количество специальных правил, хотя не отменяет проверку результата на собственном наборе страниц.

Установка базовой библиотеки и дополнительных компонентов

Базовый пакет устанавливается командой python -m pip install layoutparser. Он включает структуры данных, операции над областями, функции визуализации и средства чтения или записи поддерживаемых представлений. Для воспроизводимого проекта лучше создать отдельное виртуальное окружение и зафиксировать версии зависимостей в файле требований, потому что OpenCV, Pillow, NumPy, pdfplumber и другие компоненты развиваются независимо.

python -m venv .venv
# Windows
.venv\Scripts\activate
# Linux и macOS
source .venv/bin/activate
python -m pip install --upgrade pip
python -m pip install layoutparser

Модели макета требуют отдельного бэкенда. Для EfficientDet используется дополнительный набор зависимостей layoutparser[effdet]. Вариант на PaddleDetection устанавливается через layoutparser[paddledetection]. Detectron2 подключается отдельно вместе с torchvision; его сборка должна соответствовать версии PyTorch, CUDA и операционной системе. Именно несовместимость этих компонентов чаще всего вызывает ошибки импорта и компиляции.

OCR также не включается одним базовым вызовом. Команда python -m pip install "layoutparser[ocr]" добавляет Python-обвязки, но для Tesseract требуется установленный системный движок и языковые данные. Для Google Cloud Vision нужны учетные данные и доступ к облачному API. Поэтому перед началом проекта стоит решить, будет ли текст распознаваться локально, в облаке или другим модулем, который получит обрезанные области от LayoutParser.

Проверка установки должна быть минимальной и конкретной. Сначала импортируйте пакет и создайте простой прямоугольник. Затем проверьте визуализацию. Только после этого подключайте тяжелый детектор. Такой порядок отделяет проблему базовой среды от проблемы PyTorch, Detectron2 или загрузки весов.

import layoutparser as lp
block = lp.TextBlock(lp.Rectangle(10, 20, 210, 120), type="Text")
layout = lp.Layout([block])
print(layout[0].coordinates)

Подготовка изображений перед анализом

Качество разметки зависит не только от модели. Страница должна быть повернута правильно, содержать достаточное число пикселей и не иметь обрезанных полей. Для сканов с сильным наклоном полезно выполнить deskew до передачи в детектор. Если поворот исправлять после детекции, координаты областей перестанут соответствовать изображению.

OpenCV читает цветные файлы в порядке BGR, а многие примеры визуализации и модели ожидают RGB. Поэтому после cv2.imread часто выполняют перестановку каналов image[..., ::-1]. Ошибка не всегда приводит к исключению, но способна ухудшить детекцию или сделать визуализацию неестественной. При использовании Pillow изображение уже обычно представлено в RGB.

Слишком крупные страницы потребляют много памяти, особенно при работе с нейросетевым бэкендом. Масштабирование допускается, но координаты результата относятся к уменьшенному изображению. Если их нужно перенести на оригинал, примените обратный коэффициент к x_1, y_1, x_2 и y_2. Для четырехугольников масштабируются все четыре вершины.

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

  • Не повышайте контраст настолько, чтобы тонкие символы исчезали.
  • Не удаляйте линии таблиц, если модель использует их как структурный признак.
  • Сохраняйте исходное изображение вместе с преобразованным вариантом для контроля.
  • Для многостраничного TIFF разбирайте кадры по одному и сохраняйте номер страницы.

Чтение PDF и связь координат со страницами

Функция load_pdf извлекает текстовые блоки и геометрию страниц через pdfplumber. При параметре load_images=True она дополнительно возвращает растровые представления, на которых можно рисовать рамки. Это удобно для PDF с уже существующим текстовым слоем: сначала можно использовать координаты встроенного текста, а детектор подключать только для классификации областей или для страниц, где текстового слоя нет.

pdf_layouts, page_images = lp.load_pdf(
    "document.pdf",
    load_images=True,
    dpi=144
)
first_page = pdf_layouts[0]
first_image = page_images[0]
preview = lp.draw_box(first_image, first_page)

Параметр dpi влияет на размер растровой страницы. При 72 dpi координаты близки к PDF-пунктам, а при 144 dpi размеры изображения удваиваются. Нельзя смешивать области, полученные при разных значениях dpi, без масштабирования. Это особенно важно, когда детекция выполняется по растровой копии, а затем координаты используются для наложения аннотаций в исходный PDF.

Для порядка символов и строк доступны параметры направления: слева направо, сверху вниз, использование текстового потока, допуски по горизонтали и вертикали. На сложных колонках встроенный порядок PDF может отличаться от визуального. В таком случае лучше использовать геометрическую сортировку или собственную логику чтения, чем доверять последовательности объектов в файле.

Пустые страницы следует обрабатывать явно. Конвейер должен уметь вернуть пустой Layout, сохранить номер страницы и продолжить обработку. Если код предполагает наличие первого элемента, пустой лист вызовет IndexError. Полезно проверять if not page_layout до сортировки, OCR и экспорта.

Для сканированного PDF без текстового слоя load_pdf не заменяет OCR. Получите изображение страницы, выполните детекцию макета, обрежьте нужные области и только затем распознавайте текст. Такой порядок лучше сохраняет таблицы, подписи и многоколоночную структуру, чем распознавание всей страницы одной строкой.

Выбор модели и понимание каталога

Идентификатор модели задает бэкенд, обучающий набор и архитектуру. Строка вида lp://PubLayNet/faster_rcnn_R_50_FPN_3x/config сообщает, что конфигурация относится к PubLayNet и использует Faster R-CNN. Для другого набора данных категории могут отличаться. Поэтому выбор делается не по названию архитектуры, а по сходству учебных документов с реальными страницами.

PubLayNet ориентирован на научные публикации и обычно выделяет текст, заголовки, списки, таблицы и рисунки. HJDataset содержит исторические японские документы и более детальные классы страниц. PRImA подходит для разнообразных печатных макетов, Newspaper Navigator — для газетных материалов, TableBank — для поиска таблиц. Модель, хорошо работающая на журналах, не обязана правильно размечать ведомости, рукописи или чеки.

Примеры наборов данных для моделей LayoutParser

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

AutoLayoutModel упрощает создание модели, когда идентификатор однозначно задает бэкенд. Явные классы вроде Detectron2LayoutModel дают больше контроля над конфигурацией, устройством вычислений и картой меток. В производственном коде полезно логировать полный идентификатор, порог, карту классов и контрольную сумму весов, чтобы результат можно было воспроизвести.

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

Карта меток и категории областей

label_map переводит числовые идентификаторы классов в понятные названия. Без корректной карты блок с номером 3 может быть ошибочно принят за таблицу, хотя в другой модели этот номер означает рисунок. Некоторые официальные конфигурации подставляют карту автоматически, но при собственных весах ее следует задавать явно.

label_map = {
    0: "Text",
    1: "Title",
    2: "List",
    3: "Table",
    4: "Figure",
}
model = lp.Detectron2LayoutModel(
    MODEL_URI,
    extra_config=["MODEL.ROI_HEADS.SCORE_THRESH_TEST", 0.8],
    label_map=label_map,
)

Название категории лучше хранить в одном регистре и без случайных пробелов. Фильтр b.type == "Text" не найдет блоки с типом text. При объединении результатов нескольких моделей заранее создайте внутреннюю схему, например text, title, table, figure, и преобразуйте в нее все внешние метки.

Оценка score относится к уверенности детектора, а не к качеству OCR. Блок с высокой вероятностью класса Text может содержать плохо читаемую строку. И наоборот, OCR может отлично прочитать область, которую модель классифицировала неуверенно. Для контроля нужны отдельные показатели: порог детекции, уверенность распознавания и логика геометрической проверки.

Если одна область полностью находится внутри рисунка, ее иногда нужно удалить из списка текстовых блоков. В официальном примере сначала выбираются типы Text и Figure, затем текст отбрасывается, если он расположен внутри Figure. Это не универсальное правило: подпись внутри диаграммы может быть полезной. Решение зависит от цели — восстановить основной поток статьи, собрать все надписи или извлечь только таблицы.

Структуры Coordinate, TextBlock и Layout

Геометрические классы отделены от содержимого. Interval описывает промежуток по оси x или y, Rectangle — прямоугольник по двум углам, Quadrilateral — четырехугольник по вершинам. TextBlock добавляет к геометрии текст, идентификатор, тип, оценку и связи. Layout объединяет элементы в последовательность и предоставляет групповые операции.

Структуры данных и операции LayoutParser

Координаты прямоугольника доступны как x_1, y_1, x_2, y_2 и как кортеж coordinates. Ширина, высота и площадь вычисляются из геометрии. Для изменения области доступны методы pad, shift и scale. Метод crop_image извлекает соответствующий фрагмент изображения, что делает передачу блока в OCR прямой и проверяемой.

Большинство методов поддерживает создание нового объекта, а некоторые принимают inplace=True. В конвейере лучше придерживаться одного стиля. Неожиданное изменение исходного Layout затрудняет сравнение этапов. Для отладки удобно сохранять исходный результат модели, очищенную копию и финальную последовательность с текстом.

Layout наследует поведение списка: элементы можно индексировать, перебирать, сортировать и объединять. Дополнительные методы filter_by, get_texts, get_info и преобразования позволяют писать меньше служебного кода. При этом типы элементов могут различаться, поэтому перед операцией, требующей прямоугольников, проверьте, не содержит ли коллекция четырехугольники.

Идентификатор id полезен для порядка чтения и трассировки. После сортировки можно присвоить последовательные номера, а при экспорте сохранить исходный идентификатор модели в отдельном поле. Тогда исправление порядка не уничтожит связь с первоначальной детекцией.

Операции над координатами и геометрией

Метод pad расширяет или сужает область. Небольшое расширение перед OCR часто захватывает крайние символы, которые детектор обрезал слишком плотно. Отрицательные значения полезны для удаления рамки таблицы, однако чрезмерное сужение отрежет буквы. Поля следует задавать отдельно для каждой стороны, потому что ошибки рамки обычно асимметричны.

shift переносит блок на заданное расстояние, а scale изменяет размеры относительно начала координат. Если нужно масштабировать относительно центра, сначала вычислите новый прямоугольник вручную или примените последовательность сдвигов. Операция relative_to переводит абсолютные координаты блока в систему другого блока, а condition_on выполняет обратное преобразование.

is_in проверяет вложенность. Параметр проверки по центру помогает выбрать элементы, центр которых попадает в колонку, даже если рамка немного выходит за границу. intersect возвращает общую область, union — объединенную. Для четырехугольников некоторые операции могут приводить к прямоугольному охватывающему блоку; этот эффект нужно учитывать, если важна точная перспектива.

При фильтрации по колонке удобно создать Interval по оси x и поместить его на холст изображения. В многоколоночной статье левая половина выбирается интервалом от нуля до чуть больше половины ширины. Небольшой запас помогает включить блоки, пересекающие условную границу, но может захватить элементы из соседней колонки. Порог проверяется визуально.

height, width = image.shape[:2]
left_zone = lp.Interval(0, width * 0.53, axis="x").put_on_canvas(image)
left_blocks = text_blocks.filter_by(left_zone, center=True)
right_blocks = lp.Layout([b for b in text_blocks if b not in left_blocks])

Фильтрация, удаление пересечений и объединение блоков

Сырые результаты детектора часто содержат вложенные или перекрывающиеся рамки. Простое удаление всех пересечений опасно: заголовок может частично заходить на рисунок, а таблица — включать текстовые ячейки. Сначала определите приоритет классов. Например, при извлечении основного текста можно исключить Text внутри Figure, но сохранить Title над рисунком и Caption под ним.

Для близких блоков одного типа полезно оценивать вертикальный разрыв, горизонтальное перекрытие и сходство высоты строки. Если два прямоугольника относятся к одному абзацу, их объединяют через union. Если разрыв велик или между ними есть заголовок, объединение разрушит структуру. Лучше хранить пороги в конфигурации, а не зашивать их в тело цикла.

Мягкие поля soft_margin в filter_by компенсируют небольшое несовпадение границ. В примере извлечения таблицы правое поле расширяется, чтобы последние строки не выпали из выбранной колонки. Поля должны соответствовать разрешению изображения: десять пикселей при 72 dpi и при 300 dpi означают разную физическую величину.

Для удаления дубликатов сравнивайте не только IoU. Два блока с почти одинаковыми координатами и разными типами могут быть конфликтом классификации. Можно оставить блок с большей уверенностью, если типы равноправны, либо применить приоритет, например Table выше Text. Все удаленные элементы полезно логировать, чтобы настройка не превращалась в необъяснимую потерю данных.

Геометрическая очистка должна проходить до OCR, иначе вы распознаете одни и те же символы несколько раз. Однако исходный layout стоит сохранить: иногда OCR помогает решить конфликт, потому что один из перекрывающихся блоков содержит осмысленный текст, а другой — шум.

Восстановление порядка чтения

Детектор возвращает набор областей, но не гарантирует правильную последовательность чтения. Для простой страницы элементы сортируют по y, затем по x. На двух колонках сначала выделяют левую и правую области, сортируют каждую сверху вниз и объединяют. На газетной полосе или странице с врезками нужен более сложный граф зависимостей.

Официальный пример присваивает идентификаторы после разделения страницы на две колонки. Этот номер затем отображается поверх рамки и позволяет проверить, что текст идет в естественном порядке. Ошибка видна сразу: номер из правой колонки окажется между двумя блоками левой.

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

Для сложного документа можно построить ориентированный граф: ребро A→B означает, что A читается раньше B. Правила используют вертикальное положение, перекрытие по x, класс и ширину. Топологическая сортировка дает последовательность, а циклы показывают конфликт правил. Такой подход надежнее длинной цепочки условных операторов.

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

Разметка сложной страницы и выделение областей LayoutParser

Визуализация рамок и текста

draw_box накладывает области на исходное изображение. Можно настроить толщину рамки, прозрачность заливки, цвет по типу, отображение идентификатора и категории. Для отладки рекомендуется использовать стабильную карту цветов: одинаковый класс должен выглядеть одинаково на всех страницах и этапах.

draw_text создает текстовый холст и размещает распознанные строки в соответствующих координатах. В одном режиме результат показывается рядом с оригиналом, что помогает сравнить OCR и исходный документ. Опция рамок вокруг текста делает видимыми пустые или слишком узкие области.

Два режима визуализации LayoutParser

Наложение с высокой непрозрачностью скрывает мелкие символы. Для контроля границ лучше использовать тонкую рамку и прозрачную заливку. При проверке порядка чтения полезны крупные идентификаторы на контрастном фоне. Для итоговой иллюстрации, наоборот, идентификаторы можно убрать, оставив только категории.

Функции визуализации возвращают новое изображение, однако в старых сценариях встречались проблемы с изменением исходного массива. Чтобы исключить побочный эффект, передавайте копию или храните оригинал отдельно. После сохранения проверяйте цветовой порядок, особенно если результат проходит через OpenCV.

Большие страницы лучше уменьшать только для просмотра, а координаты и OCR выполнять в полном разрешении. Сохраняйте в имени файла номер страницы, модель и этап: p003_detected.png, p003_filtered.png, p003_ordered.png. Это ускоряет поиск причины ошибки в пакетной обработке.

Распознавание текста через Tesseract

TesseractAgent связывает область LayoutParser с движком Tesseract. Языки задаются при создании агента. Для русского текста нужен установленный пакет русских данных, для смешанного документа можно указать несколько языков. Отсутствующий язык обычно приводит к ошибке запуска или к распознаванию неверной моделью.

ocr = lp.TesseractAgent(languages="rus+eng")
for block in text_blocks:
    crop = block.pad(left=5, right=5, top=3, bottom=3).crop_image(image)
    block.set(text=ocr.detect(crop), inplace=True)

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

Числовые строки требуют особого контроля. В старых сценариях автоматическое преобразование могло интерпретировать последовательности цифр как числа с плавающей точкой. Экспортируйте OCR как текст и преобразуйте тип только после проверки формата. Идентификаторы, номера партий и почтовые индексы нельзя безусловно превращать в числа, поскольку ведущие нули имеют значение.

Tesseract не выделяет таблицы как структуру. LayoutParser определяет геометрию, но строки и столбцы все равно нужно группировать по координатам. Для документов с линиями можно использовать их как границы; для безлинейных таблиц — кластеризовать центры слов и интервалы между строками.

Если результат пустой, проверьте путь к исполняемому файлу, язык, размер фрагмента и контраст. Если текст читается, но порядок символов неверен, измените режим сегментации Tesseract в собственном вызове или распознавайте более крупный блок. LayoutParser не скрывает настройки внешнего движка, поэтому сложные параметры иногда удобнее передать напрямую.

Распознавание через Google Cloud Vision

GCVAgent используется для отправки изображения в Google Cloud Vision. Агент создается с путем к файлу учетных данных и подсказками языков. Поскольку данные уходят во внешний сервис, документам с персональной или коммерческой информацией требуется отдельная оценка политики хранения и доступа.

Метод detect может вернуть готовый текст либо исходный ответ API. В полном ответе доступны два уровня представления: text_annotations и иерархическая full_text_annotation. LayoutParser умеет собирать элементы уровня PAGE, BLOCK, PARA, WORD или SYMBOL. Для таблиц обычно выбирают WORD, чтобы сохранить координаты отдельных значений.

После получения ответа gather_full_text_annotation преобразует слова в объекты layout. Далее применяются те же фильтры, сортировка и визуализация, что и для результатов детектора. Это важное преимущество общей структуры данных: облачный OCR можно заменить локальным, не переписывая весь последующий код.

Визуализация слов, распознанных через OCR в LayoutParser

Ошибки аутентификации обычно связаны с неверным путем, недоступным проектом или изменением версии клиентской библиотеки. Не храните ключ в репозитории. Перед пакетным запуском проверьте один небольшой файл и обработайте исключения квоты, сети и временной недоступности.

Стоимость и задержка зависят от числа запросов. Если страница отправляется по одному блоку, запросов становится много. Иногда эффективнее распознать всю страницу одним вызовом, получить координаты слов и затем отфильтровать их по областям LayoutParser. Решение зависит от ограничений API и качества распознавания на вашем типе документов.

Извлечение таблиц по координатам

LayoutParser не преобразует любую таблицу в готовый DataFrame одной командой. Он дает строительные блоки: область таблицы, слова с координатами, интервалы строк и столбцов. В официальном примере сначала распознается вся страница, затем выбираются две колонки по прямоугольникам, а слова группируются по вертикальным интервалам.

Для таблицы с фиксированной высотой строк можно задать начальную координату, число строк и шаг. Такой способ прост и воспроизводим, но ломается при переносах текста и разной высоте строк. Более устойчивый вариант вычисляет расстояния между соседними блоками, строит распределение и разделяет строки по порогу.

Автоматическое группирование тоже ошибается. Если в одной ячейке две строки, дополнительный блок сдвигает границу и может объединить значения соседних строк. Для контроля сравнивайте вертикальные центры нескольких колонок, используйте допустимое расхождение и оставляйте пустую ячейку, когда соответствие не найдено.

Столбцы определяются диапазонами x. Жесткие координаты подходят для формы одного шаблона. Для разных масштабов нормализуйте координаты на ширину страницы. Для меняющегося шаблона сначала найдите заголовки столбцов, затем создайте границы по их центрам.

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

  • Удаляйте переносы и лишние пробелы только после объединения слов.
  • Не теряйте вопросительные знаки и другие признаки неуверенного OCR.
  • Проверяйте уникальность ключевых столбцов и допустимые форматы дат.
  • Для денежных значений отделяйте OCR от преобразования десятичного разделителя.

Загрузка и сохранение JSON, CSV и DataFrame

LayoutParser поддерживает преобразование layout в словари и табличное представление. JSON подходит для вложенных данных и сохранения полей каждого блока. CSV удобен для анализа и обмена, но хуже описывает многостраничную иерархию. DataFrame полезен внутри Python для фильтрации, группировки и проверки.

При экспорте сохраняйте координатный тип и размер страницы. Четыре числа без сведений о dpi и ширине изображения трудно использовать позже. Для многостраничного документа добавляйте page_index, а для нескольких моделей — model_id и stage.

Текст может содержать переводы строк, кавычки и разделители CSV. Используйте стандартные средства pandas или csv, а не собирайте строки вручную. Кодировка UTF-8 сохраняет русский текст, но при открытии в некоторых табличных редакторах может потребоваться вариант с BOM. Это вопрос экспорта, а не распознавания.

JSON удобно версионировать. Добавьте собственное поле схемы, чтобы отличать старые файлы от новых. Если позже появится confidence OCR или связи между блоками, загрузчик сможет обработать обе структуры. Не полагайтесь на порядок ключей JSON; порядок чтения храните явным id или reading_order.

Перед повторной загрузкой проверьте типы. Координаты могут стать целыми или вещественными числами, а пустой текст — значением null. Нормализация типов в одном месте уменьшает количество скрытых ошибок в сортировке и сравнении.

Работа с аннотациями COCO

COCO хранит изображения, категории и прямоугольники в JSON. LayoutParser можно использовать как удобный слой для загрузки аннотаций, визуальной проверки и сравнения с прогнозом модели. Каждый объект COCO преобразуется в TextBlock с прямоугольником, типом категории и идентификатором аннотации.

Для работы с исходным форматом обычно подключается pycocotools. Код получает информацию об изображении, список аннотаций и карту категорий. Затем draw_box накладывает рамки на страницу. Цветовая карта должна соответствовать классам набора.

Визуализация COCO-аннотаций через LayoutParser

Отображение идентификатора и типа помогает искать ошибки разметки. Если рамка выходит за границы, категория перепутана или два объекта дублируются, это видно до обучения. В больших наборах полезно автоматически проверять отрицательные координаты, нулевую площадь, неизвестные категории и несоответствие размера изображения.

После загрузки аннотаций можно запустить модель на той же странице и сравнить два Layout. Сопоставление выполняется по IoU и классу. Для полноценной оценки нужны метрики набора, но визуальное сравнение быстро показывает систематические проблемы: слишком широкие таблицы, пропуск заголовков, путаницу рисунков и текста.

При собственном экспорте в COCO не забывайте, что формат bbox использует x, y, ширину и высоту, тогда как Rectangle хранит две пары углов. Преобразование должно быть явным: w=x_2-x_1, h=y_2-y_1. Идентификаторы изображений и аннотаций должны быть уникальными во всем файле.

Подготовка собственных данных и корректировка разметки

Если готовая модель плохо различает классы конкретных документов, требуется собственная разметка и дообучение. LayoutParser связан с инструментами аннотирования, которые позволяют загрузить предварительные прогнозы и исправлять их, а не рисовать все рамки с нуля. Это ускоряет создание набора, но предварительные ошибки могут влиять на разметчика, поэтому часть страниц полезно размечать независимо.

Интерфейс корректировки разметки для проектов LayoutParser

Схема классов должна отвечать конечной задаче. Если нужно извлекать таблицы и подписи, классы Table и Caption важнее тонкого разделения абзацев. Слишком много похожих категорий уменьшает согласованность разметки. Перед массовой работой подготовьте инструкцию с примерами пограничных случаев.

Набор делят на обучение, проверку и тест по документам, а не по случайным страницам одного PDF. Иначе страницы с одинаковым дизайном попадут в обе части, и оценка будет завышена. В тест включают разные качества сканирования, ориентации и типы шаблонов.

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

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

Настройка производительности и памяти

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

GPU ускоряет поддерживаемые модели, но требует совместимых PyTorch, CUDA и драйвера. Параметр принудительного CPU полезен для воспроизводимости и для среды без правильно настроенной видеокарты. На CPU можно уменьшить размер страницы или выбрать более легкую архитектуру, однако изменение масштаба требует обратного пересчета координат.

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

OCR через внешний сервис ограничивается сетью и квотами. Локальный Tesseract чаще упирается в CPU. Разделение стадий позволяет сначала детектировать и сохранить обрезанные области, а затем распознавать их отдельным пулом работников. При сбое не придется повторять детекцию всего PDF.

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

Пакетная обработка больших коллекций

Для тысяч файлов нужен журнал на уровне документа и страницы. Записывайте входной путь, номер страницы, время каждого этапа, количество областей, предупреждения и путь к результату. Ошибка одного PDF не должна останавливать очередь. После завершения отдельный отчет показывает файлы, требующие повторной обработки.

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

Промежуточные файлы занимают место, но сильно упрощают восстановление. Минимальный набор — исходный layout модели, очищенный layout, OCR-текст и финальный экспорт. Визуальные PNG можно сохранять только для страниц с низкой уверенностью или аномальным числом блоков.

Идемпотентность означает, что повторный запуск не создает дубликаты и не меняет готовые результаты без причины. Сравнивайте конфигурацию и контрольную сумму входа. Если файл и настройки не изменились, страницу можно пропустить. Если изменилась только стадия экспорта, повторно используйте сохраненный layout.

Для очереди полезно разделять постоянные и временные ошибки. Поврежденный PDF не исправится после десяти повторов, а временная недоступность весов или облачного OCR может исчезнуть. Ограничьте число попыток и сохраняйте последнее исключение полностью.

Диагностика проблем с установкой

Модуль импортируется, но класс модели недоступен

Бэкенды подключаются динамически. Если установлен только базовый пакет, класс или зависимость конкретной модели может отсутствовать. Проверьте выбранный тип модели и установите соответствующий дополнительный набор. Затем перезапустите интерпретатор, потому что Jupyter продолжает использовать уже загруженные модули.

Detectron2 не устанавливается в Windows

Совместимость Detectron2 с Windows сложнее, чем с Linux и macOS. Ошибки компилятора, pycocotools, CUDA и Visual C++ часто появляются одновременно. Практичный путь — использовать WSL2 или контейнер Linux с согласованными версиями PyTorch и CUDA. Если требуется чистая Windows, фиксируйте проверенную комбинацию и не обновляйте компоненты по отдельности.

Ошибка загрузки весов или UnpicklingError

Проверьте, что файл действительно является весами, а не HTML-страницей с сообщением об ошибке. Посмотрите размер и первые байты, удалите поврежденный файл из кэша и загрузите снова. Корпоративный прокси может возвращать страницу авторизации вместо бинарного содержимого.

OpenCV показывает неверные цвета

Причина обычно в смешении BGR и RGB. Перед передачей в функции, ожидающие RGB, переставьте каналы. При сохранении через OpenCV выполните обратное преобразование. Координаты при этом не меняются.

Визуализация падает на идентификаторах

Убедитесь, что id имеет ожидаемый тип и не содержит сложный объект. Для диагностики отключите отображение идентификаторов, затем присвойте простые строки или целые числа. Проверьте шрифт и размер на очень маленьких блоках.

Диагностика ошибок детекции и OCR

Модель пропускает мелкие заголовки

Снизьте порог уверенности и увеличьте разрешение страницы. Затем проверьте, не исчезли ли заголовки при предварительной бинаризации. Если модель обучалась на другом типе документа, настройка порога может не помочь — потребуется другая модель или дообучение.

На странице слишком много перекрывающихся рамок

Повышайте порог постепенно и применяйте подавление дубликатов по IoU с учетом класса. Не удаляйте вложенные области без анализа: текст внутри таблицы может быть полезен. Сохраните визуализации до и после фильтра.

Текст читается в неправильном порядке

Последовательность layout не является готовым порядком чтения. Разделите страницу на колонки, обработайте широкие заголовки и присвойте идентификаторы после сортировки. Для сложного макета используйте граф зависимостей.

OCR теряет крайние символы

Расширьте область методом pad. Если соседний текст начинает попадать в фрагмент, увеличьте только нужную сторону. Проверьте, не была ли рамка уменьшена при переносе координат между масштабами.

Табличные строки смешиваются

Не используйте один вертикальный порог для всех документов. Оцените медианную высоту текста и интервалы между центрами. Сопоставляйте строки по нескольким колонкам и допускайте пустые ячейки. При многострочной ячейке объединяйте блоки внутри диапазона строки до формирования DataFrame.

Пустой результат на сканированном PDF

Проверьте, что вы получили растровое изображение страницы. Чтение текстового слоя не извлечет символы из скана. Выполните детекцию по изображению, затем OCR. Для очень темной страницы проверьте динамический диапазон и ориентацию.

Совместимость с операционными системами и средами

Базовые структуры LayoutParser написаны на Python и не привязаны к одному рабочему столу, но фактическая совместимость определяется зависимостями. Pillow, NumPy, pandas и pdfplumber обычно устанавливаются на Windows, Linux и macOS без сложной настройки. Нейросетевые бэкенды и системный OCR требуют отдельной проверки.

Linux чаще выбирают для Detectron2 и GPU, потому что доступны проверенные сочетания CUDA и контейнеров. macOS подходит для базовых функций и части моделей, но ускорение зависит от конкретного бэкенда. Windows удобен для разработки базового кода, однако сборка Detectron2 может потребовать WSL2.

В Jupyter вывод изображений и пошаговый просмотр упрощают настройку. В производственном сервисе те же вызовы помещаются в функцию или очередь задач. Не оставляйте магические команды блокнота в модуле Python; импорты и конфигурацию переносите в обычный код.

Контейнер фиксирует системные библиотеки, Tesseract, Poppler, PyTorch и модельный кэш. Это снижает различия между компьютерами. Для GPU контейнеру нужен доступ к драйверу хоста. Сборку проверяют на том же типе устройства, где будет обработка.

Файл wheel с тегом py3-none-any не содержит платформенно-зависимого бинарного кода самого LayoutParser. Это не означает, что весь стек универсален: opencv-python, PyTorch, Detectron2 и системные утилиты имеют собственные ограничения.

Проверка качества результата

Качество оценивают на уровне рамок, классов, порядка чтения, OCR и конечной структуры. Высокая точность детектора не гарантирует правильный CSV, если строки таблицы сгруппированы неверно. Поэтому контрольный набор должен проходить весь конвейер.

Для рамок используют IoU и метрики по классам. Для OCR — посимвольную или пословную ошибку. Для порядка чтения можно сравнивать последовательность идентификаторов с эталоном. Для таблицы проверяют строки, столбцы и значения ячеек. Все показатели полезно разбивать по типам документов.

Визуальная выборка остается обязательной. Автоматические метрики могут не заметить, что подпись присоединена к неправильному рисунку, а два абзаца поменялись местами. Отбирайте страницы с низкой уверенностью, необычным числом блоков и большим числом перекрытий.

Контроль регрессий выполняется после изменения модели, порога, dpi или правил фильтрации. Храните эталонные JSON и изображения. Сравнивайте не только среднюю метрику, но и конкретные страницы, которые ухудшились. Малое улучшение на массе документов может скрыть критическую ошибку на таблицах.

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

Безопасность, конфиденциальность и воспроизводимость

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

Облачный OCR отправляет содержимое поставщику сервиса. До использования определите, допустимы ли персональные данные, медицинские документы, договоры и коммерческая тайна. Ключи доступа храните в секретах среды, а не в коде и не в блокноте.

Экспортированные JSON и PNG могут содержать тот же чувствительный текст, что и исходный PDF. Промежуточные файлы должны иметь ограниченный доступ и срок хранения. Логи не должны печатать полный OCR-текст, если он не нужен для диагностики.

Воспроизводимость требует фиксировать версии Python, LayoutParser, бэкенда, OCR, модели, весов, конфигурации и параметров подготовки изображения. Один номер пакета недостаточен: одинаковый код с другой моделью или dpi даст другой результат.

При обновлении зависимостей сначала собирайте новую среду параллельно. Прогоните контрольный набор и сравните результаты. Не меняйте рабочее окружение на месте без возможности отката.

Практические сценарии использования

Научные статьи и журналы

Модель на PubLayNet выделяет текст, заголовки, списки, таблицы и рисунки. После фильтрации можно восстановить колонки, отправить только текстовые блоки в OCR и сохранить таблицы отдельно. Для PDF с текстовым слоем OCR иногда не нужен: координаты встроенного текста объединяются с категориями детектора.

Исторические газеты и книги

Страницы требуют выравнивания, контроля контраста и модели, близкой к историческим макетам. Газетные врезки и несколько колонок усложняют порядок чтения. Результат лучше хранить как граф или иерархию, а не как простую строку.

Формы и ведомости

Если шаблон стабилен, после детекции можно фильтровать области по нормализованным координатам. Табличные поля группируются по строкам. Для нового шаблона правила следует настраивать отдельно; универсальные координаты здесь редко работают.

Подготовка данных для поиска и RAG

LayoutParser помогает не смешивать заголовки, основной текст, подписи и таблицы. Каждый фрагмент получает страницу и координаты, что позволяет показывать источник ответа. До индексации необходимо исправить порядок чтения и удалить дубликаты из перекрывающихся областей.

Контроль наборов разметки

COCO-аннотации загружаются в Layout и визуализируются. Автоматические проверки находят неверные координаты, а сравнение с моделью помогает отобрать подозрительные страницы для ручного просмотра.

Ограничения, которые нужно учитывать заранее

У LayoutParser нет готового окна для открытия PDF, выбора области мышью и экспорта по кнопке. Пользователь формирует процесс кодом. Для разовой ручной правки PDF это избыточно; инструмент раскрывается в повторяемых конвейерах и исследованиях.

Базовая установка не дает автоматическую детекцию без модельного бэкенда. Detectron2 может быть сложен на Windows, а веса занимают место и загружаются отдельно. Для защищенной сети это нужно предусмотреть до развертывания.

OCR выполняют внешние движки. LayoutParser связывает их результаты со структурой, но не гарантирует качество распознавания языка, рукописи или плохого скана. Точность зависит от Tesseract, облачного API или другого подключенного распознавателя.

Готовые модели ограничены обучающими наборами. Необычные формы, чертежи, рукописи, рекламные полосы и документы с нестандартными классами могут потребовать дообучения. Простая смена порога не исправит систематическое несоответствие домена.

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

Порядок чтения не является встроенным универсальным результатом каждой модели. Его восстанавливают по геометрии и классу. Для многоуровневой верстки нужны правила, граф или отдельная модель порядка.

Сравнение LayoutParser с аналогами

Прямые аналоги различаются не только точностью, но и уровнем готовности. Одни сосредоточены на OCR, другие дают полный разбор документа, третьи рассчитаны на исследовательское обучение моделей. Выбор зависит от того, нужна ли только геометрия макета, распознанный текст, чтение таблиц или готовый вывод для дальнейшей обработки.

ПрограммаЛучше подходит дляГлавное ограничение
LayoutParserГибких Python-конвейеров с собственными правилами геометрии, моделями и OCRНет готового пользовательского интерфейса, бэкенды устанавливаются отдельно
PaddleOCRКомплексного OCR и структурного разбора PDF с таблицами, формулами и несколькими языкамиБольшой стек компонентов и заметные требования к настройке моделей
docTRСовременного двухэтапного OCR с детекцией и распознаванием текста, а также анализа элементов страницыОсновной акцент сделан на OCR, собственные геометрические правила нужно строить отдельно
MMOCRИсследований и обучения моделей обнаружения, распознавания и извлечения ключевой информацииКонфигурации OpenMMLab сложнее для быстрого прикладного запуска
SuryaМногоязычного OCR, анализа макета, порядка чтения и распознавания таблиц одним современным наборомТяжелая модель требует значительных вычислительных ресурсов

LayoutParser выбирают, когда важна прозрачная объектная модель областей и возможность собрать собственный конвейер. PaddleOCR удобнее для готового комплексного разбора, docTR — для OCR с выбираемыми архитектурами, MMOCR — для экспериментов и обучения, Surya — для современного многоязычного процесса с порядком чтения. PDF Commander решает другую задачу: ручное редактирование и управление PDF, поэтому он не заменяет библиотеку анализа макета и не включен в таблицу прямых аналогов.

Как выбрать конфигурацию для проекта

Начните с конечного формата. Если нужен список областей и координат, достаточно базовых структур и детектора. Если нужен текст, выберите OCR. Если нужен DataFrame таблицы, заранее спроектируйте группировку строк и столбцов. Такой порядок не позволяет ошибочно считать, что одна модель решит все стадии.

Затем соберите 30–100 типичных страниц, включая плохие. Проверьте несколько моделей и порогов на одном наборе. Не выбирайте по красивой демонстрации: измеряйте пропуски нужных классов и время обработки.

Для первого прототипа используйте Jupyter и сохраняйте визуализации. После стабилизации вынесите код в функции, добавьте конфигурацию, журнал и тесты. Модель создавайте один раз, а вход и выход функции делайте явными.

Для развертывания зафиксируйте зависимости, кэш весов и системные утилиты. Протестируйте чистую установку. Если Detectron2 вызывает слишком много сложностей, рассмотрите другой поддерживаемый бэкенд или аналог, который лучше соответствует среде.

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

Минимальный воспроизводимый пример

Ниже показана структура сценария без привязки к конкретному файлу. Он загружает изображение, создает модель, выполняет детекцию, выбирает текстовые блоки, сортирует их и сохраняет визуализацию. Перед запуском нужно установить подходящий бэкенд и заменить идентификатор модели на проверенный для ваших документов.

from pathlib import Path
import cv2
import layoutparser as lp

source = Path("page.png")
image_bgr = cv2.imread(str(source))
if image_bgr is None:
    raise FileNotFoundError(source)
image = image_bgr[..., ::-1]

model = lp.Detectron2LayoutModel(
    "lp://PubLayNet/faster_rcnn_R_50_FPN_3x/config",
    extra_config=["MODEL.ROI_HEADS.SCORE_THRESH_TEST", 0.8],
    label_map={0: "Text", 1: "Title", 2: "List", 3: "Table", 4: "Figure"},
)

raw_layout = model.detect(image)
text_layout = lp.Layout([b for b in raw_layout if b.type in {"Text", "Title"}])
text_layout.sort(key=lambda b: (b.coordinates[1], b.coordinates[0]), inplace=True)
text_layout = lp.Layout([b.set(id=i) for i, b in enumerate(text_layout)])

preview = lp.draw_box(image, text_layout, show_element_id=True, box_width=2)
preview.save("page-layout.png")

Для двух колонок простую сортировку следует заменить разделением по x. Для OCR добавьте агент и записывайте текст в каждый блок. Для многостраничного PDF поместите обработку страницы в функцию и вызывайте ее в цикле, сохраняя номер страницы.

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

Итоговый подход к надежной обработке

Надежный проект с LayoutParser строится вокруг явных промежуточных данных. Сначала сохраняется страница в согласованном цветовом пространстве и масштабе. Затем фиксируется сырой результат модели. После этого выполняются фильтры, порядок чтения, OCR и экспорт. Каждый переход можно проверить отдельно.

Главная практическая ценность библиотеки — единая геометрическая модель. Детекторы разных бэкендов, OCR и аннотации COCO превращаются в совместимые блоки. Это позволяет менять одну стадию без полной переработки остальных.

Лучший результат дает не максимальное число моделей, а точное соответствие документа и задачи. Для научных статей подходит одна схема классов, для ведомостей — другая, для исторических газет — третья. Контрольный набор и визуализация важнее предположений.

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

Контрольный список перед запуском обработки

Перед первой большой очередью проверьте, что входные страницы открываются без ошибок, цветовое пространство известно, ориентация исправлена, а dpi записан в конфигурации. Прогоните несколько страниц каждого типа и сохраните изображения с рамками. Убедитесь, что карта классов совпадает с моделью и что фильтры сравнивают строки в одном регистре.

Проверьте модельный кэш: весовой файл должен иметь ожидаемый размер и контрольную сумму. Запуск без сети должен успешно обработать контрольную страницу, если рабочая среда предполагает автономность. Для GPU запишите версию драйвера, CUDA и PyTorch; для CPU измерьте время на худшей странице.

OCR проверяют отдельно на русском, английском, цифрах и специальных символах. Для Tesseract убедитесь, что языковые данные установлены. Для облачного агента проверьте учетные данные, квоту и обработку сетевых исключений. Не выводите распознанный конфиденциальный текст в общий журнал.

Экспорт должен сохранять номер страницы, координаты, тип, текст и оценку уверенности там, где она доступна. Откройте JSON повторно и убедитесь, что координаты не изменились. CSV проверьте на строках с кавычками, запятыми и переводами строк. Для таблиц сравните несколько строк с оригиналом.

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

Наконец, выполните повторный запуск на тех же данных. Результаты должны совпасть, а готовые страницы не должны дублироваться. Смоделируйте сбой посередине очереди и убедитесь, что обработка продолжается с нужного места. Такой тест выявляет больше практических проблем, чем успешный запуск одного демонстрационного файла.

Геометрическая нормализация и перенос координат

Координаты в LayoutParser имеют смысл только вместе с системой отсчета страницы. Если изображение уменьшено перед детекцией, рамки модели относятся к уменьшенной копии, а не к исходному PDF. Поэтому коэффициент масштаба нужно сохранять явно. При уменьшении ширины с 2400 до 1200 пикселей координаты по обеим осям умножают на два перед записью в исходную систему. Отдельно учитывают поворот: после исправления страницы на 90 градусов меняются не только x и y, но и ширина с высотой.

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

Методы pad, shift и scale полезны для типовых преобразований. pad расширяет область вокруг найденного объекта, чтобы OCR получил поля и не потерял крайние символы. shift возвращает локальные координаты вырезанного фрагмента в координаты всей страницы. scale применяют после изменения разрешения. После каждого действия стоит визуализировать несколько областей: ошибка на один коэффициент часто выглядит правдоподобно в JSON, но сразу заметна на изображении.

Интервалы Interval позволяют задавать полосу по одной оси. Например, вертикальный интервал от нуля до половины ширины выбирает левую колонку, а горизонтальный интервал ниже верхнего колонтитула исключает шапку. Метод filter_by поддерживает проверку по центру объекта. Это важно для блоков, которые слегка пересекают границу колонки: выбор по полному вхождению может отбросить полезный абзац, а выбор по центру обычно устойчивее.

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

При работе с PDF следует различать пиксели растра и пункты PDF. Размер страницы в пунктах не равен размеру изображения, если оно получено с произвольным dpi. Для возврата рамки в PDF вычисляют коэффициенты отдельно по x и y: ширину страницы в пунктах делят на ширину растра, высоту — на высоту растра. Если PDF-библиотека использует начало координат снизу, координату y дополнительно отражают относительно высоты страницы.

Нормализация особенно важна при объединении результатов нескольких детекторов. Один модуль может получать страницу 150 dpi, другой — 300 dpi, а OCR — отдельные вырезки. Перед сравнением все рамки переводят в общую систему. После этого можно вычислять IoU, удалять дубликаты и связывать текст с родительским блоком. Без общей системы координат совпадения будут случайными, даже если каждый модуль сам по себе работает правильно.

Построение воспроизводимого конвейера

Практический конвейер удобно разделить на функции: загрузка страницы, подготовка изображения, детекция, постобработка, OCR, экспорт и контроль качества. LayoutParser связывает центральные этапы через объекты Layout и TextBlock, но не навязывает способ запуска. Поэтому границы этапов нужно определить в собственном коде и не смешивать, например, скачивание PDF, вызов модели и запись базы данных в одной длинной функции.

Конфигурация должна содержать идентификатор модели, карту меток, порог уверенности, параметры растеризации PDF, языки OCR и правила сортировки. Ее сохраняют рядом с результатом. Тогда JSON с блоками можно интерпретировать через месяц: понятно, почему область получила тип Table, какой порог применялся и в каком масштабе выполнялась детекция. Без такой записи два запуска с разными параметрами внешне выглядят одинаково, но дают несопоставимые данные.

Модель создают один раз на процесс, а не для каждой страницы. Инициализация загружает конфигурацию и веса, поэтому повтор внутри цикла резко увеличивает время. В веб-службе объект модели обычно помещают в долгоживущий рабочий процесс; в пакетной задаче — перед циклом по файлам. Если одновременно работают несколько процессов с GPU, им задают контролируемое число экземпляров, иначе память видеокарты исчерпывается еще до обработки первой страницы.

Для каждой страницы полезно сохранять три уровня результата: исходное изображение или его идентификатор, сырой вывод модели и нормализованный Layout после правил. Сырой слой нужен для диагностики: если итоговый блок пропал, можно понять, не нашла ли его модель или его удалил фильтр. Нормализованный слой используют далее, чтобы OCR и экспорт не зависели от внутреннего формата конкретного бэкенда.

Идентификатор документа и номер страницы следует добавлять к каждому блоку при экспорте. Внутренний id элемента обычно уникален только внутри Layout, поэтому его недостаточно для общей базы. Практичный составной ключ включает документ, страницу, тип и порядковый номер. При повторной обработке ключи должны создаваться детерминированно, иначе сравнение результатов превратится в сопоставление случайных записей.

Ошибку отдельной страницы не стоит превращать в потерю всей очереди. Исключения перехватывают вокруг этапа страницы, записывают тип ошибки и продолжают обработку, если данные остальных страниц независимы. При этом нельзя скрывать сбой пустым Layout: пустая страница и авария модели — разные состояния. В экспорте нужны явные поля статуса, а в итоговом отчете — количество успешных, пустых и ошибочных страниц.

Повторный запуск ускоряют кэшем. Ключ кэша должен учитывать контрольную сумму входного файла, страницу и параметры, влияющие на вывод. Если изменился порог или карта классов, прежний результат нельзя считать действительным. Кэширование особенно полезно, когда отлаживается порядок чтения или экспорт: детекцию можно не повторять, а загружать сохраненный Layout и тестировать только последующие этапы.

Для параллельной обработки CPU-задач страницы распределяют между процессами, но учитывают размер изображений и стоимость передачи данных. Часто проще передавать путь и номер страницы, а растр создавать внутри рабочего процесса. На GPU размер пакета подбирают экспериментально; LayoutParser не отменяет ограничений выбранного детектора. Метрики должны включать время растеризации, детекции, OCR и записи, иначе невозможно понять, какой этап действительно тормозит очередь.

Проверка качества на собственных документах

Качество нельзя оценивать по одной красивой странице из документации. Соберите небольшой набор, отражающий реальные отклонения: разные шаблоны, сканы, повороты, таблицы без линий, много колонок, подписи к рисункам и страницы с почти пустыми полями. Для каждого типа достаточно нескольких тщательно размеченных примеров, чтобы увидеть систематическую ошибку и не принимать случайный успех за надежность.

Разметка должна совпадать с задачей. Если последующему процессу нужны только таблицы, нет смысла спорить о различии Title и Text на каждой странице. Если требуется восстановление порядка чтения, одной точности рамок недостаточно: нужно проверять последовательность элементов. LayoutParser позволяет хранить геометрию и типы, а метрики и правила приемки выбирает разработчик конвейера.

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

OCR оценивают после привязки текста к блокам. Сначала проверяют, что вырезка действительно содержит нужную область; затем сравнивают распознанную строку. Иначе геометрическая ошибка будет ошибочно записана на счет OCR. Для таблиц важны не только символы, но и правильное распределение по ячейкам или строкам. LayoutParser помогает выделить и упорядочить области, однако окончательная табличная структура требует отдельной логики.

Визуальный набор ошибок полезнее случайного просмотра. Для каждой категории автоматически сохраняют несколько страниц с рамками, идентификаторами и оценками. Отдельные каталоги для ложных срабатываний, пропусков и конфликтов классов ускоряют поиск причины. Если ошибка повторяется в одном месте страницы, вероятен дефект фильтра или шаблона; если она зависит от оформления, возможно, модель не соответствует домену.

Порог уверенности подбирают по кривой компромисса. Повышение порога уменьшает число ложных рамок, но может удалить слабые таблицы и мелкие подписи. Вместо единого порога иногда применяют разные значения по классам: для крупных Figure допустим один уровень, для небольших Title — другой. Такой фильтр выполняют после детекции, используя score каждого TextBlock, если бэкенд его возвращает.

Тесты правил чтения строят на ожидаемой последовательности идентификаторов. После сортировки получают список блоков и сравнивают его с эталоном. Для страниц со сложной компоновкой полезно разрешить частичный порядок: заголовок должен быть раньше колонок, подпись — после связанного рисунка, но независимые боковые заметки могут не иметь единственного правильного места. Это делает тест устойчивым и одновременно выявляет реальные нарушения.

Регрессионный набор запускают после изменения модели, версии зависимостей или правил геометрии. Сравнивают не только итоговый текст, но и количество блоков, классы, координаты и порядок. Допустимое отклонение для координат задают в пикселях или доле размера страницы. Резкий сдвиг всех рамок обычно указывает на изменение dpi или поворота, а локальные расхождения — на модель или постобработку.