Google Cloud Vision OCR распознаёт печатный и рукописный текст на фотографиях, сканах, PDF и TIFF, возвращает слова вместе с координатами и структурой страницы, а для быстрой проверки позволяет загрузить изображение в демонстрационное окно, увидеть найденные блоки и открыть исходный JSON-ответ.
Основной рабочий процесс строится вокруг проекта Google Cloud: пользователь включает Cloud Vision API, выбирает TEXT_DETECTION для надписей на обычных изображениях либо DOCUMENT_TEXT_DETECTION для плотных документов, передаёт файл через запрос или Cloud Storage и получает UTF-8-текст с геометрией распознанных элементов.
Результат не превращается автоматически в отредактированный PDF или таблицу. Сервис отдаёт данные для дальнейшей обработки, поэтому практическая работа включает проверку качества исходника, разбор fullTextAnnotation, хранение выходных JSON-файлов, контроль квот и создание собственного шага экспорта в нужный формат.
Открыть Google Cloud Vision OCR
- Редактирование PDF
- Русский интерфейс
- Просто новичкам
- Нужен проект Google Cloud
- PDF требует Cloud Storage
- Нет встроенного PDF-редактора
Как устроен рабочий процесс распознавания
Задача начинается не с выбора кнопки экспорта, а с определения вида исходника. Фотография вывески, ценника или экрана обычно содержит несколько разрозненных надписей, поэтому для неё удобен TEXT_DETECTION: первый элемент textAnnotations хранит цельную строку, а последующие элементы описывают отдельные слова и их boundingPoly. Скан договора, книги или анкеты лучше отправлять как DOCUMENT_TEXT_DETECTION. В этом режиме основным результатом становится fullTextAnnotation с уровнями page, block, paragraph, word и symbol, а также с признаком разрыва после символа или слова.
После выбора функции формируется запрос. Изображение можно вложить в JSON как Base64, указать путь к локальному файлу при использовании клиентской библиотеки или передать URI объекта в Cloud Storage. Для PDF и TIFF применяется файловый запрос: входной документ и каталог для результатов задаются через адреса gs://, после чего сервис создаёт долговременную операцию и записывает один или несколько JSON-файлов в указанный префикс бакета.
Распознанный текст следует рассматривать как набор данных, а не как готовый документ. Если конечная цель — поиск по архиву, достаточно сохранить общий текст и идентификатор исходника. Если нужно подсветить слова на странице, используются вершины многоугольников. Для восстановления абзацев анализируются блоки, переносы и пробелы. Для создания PDF с текстовым слоем потребуется отдельная библиотека, которая наложит невидимый текст на исходные страницы с учётом координат.
Быстрая проверка в демонстрационном окне
Официальное демонстрационное окно полезно до настройки проекта. В область загрузки перетаскивают JPEG, PNG, GIF, BMP, WebP, RAW или ICO, после чего страница показывает найденные объекты и аннотации. Для OCR демонстрация применяет DOCUMENT_TEXT_DETECTION и модель builtin/latest. Кнопка Show JSON раскрывает необработанный ответ, Reset очищает текущий результат, а New file возвращает область выбора другого изображения.

Демонстрация имеет несколько важных границ. Размер файла не должен превышать 20 МБ, JavaScript обязан быть включён, а PDF и TIFF в эту форму не принимаются. Подписи интерфейса доступны на английском, но текст внутри изображения может быть на поддерживаемом языке. Поэтому окно годится для сравнения качества нескольких вариантов одного скана, проверки рукописной страницы или изучения структуры ответа, но не заменяет пакетную обработку документов.
Практичная проверка состоит из трёх прогонов. Сначала загрузите исходный кадр без обработки и сохраните JSON. Затем выровняйте перспективу, обрежьте лишние поля и повторите распознавание. В третьем варианте слегка увеличьте контраст, не уничтожая тонкие штрихи. Сравнивайте не только цельную строку, но и количество слов, положение рамок и ошибки в похожих символах: латинской B и кириллической В, цифре 0 и букве O, единице и вертикальному штриху.
Создание проекта и включение Cloud Vision API
Для постоянных запросов нужен проект с включённым биллингом и активной службой Cloud Vision API. В консоли выбирают существующий проект или создают новый, затем открывают библиотеку API, находят Cloud Vision API и нажимают Enable. Проектный идентификатор отличается от отображаемого имени: он входит в команды, журналы, настройки квот и часть путей, поэтому его лучше сразу записать без опечаток.

Если кнопка включения недоступна, проверьте права. Разрешение serviceusage.services.enable обычно входит в роль Service Usage Admin, а владелец нового проекта получает его через роль Owner. В корпоративной организации доступ может ограничиваться политикой или группой, поэтому сообщение Permission denied не исправляется повторным нажатием. Администратор должен выдать требуемую роль именно в том проекте, где планируется обработка.
После включения API стоит открыть страницу Quotas, страницу Metrics и журнал аудита. Так вы заранее увидите, какой проект принимает запросы, какие лимиты действуют и кто менял настройки. Это особенно важно, когда одна учётная запись работает с несколькими тестовыми проектами: запрос может успешно пройти, но расходы и квоты окажутся привязаны не к тому месту, которое проверяет оператор.

Поиск службы в библиотеке API
В библиотеке удобно искать по точному имени Cloud Vision API, а не по общему слову OCR. В результатах рядом могут появиться другие продукты для анализа документов и изображений. Нужная карточка содержит название Cloud Vision API и назначение Image Content Analysis. Такая проверка предотвращает типичную ошибку, когда включают Document AI API, ML Kit на мобильной платформе или стороннюю интеграцию, а затем получают ответ о недоступном методе images:annotate.

После открытия карточки состояние Enable меняется на Manage. На странице управления доступны метрики трафика, доля ошибок, задержка, квоты и учётные данные. При первом тесте полезно оставить эту страницу открытой: если запрос из Cloud Shell завершился ошибкой, график и журнал помогают отличить неправильную авторизацию от неверного тела JSON или превышения лимита.
Страница Cloud Vision API в консоли
Карточка службы подтверждает, что включается именно API анализа изображений, содержащий OCR. Кнопка Try this API ведёт к средствам выполнения запросов, а Manage — к панели конкретного проекта. Здесь нет редактора страниц или списка распознанных документов: консоль предназначена для конфигурации, контроля вызовов и доступа, тогда как входные файлы и выходные данные живут в приложении пользователя либо в Cloud Storage.

При диагностике сначала убедитесь, что в верхней панели выбран правильный проект. Затем проверьте статус службы и наличие платёжного аккаунта. Даже если используется бесплатный объём запросов, проект обычно должен быть связан с биллингом. Ошибка, связанная с отключённым API, нередко выглядит как запрет доступа, хотя ключ или токен сформированы корректно.
Аутентификация без передачи секретов в коде
Клиентские библиотеки рассчитаны на Application Default Credentials. В локальной среде разработчик может выполнить вход через gcloud auth application-default login, а в Cloud Shell использовать уже доступную учётную запись. На сервере предпочтительна сервисная учётная запись, назначенная ресурсу, либо федерация удостоверений. Хранить постоянный JSON-ключ в репозитории, образе контейнера или каталоге сайта не следует.

ADC последовательно ищет подходящие учётные данные в известных местах. Благодаря этому один и тот же код может работать на ноутбуке, в Cloud Run и на виртуальной машине без замены вызова ImageAnnotatorClient. Если библиотека пишет, что не нашла credentials, проверьте переменную GOOGLE_APPLICATION_CREDENTIALS, активную учётную запись gcloud и то, действительно ли процесс видит файл, а не только интерактивный пользователь терминала.
Для команд REST удобно получить краткоживущий access token командой gcloud auth print-access-token и передать его в заголовке Authorization. Такой токен не равен API key. Ключ идентифицирует проект и подходит не для всех сценариев доступа, а OAuth-токен подтверждает полномочия субъекта. В производственном коде токен должен обновляться автоматически, а не сохраняться в конфигурации.

Роли и минимально необходимые разрешения
Приложению нужны права вызвать Vision API и прочитать входные объекты. Для PDF и TIFF добавляются операции Cloud Storage: чтение документа, создание выходных JSON-файлов и, при необходимости, просмотр состояния объектов. Разделяйте роли для входного и выходного бакетов. Процесс распознавания не обязан иметь возможность удалять весь архив или менять политику доступа бакета.

Ошибка 403 может возникнуть на нескольких уровнях. API не включён; у принципала нет права serviceusage.services.use; сервисная учётная запись не видит gs://-объект; выходной префикс закрыт для записи; организация запретила вызов внешнего сервиса; квотный проект не задан для пользовательских ADC. В тексте ошибки обычно есть имя отсутствующего permission или resource, поэтому полезнее разобрать поле error.details, чем создавать новые ключи наугад.
Если запрос отправляет веб-приложение от имени пользователя, настраиваются OAuth client ID и экран согласия. Для фоновой серверной обработки пользовательское OAuth-согласие чаще не требуется: служба работает от имени сервисной учётной записи. Неправильный выбор модели доступа усложняет поддержку и создаёт лишние секреты.
Когда нужны OAuth-клиенты
OAuth-клиент пригодится, если приложение должно получить разрешение конкретного человека и работать с его данными в рамках интерактивного сеанса. В форме выбирают тип приложения и указывают допустимые адреса перенаправления. Для утилиты командной строки или фонового обработчика обычно лучше ADC и сервисная учётная запись: пользователь не должен каждый раз подтверждать доступ к OCR.

Не путайте OAuth client secret с ключом сервисной учётной записи. Первый участвует в пользовательском потоке авторизации, второй представляет машинный субъект. Оба требуют защиты, но жизненный цикл и права различаются. После создания проверьте, какие scopes запрашивает приложение; Vision API не требует давать доступ к почте, контактам или другим несвязанным данным.
TEXT_DETECTION для надписей на изображениях
TEXT_DETECTION удобен для сцен, где текст является одним из объектов: дорожный знак, этикетка, ценник, серийный номер, экран прибора, упаковка или фотография доски. В textAnnotations первый элемент содержит объединённую расшифровку, а остальные — отдельные фрагменты с координатами. Такой ответ легко использовать для поиска слова, маскирования номера или показа рамок поверх изображения.
Функция не восстанавливает таблицу и не определяет значение поля по подписи. Если на чеке найдено слово Итого и сумма, приложение само должно связать их по координатам или передать документ специализированному парсеру. maxResults влияет на некоторые типы аннотаций, но для OCR нельзя полагаться на него как на способ ограничить число слов: лучше фильтровать итоговый массив в коде.
На повернутых и перспективных кадрах boundingPoly может быть наклонным четырёхугольником. Не заменяйте его прямоугольником только по минимальным и максимальным координатам, если планируется точная подсветка: при сильном наклоне рамка захватит соседний текст. Для визуализации соединяйте вершины в исходном порядке.
DOCUMENT_TEXT_DETECTION для плотных страниц
DOCUMENT_TEXT_DETECTION ориентирован на страницы, где важна иерархия. fullTextAnnotation.text даёт цельный текст, pages описывают размеры и свойства страницы, blocks делят содержимое на крупные области, paragraphs — на абзацы, words — на слова, symbols — на символы. На каждом уровне доступны confidence и геометрия, хотя заполнение отдельных полей может зависеть от типа запроса и ответа библиотеки.
Разрывы хранятся в detectedBreak после символа или слова. Значения SPACE, SURE_SPACE, EOL_SURE_SPACE, HYPHEN и LINE_BREAK позволяют понять, где вставить пробел, перенос строки или соединить слово, разорванное дефисом. Простое склеивание symbol.text без detectedBreak превращает страницу в непрерывную строку; вставка пробела после каждого слова разрушает пунктуацию и переносы.
Структура документа остаётся геометрической, а не семантической. Блок не гарантирует, что перед вами заголовок, подпись или ячейка таблицы. Для семантических сущностей, форм, чеков и договоров лучше рассмотреть Document AI или собственную модель поверх OCR-результата.
Поддерживаемые форматы и ограничения файла
Для изображений поддерживаются JPEG, PNG8, PNG24, GIF, анимированный GIF с обработкой первого кадра, BMP, WebP, RAW и ICO. PDF и TIFF также поддерживаются, но их обработка оформляется файловыми методами. Отправляемое изображение не должно превышать 20 МБ, а JSON-запрос — 10 МБ. Base64 увеличивает объём примерно на треть, поэтому файл, который укладывается в 20 МБ на диске, может не поместиться в JSON.
Для OCR рекомендуемый ориентир — около 1024×768 пикселей, но это не жёсткий минимум. Слишком маленькие символы теряются, а огромный кадр увеличивает трафик и задержку без пропорционального выигрыша. Изображение для OCR не должно превышать 75 миллионов пикселей; более крупный кадр сервис уменьшает. PDF может иметь размер до 1 ГБ, однако число страниц и способ запроса всё равно ограничены.
Не используйте расширение файла как единственную проверку. JPEG, переименованный в PNG, или повреждённый TIFF даст ошибку декодирования. Перед отправкой полезно открыть файл библиотекой изображений, проверить MIME-тип, число страниц, ориентацию и наличие пароля. Зашифрованный PDF, который нельзя прочитать без пароля, нужно расшифровать в разрешённом рабочем процессе до загрузки.
Подготовка изображения к распознаванию
Лучшее улучшение точности обычно даёт не фильтр резкости, а правильная геометрия. Обрежьте фон, выровняйте страницу, исправьте перспективу и убедитесь, что строки не уходят под сильным углом. У фотографии документа должны быть различимы все четыре края, а блики не должны закрывать символы. При съёмке глянцевой бумаги помогает рассеянный свет и небольшой наклон источника относительно камеры.
Не превращайте серый текст в чисто чёрно-белое изображение слишком агрессивным порогом. Тонкие штрихи, точки и диакритика исчезают первыми. Для бледного скана лучше поднять локальный контраст, удалить крупные цветные пятна и оставить полутона. Сильное шумоподавление способно соединить соседние буквы или стереть десятичную точку, поэтому результат нужно сравнивать на реальных контрольных страницах.
Разрешение оценивают по размеру символа, а не по размеру страницы. Если на фотографии 4000×3000 пикселей документ занимает четверть кадра, полезная область текста может быть меньше, чем у аккуратно обрезанного изображения 1600×1200. Сохраняйте исходник и подготовленный вариант: координаты ответа относятся к отправленной версии, и наложить их на другой размер без пересчёта нельзя.
Отправка локального изображения через REST
REST-запрос к images:annotate содержит массив requests. В каждом элементе image.content хранится Base64 без префикса data:image, а features включает объект с type TEXT_DETECTION или DOCUMENT_TEXT_DETECTION. Заголовок Content-Type задают как application/json, в Authorization передают Bearer-токен, а в параметре x-goog-user-project при необходимости указывают квотный проект.
Кодировать файл следует без переносов строки. Некоторые утилиты Base64 добавляют завершающий перевод или разбивают вывод на строки; JSON формально может остаться валидным, но лишние символы приводят к ошибке декодирования. При отладке не печатайте полное содержимое изображения в журнал: лог станет огромным и может сохранить конфиденциальный документ.
Один синхронный images:annotate принимает до 16 изображений. Пакет должен оставаться в пределах размера JSON, поэтому для крупных файлов или высокой нагрузки выгоднее Cloud Storage и асинхронный режим. Ответ каждого элемента массива соответствует запросу по позиции; сохраняйте свой correlation ID рядом с порядковым номером, чтобы не спутать результаты после повторов.
Работа с изображениями в Cloud Storage
Вместо image.content можно указать image.source.imageUri со значением gs://bucket/path/file.jpg. Принципал, от имени которого выполняется вызов, должен иметь право чтения объекта. Публичный HTTPS-адрес технически может использоваться для удалённого изображения, но документация предупреждает, что внешний сервер способен ограничить запрос или отказать сервису; для производственной цепочки надёжнее Cloud Storage.

Имена объектов чувствительны к регистру и могут содержать пробелы, однако в автоматизации лучше использовать предсказуемый префикс без специальных символов. Метаданные объекта удобно дополнять идентификатором задания, типом документа и контрольной суммой. Это помогает не распознавать один и тот же файл повторно и связать JSON с исходником.
Для входного бакета настройте срок хранения и правила доступа отдельно от выходного. Если исходники содержат персональные данные, не делайте объект публичным ради упрощения теста. Подпись временной ссылки также не отменяет необходимость удалить её из журналов и сообщений об ошибке.
PDF и TIFF: асинхронное распознавание
Многостраничные PDF и TIFF передаются методом files:asyncBatchAnnotate. В inputConfig задаются gcsSource.uri и mimeType application/pdf либо image/tiff. В features выбирают DOCUMENT_TEXT_DETECTION или TEXT_DETECTION, а outputConfig содержит gcsDestination.uri и batchSize — число страниц, объединяемых в один выходной JSON-файл.
Операция возвращается сразу как long-running operation. Нужно опрашивать её состояние с разумным интервалом или использовать библиотечный future, а не повторно отправлять тот же документ при отсутствии мгновенного ответа. После завершения файлы появляются в указанном префиксе Cloud Storage. Имя обычно отражает диапазон страниц, поэтому приложение должно перечислить объекты по префиксу и собрать их в правильном порядке.
Один асинхронный файловый запрос поддерживает до 2000 страниц, а PDF может достигать 1 ГБ. При больших архивах разбивайте работу на управляемые задания и сохраняйте статус каждого документа. Если один файл повреждён, очередь не должна блокировать остальные; его лучше перевести в отдельное состояние ошибки с диагностикой.
Синхронная обработка небольших файлов
Метод files:annotate позволяет синхронно обработать небольшой PDF, TIFF или GIF и выбрать до пяти страниц. Если pages не указаны, для квоты учитывается пять страниц на файл, хотя оплачиваются реально обработанные страницы. Этот режим удобен для короткого документа в интерактивном приложении, где пользователь ждёт ответ, но не подходит для сотен страниц.
Номера страниц задаются явно, когда нужно распознать титульный лист, страницу подписи или случайную выборку для проверки качества. Не путайте нумерацию в пользовательском интерфейсе с индексами API: сверяйтесь с примером конкретной библиотеки. После ответа сопоставляйте context.pageNumber и исходную страницу, особенно если порядок списка pages был нестандартным.
Если синхронный запрос регулярно выходит за тайм-аут клиентского прокси, переходите на асинхронный метод, а не увеличивайте ожидание бесконечно. Долговременная операция отделяет обработку от HTTP-соединения и лучше переживает большие документы.
Структура ответа textAnnotations
В ответе TEXT_DETECTION массив textAnnotations начинается с агрегированной аннотации. Её description содержит все распознанные строки с переводами, locale может указывать язык, а boundingPoly охватывает общий текстовый регион. Следующие элементы обычно соответствуют отдельным словам или коротким фрагментам и содержат собственные четырёхугольники.
Координата с нулевым значением может быть опущена в JSON. Поэтому вершина {} не означает отсутствие точки: для x и y нужно подставлять ноль. Код, требующий обязательные поля, упадёт на рамке, касающейся верхней или левой границы изображения. Нормализуйте каждую вершину в объект с двумя числовыми значениями до дальнейшей геометрии.
Для поиска по тексту агрегированная строка удобна, но для подсветки совпадений придётся сопоставить слова. Приводите строку к единому регистру только для поиска, сохраняя оригинальное написание. При объединении соседних слов учитывайте пунктуацию и переносы, иначе найденная фраза не совпадёт с визуальным порядком.
Структура fullTextAnnotation
fullTextAnnotation.text — быстрый способ получить связный результат, но подробная иерархия нужна для восстановления макета. Каждая page содержит width и height, blocks — boundingBox и blockType, paragraphs — набор words, words — symbols. detectedLanguages могут появляться на разных уровнях и содержат код языка с confidence.
При обходе дерева сохраняйте путь page/block/paragraph/word/symbol. Он полезен для отладки: вместо сообщения ошибка в слове можно указать конкретный блок и координаты. Для хранения в базе часто достаточно таблицы слов с page, text, confidence и вершинами, а полный JSON можно оставить в объектном хранилище как первичный результат.
Порядок элементов обычно соответствует чтению, но сложные колонки, боковые подписи и таблицы требуют проверки. Не сортируйте все слова только по y, затем по x: строки с разной высотой и наклоном перемешаются. Используйте абзацы и блоки, а геометрическую сортировку применяйте внутри ограниченной области.
Координаты, рамки и масштабирование
Для обычных изображений часто возвращаются vertices в пикселях. Для PDF и TIFF в файловом режиме документация указывает normalizedVertices от 0 до 1. Чтобы получить пиксельные координаты, умножьте x на ширину страницы, y — на высоту визуализированного изображения. Если PDF рендерится с другим DPI, масштабируйте относительно фактического размера страницы в пикселях.
Четыре вершины образуют многоугольник, а не обязательно осевой прямоугольник. Для вращённого текста вычислите угол верхней грани и поворачивайте подпись при наложении. При создании поискового слоя PDF учитывайте систему координат: в изображении начало обычно сверху слева, а в PDF — снизу слева. Значение y приходится преобразовывать относительно высоты страницы.
Перед визуализацией проверяйте границы. Округление нормализованных координат может дать ширину страницы вместо последнего допустимого пикселя; ограничьте x диапазоном 0…width−1, y диапазоном 0…height−1. Не изменяйте исходный JSON — храните нормализованное представление отдельно.
Языки и languageHints
OCR способен распознавать несколько языков на одном изображении. По умолчанию лучше оставить languageHints пустым и дать модели определить письменность. Подсказка полезна, когда язык точно известен и автоматическое определение путает близкие алфавиты. Неверный hint может заметно ухудшить результат, поэтому не подставляйте язык интерфейса пользователя вместо языка документа.
Коды задаются в формате BCP-47: например, разновидности китайского различаются как zh-Hans и zh-Hant. В списках поддержки есть полностью поддерживаемые, экспериментальные и сопоставленные языки. Для сопоставленного кода модель может использовать общий распознаватель, поэтому идентификация похожих языков менее надёжна.
При смешанном русском и английском тексте полезно сохранять detectedLanguages на уровне слова. Это помогает выбрать словарь для постобработки, но confidence языка не следует принимать за вероятность правильности самого слова. Номера, артикулы и адреса электронной почты часто не имеют осмысленного языка.
Рукописный текст
Рукопись обрабатывается через DOCUMENT_TEXT_DETECTION. Лучшие результаты дают ровные строки, достаточный контраст и отсутствие пересечений с печатными линиями бланка. Слитный почерк, исправления, зачёркивания и подписи остаются трудными случаями. Подпись человека не следует превращать в достоверное имя без дополнительной проверки.
Для анкет удобна двухступенчатая схема: сначала известная разметка формы задаёт области интереса, затем каждая область распознаётся и проверяется правилами поля. Дата должна соответствовать допустимому диапазону, индекс — длине, сумма — числовому формату. Правила не улучшают OCR, но позволяют обнаружить сомнительный ответ до записи в систему.
Не увеличивайте рукопись простым растяжением низкого качества. Интерполяция не создаёт потерянные штрихи и иногда делает контуры размытыми. Лучше переснять страницу, устранить тень от сгиба и сохранить цвет, если чернила отличаются от линий бланка.
Выбор модели OCR
В объекте Feature можно указать model. builtin/latest предназначен для использования обновлённой модели, а builtin/stable — для более предсказуемого поведения, когда он доступен для конкретной функции. Демонстрационное окно использует builtin/latest. Перед массовым переходом сравните результаты на собственном наборе: обновление способно изменить confidence и разбивку текста даже при улучшении общей точности.
Контрольный набор должен включать не только чистые страницы, но и реальные проблемы: слабый контраст, печати, наклон, смешанные языки, мелкие сноски и таблицы. Сравнивайте посимвольную ошибку, долю правильно найденных слов, полноту и геометрию. Одного красивого примера недостаточно для решения о смене модели.
Храните имя модели вместе с результатом и датой запроса. Тогда изменение качества можно связать с конфигурацией, а повторная обработка не смешает ответы разных режимов. Не вставляйте номер модели в имя конечного документа, если пользователю эта техническая деталь не нужна.
Пакетная обработка изображений
Асинхронный images:asyncBatchAnnotate принимает до 2000 изображений и записывает результаты в Cloud Storage. Это подходит для фотографий, которые уже находятся в бакете, и для задач, где не требуется мгновенный ответ. В одном задании можно запросить несколько функций Vision, но каждая функция на изображении учитывается как отдельная оплачиваемая единица.
Оркестратор должен ограничивать число одновременно создаваемых операций, хранить operation name и повторять только безопасные шаги. Если ответ на создание операции потерялся, повторная отправка может породить дубль. Используйте собственный идентификатор задания и проверку выходного префикса, чтобы понять, была ли работа уже выполнена.
После завершения валидируйте количество входов и ответов. Пустой текст не всегда является ошибкой: изображение может действительно не содержать читаемых символов. Но отсутствие элемента responses, поле error или несоответствие числа результатов требуют отдельного статуса.
Управление выходными JSON-файлами
Параметр batchSize определяет, сколько страниц попадёт в один выходной объект. Малое значение создаёт много файлов и упрощает повторную обработку отдельных диапазонов; большое уменьшает число операций Cloud Storage, но делает объект тяжелее. Выберите размер по ограничению памяти потребителя и типичному документу, а не по максимальному значению.
Выходной префикс должен быть уникален для задания. Если несколько операций пишут в одну папку, файлы с похожими именами трудно сопоставить, а повторный запуск может оставить старые результаты. Хорошая схема содержит дату, идентификатор документа и идентификатор попытки. После успешной загрузки в базу можно применить правило жизненного цикла и удалить промежуточный JSON.
Не полагайтесь на порядок выдачи списка объектов. Извлеките диапазон страниц из имени или прочитайте context, затем отсортируйте. Перед объединением проверьте, что диапазоны не перекрываются и не имеют пробелов.
Региональные конечные точки
Для OCR доступны много-региональные конечные точки us-vision.googleapis.com и eu-vision.googleapis.com. Они позволяют направить хранение и машинную обработку OCR-данных в США или Европейский союз. Регион задаётся не только полем в запросе: клиент должен обращаться к соответствующему endpoint напрямую.
В Python api_endpoint передают в client_options, в Node.js — apiEndpoint, в Java — setEndpoint. Если путь ресурса содержит location, он должен соответствовать конечной точке. Не отправляйте запрос с location=eu на глобальный endpoint в надежде на автоматическую переадресацию.
Региональная настройка не переносит входной объект автоматически. Размещайте бакет и связанные ресурсы в согласованной географии, учитывайте требования организации и проверяйте, какие метаданные остаются глобальными. Решение о регионе фиксируйте в архитектуре до массовой загрузки архива.
Квоты и масштабирование
По умолчанию общая квота составляет 1800 запросов в минуту, а квота Text detection — 1800 изображений или страниц в минуту. Для асинхронной аннотации изображений одновременно обрабатывается до 8000 изображений, для асинхронного DOCUMENT_TEXT_DETECTION — до 10000 страниц. Значения относятся к проекту и могут меняться после одобренной корректировки.
Синхронный images:annotate принимает до 16 изображений, асинхронный images:asyncBatchAnnotate — до 2000. files:annotate обрабатывает до пяти страниц, files:asyncBatchAnnotate — до 2000 страниц. Увеличение размера пакета сокращает число HTTP-запросов, но не отменяет feature quota: она считает каждую страницу.
При 429 RESOURCE_EXHAUSTED используйте экспоненциальную задержку со случайным разбросом и ограничением числа повторов. Немедленный параллельный повтор всех неудачных запросов создаёт новую волну превышения. Очередь должна учитывать квоту проекта, а не только число потоков на одном сервере.
Панель метрик и поиск узких мест
В разделе APIs & Services графики показывают трафик, ошибки и медианную задержку. Сопоставляйте всплеск ошибок с развёртыванием приложения, изменением прав или ростом размера файлов. Доля 100% при одном запросе означает единичную ошибку, а не отказ всей службы, поэтому всегда смотрите абсолютное число вызовов.

Разделяйте клиентскую и серверную задержку. Время от загрузки PDF до появления текста включает передачу в Cloud Storage, ожидание очереди, OCR, чтение выходных JSON и собственную постобработку. Метрика API отражает только часть цепочки. Добавьте временные метки на каждом этапе.
Для асинхронных операций полезны две метрики: время до завершения и возраст самого старого задания. Среднее может выглядеть нормально, пока небольшая доля документов застряла из-за прав или повреждения. Отдельный счётчик ошибок по коду быстрее выявит повторяющийся сбой.
Журналы и трассировка
В журнал не следует писать исходное изображение, Base64, access token или полный распознанный текст конфиденциального документа. Достаточно operation name, идентификатора объекта, размера, функции, времени и кода результата. Для отладки можно сохранить обезличенный фрагмент или хэш, если это допускает политика.

Cloud Run и другие вычислительные сервисы показывают строки приложения рядом с системными событиями. Добавляйте структурированные поля severity, document_id, attempt и latency_ms, чтобы фильтровать записи. Сообщение Calling the Vision API без идентификатора бесполезно, когда параллельно идут сотни документов.
При ошибке сохраняйте безопасную копию error.code, error.message и details. Ответ 5xx допускает повтор с задержкой; 400 обычно требует исправить запрос или файл; 403 — права и включение службы; 429 — регулирование скорости. Такой разбор предотвращает бесконечные повторы неустранимой ошибки.
Стоимость и контроль расходов
Оплата считается по изображениям или страницам и по каждой запрошенной функции. Для многостраничного PDF каждая страница является отдельной единицей. Первые 1000 единиц Text Detection или Document Text Detection в месяц предоставляются без платы, далее применяется тариф соответствующего диапазона. Cloud Storage, сетевой трафик и вычисления приложения оплачиваются отдельно.
Не отправляйте OCR вместе с Label Detection, Safe Search и другими функциями на всякий случай: каждая дополнительная функция создаёт отдельную единицу. На этапе приёма файла определите, какие данные действительно нужны. Повторное распознавание из-за ошибки собственного парсера тоже увеличивает расход, поэтому храните исходный JSON и повторяйте только постобработку.
Для проекта настройте бюджет и уведомления, а в базе храните число страниц и тип вызова. Стоимость удобнее прогнозировать по страницам, а не по размеру файла: тонкий PDF из двух страниц может быть тяжелее скана на сто страниц, но OCR тарифицируется иначе.
Безопасность входных документов
Документы часто содержат персональные данные, договоры, счета и удостоверения. Ограничьте доступ к бакетам сервисным периметром и IAM, включите аудит, задайте срок хранения и удаляйте временные копии. Название объекта не должно раскрывать паспортный номер или диагноз: используйте непрямой идентификатор.
Google указывает, что содержимое используется для предоставления Vision API и не публикуется и не передаётся третьим сторонам. Метаданные запросов могут временно журналироваться для улучшения службы и борьбы со злоупотреблениями. Эти условия не заменяют внутреннюю оценку риска и правовое основание обработки.
Синхронные методы не сохраняют данные на диск в рамках работы службы, асинхронные временно используют дисковое хранение; документация описывает их как автоматически совместимые с CMEK. При этом ваши собственные бакеты и базы требуют отдельной настройки шифрования и ключей.
Интеграция с очередью и Cloud Run
Надёжная цепочка отделяет приём файла от OCR. После загрузки объект генерирует событие, обработчик проверяет формат и размер, создаёт задание, а воркер вызывает Vision API. Результат записывается в базу и публикуется как отдельное событие. Пользовательский запрос не должен держать соединение до завершения многостраничного PDF.
События доставки могут повторяться. Обработчик обязан быть идемпотентным: перед запуском проверять, есть ли успешный результат для пары object generation и конфигурации OCR. Простая проверка имени файла недостаточна, потому что объект может быть перезаписан новой версией.
В Cloud Run задайте ограничение параллелизма с учётом памяти и квот. Один процесс может безопасно переиспользовать клиент ImageAnnotatorClient; создание нового клиента на каждое слово или страницу расходует соединения. При остановке контейнера корректно завершайте загрузку результата либо оставляйте задание в состоянии, которое допускает повтор.
Загрузка файлов через Cloud Shell
Cloud Shell удобен для первого теста: в меню терминала есть Upload File, после чего изображение появляется в домашнем каталоге. Команды gcloud используют активный проект и учётную запись. Перед вызовом проверьте gcloud config get-value project и gcloud auth list, чтобы тест не ушёл в случайный проект.

Загруженный в Cloud Shell документ находится на виртуальной машине, а не в Cloud Storage. Для PDF/TIFF его нужно скопировать в бакет командой gcloud storage cp или через консоль. После теста удалите конфиденциальный файл из домашнего каталога и бакета.
Извлечение текста из архивных PDF
Для архива сначала разделите цифровые PDF с текстовым слоем и сканы. Если текст уже извлекается библиотекой PDF, повторный OCR ухудшит качество и создаст расходы. Сканированные страницы направляйте в Vision, а цифровой текст сохраняйте напрямую. Смешанный документ можно анализировать постранично.
После OCR полезно хранить три представления: исходный PDF, неизменённый JSON Vision и нормализованный текст. Исходник нужен для визуальной проверки, JSON — для повторной разметки без нового запроса, текст — для поиска. Версия нормализатора должна быть записана рядом, чтобы при улучшении правил пересобрать индекс.
Для поиска удаляйте служебные переносы и нормализуйте пробелы, но не уничтожайте исходную строку. Суммы, даты и артикулы чувствительны к пунктуации. Поиск может использовать отдельное поле без пунктуации, а отображение — точный OCR-результат.
Создание PDF с поисковым слоем
Vision API не возвращает готовый PDF с невидимым текстом. Чтобы сделать скан доступным для поиска, отрендерите каждую страницу в том же размере, преобразуйте координаты слов в систему PDF и добавьте текстовый слой библиотекой создания PDF. Исходное изображение остаётся видимым фоном.
Шрифт текстового слоя должен поддерживать распознанные символы. Размер подбирается по высоте рамки, а горизонтальное масштабирование — по ширине слова. Даже при точном OCR метрика шрифта может отличаться, поэтому слой обычно делают невидимым, но проверяют копирование и поиск.
Не накладывайте агрегированную fullTextAnnotation.text одним большим блоком: порядок может быть правильным, но выделение текста не совпадёт с изображением. Используйте слова или строки и сохраняйте поворот. Для PDF с несколькими колонками проверьте, что порядок чтения соответствует ожиданиям пользователя.
Таблицы, формы и поля
Cloud Vision OCR возвращает текст и геометрию, но не обещает таблицу с рядами и столбцами, пары ключ — значение или готовые поля счёта. Линии сетки могут появиться как границы блоков лишь косвенно. Для простой фиксированной формы можно сопоставлять слова с заранее известными прямоугольниками.
Изменяемые счета и анкеты требуют анализа макета. Один подход группирует слова в строки по вертикальному пересечению, затем ищет колонки по x. Другой применяет Document AI, который предлагает специализированные процессоры и структурированный вывод. Выбор зависит от стабильности шаблона и ценности ошибок.
При извлечении суммы не берите ближайшее число без проверки. У слова Итого могут быть рядом налог, скидка и итоговая сумма. Используйте направление, расстояние, формат валюты и согласованность арифметики. Низкий confidence или несколько кандидатов должны отправлять документ на ручную проверку.
Контроль качества распознавания
Создайте размеченный набор страниц, отражающий реальный поток. Для обычного текста рассчитывают Character Error Rate и Word Error Rate. Для полей важнее доля полностью правильных значений: одна ошибка в номере договора делает весь номер непригодным. Для координат измеряют пересечение рамок и полноту обнаружения.
Разделяйте ошибки детектора и распознавателя. Если слово отсутствует, проблема в обнаружении области или качестве изображения. Если рамка есть, но символы неверны, анализируйте язык, шрифт и контраст. Эти классы требуют разных улучшений.
Ручная проверка должна показывать исходную область рядом с распознанным значением и confidence, а не весь документ без подсветки. Исправления сохраняйте как обучающий и контрольный материал, соблюдая требования к персональным данным.
Типовые ошибки запросов
INVALID_ARGUMENT обычно указывает на неверный JSON, неподдерживаемый feature type, неправильный MIME или страницу вне диапазона. Проверьте, что inputConfig используется для файла, а image — для изображения. Для PDF укажите application/pdf, для TIFF — image/tiff.
UNAUTHENTICATED означает, что токен отсутствует, истёк или предназначен не для этого вызова. PERMISSION_DENIED связан с IAM, выключенным API, квотным проектом или доступом к бакету. NOT_FOUND часто появляется из-за ошибочного gs://-пути, регистра имени или удалённого объекта.
RESOURCE_EXHAUSTED требует снижения скорости или увеличения квоты. DEADLINE_EXCEEDED в синхронном запросе не доказывает, что сервер ничего не сделал; перед повтором учитывайте идемпотентность. INTERNAL и UNAVAILABLE повторяют с экспоненциальной задержкой, но после ограниченного числа попыток переводят задание в очередь разборов.
Ошибки формата и размера
Файл свыше 20 МБ нельзя вложить как обычное изображение, а JSON ограничен 10 МБ. Решение — загрузить объект в Cloud Storage и передать URI. Простое увеличение HTTP-лимита собственного сервера не меняет лимит Vision. Для PDF действует отдельный предел 1 ГБ и ограничение страниц.
Анимированный GIF обрабатывается по-разному в зависимости от метода: общий список форматов указывает первый кадр для изображения, а файловые методы позволяют выбрать кадры как страницы в малом пакете. Если нужна каждая анимационная сцена, извлеките кадры самостоятельно и сохраните связь с временной меткой.
Повреждённый JPEG иногда открывается просмотрщиком за счёт терпимого декодера, но API его отклоняет. Пересохраните в стандартный JPEG или PNG, не меняя расширение вручную. Сохраняйте хэш до и после преобразования, чтобы понимать, какой вариант был распознан.
Низкая точность и способы улучшения
При пропущенных строках сначала проверьте размер символов и резкость. Если кадр снят под углом, исправьте перспективу. Для бледной страницы попробуйте локальный контраст. Для смешанных алфавитов сравните автоматическое определение и точный languageHint. Каждое изменение тестируйте на наборе, а не на одной странице.
Если текст расположен вертикально или по дуге, стандартный порядок чтения может быть неудобен. Используйте координаты, группируйте слова по углу и области. Для декоративных шрифтов и логотипов OCR не гарантирует точность; иногда надёжнее словарь допустимых брендов и проверка по изображению.
Печати и фоновые узоры закрывают символы. Цветовое разделение может помочь, если печать и текст различаются по оттенку, но удаление печати способно стереть подпись. Храните исходник и показывайте оператору обе версии.
Производительность и задержка
Не отправляйте исходные фотографии огромного размера, если текст занимает небольшую часть. Обрезка уменьшает трафик и время декодирования. Но слишком сильное уменьшение портит мелкие символы. Оптимальный размер выбирают по тестам для конкретной камеры и документа.
Переиспользуйте клиент и сетевые соединения, группируйте до 16 небольших изображений в синхронный запрос, а большие очереди направляйте в асинхронный режим. Разделяйте приоритеты: интерактивная фотография должна пройти раньше архивной пачки.
Кэшируйте результат по криптографическому хэшу содержимого и конфигурации OCR. Один и тот же файл с другим именем не нужно распознавать повторно. Однако изменение languageHints, model или режима TEXT/DOCUMENT создаёт другой ключ кэша.
Практический сценарий: серийные номера и маркировка
Для серийного номера сначала ограничьте область кадра, затем используйте TEXT_DETECTION. Нормализуйте пробелы и дефисы только после сохранения оригинала. Регулярное выражение должно проверять длину и допустимые символы, но не молча заменять O на 0: такая замена может изменить настоящий код.
Если номер наносится точечно-матричным шрифтом, подготовьте примеры с разной экспозицией и загрязнением. Confidence отдельного слова помогает сортировать кандидатов, но финальное правило должно учитывать контрольную цифру или справочник устройств.
При массовой съёмке добавьте визуальную рамку в мобильном приложении, предупреждение о блике и автоматический контроль резкости. Vision получает уже подготовленный кадр; качество интерфейса съёмки влияет на результат не меньше модели.
Практический сценарий: перевод текста с фотографии
OCR возвращает исходный UTF-8-текст, который можно передать Cloud Translation API. Сохраняйте связь перевода с рамками, если хотите показать подписи поверх изображения. Перевод отдельных слов без контекста хуже, поэтому объединяйте их в строку или абзац, но не смешивайте разные колонки.
Определённый OCR-язык и язык перевода — разные сущности. Пользователь может запросить перевод на русский, хотя исходник содержит английский и французский. Передавайте исходный язык автоматически, если уверенность достаточна, либо разрешите Translation определить его.
Числа, артикулы и адреса не должны переводиться. Сегментация по типу текста предотвращает замену кодов. При наложении перевода учитывайте, что длина строки меняется и может не помещаться в исходную рамку.
Практический сценарий: поиск по корпоративному архиву
После распознавания создайте индекс с идентификатором документа, номером страницы, текстом и координатами. Поиск возвращает страницу и прямоугольник совпадения, а интерфейс открывает исходный PDF на нужном месте. Это полезнее выдачи длинного OCR-текста без контекста.
Нормализованный индекс может хранить варианты ё/е, дефисы и распространённые OCR-подмены, но оригинал показывают без исправления. Для доступа к результатам применяются те же права, что к документу: OCR не должен делать закрытый файл доступным через общий поисковый индекс.
При удалении исходника удаляйте связанные страницы, JSON и индекс. Иначе поиск сохранит текст документа после окончания срока хранения. Связь по неизменяемому document_id упрощает такую очистку.
Сравнение Google Cloud Vision OCR с аналогами
Решения различаются не только точностью, но и формой результата. Cloud Vision удобен, когда приложению нужны текст, рамки и масштабирование через API. Редактор PDF лучше подходит человеку, которому требуется сразу исправить страницу. Сервисы обработки документов добавляют таблицы и поля, но требуют более сложной настройки и проверки схемы.
| Программа | Лучше подходит для | Главное ограничение |
|---|---|---|
| Google Cloud Vision OCR | OCR изображений и PDF в облачных процессах | Не создаёт готовый PDF или таблицу |
| PDF Commander | Распознавание и правка PDF пользователем | Не рассчитан на облачные API-потоки |
| Google Document AI | Формы, таблицы и сущности документов | Сложнее и избыточнее для простых фото |
| Amazon Textract | Текст, рукопись, формы и таблицы в AWS | Результат требует интеграции в AWS-процесс |
| Azure AI Vision Read | OCR изображений и многостраничных файлов | Нужен ресурс Azure и асинхронная обработка |
| Tesseract OCR | Локальная автоматизация без облачной платы | Не читает PDF напрямую и не имеет GUI |
Как выбрать подходящее решение
Google Cloud Vision OCR выбирают для приложений, которые уже используют Google Cloud, обрабатывают изображения и нуждаются в координатах слов. Google Document AI разумнее для счетов, форм и договоров, когда важна структура. Amazon Textract логичен внутри инфраструктуры AWS, Azure AI Vision Read — в экосистеме Microsoft. Tesseract подходит для локальных конвейеров, если команда готова самостоятельно готовить изображения и поддерживать языковые модели.
PDF Commander удобнее для разовой работы человека: открыть скан, распознать текст, проверить страницу и продолжить редактирование PDF без разработки API-интеграции. Он решает соседний пользовательский сценарий, но не заменяет облачный обработчик тысяч изображений.
Чек-лист перед запуском в рабочей среде
До обработки реальных документов проверьте проект, биллинг, API, IAM, регион, бакеты и бюджет. Убедитесь, что приложение использует ADC, секреты не попадают в журнал, а выходной префикс уникален. Зафиксируйте функцию OCR, модель, языковые подсказки и правила подготовки изображения.
Создайте контрольный набор и пороги качества. Опишите, какие ошибки допускают автоматический результат, а какие отправляют страницу человеку. Проверьте повторную доставку событий, поведение при 429 и 5xx, удаление временных файлов и восстановление после частично завершённой операции.
После запуска отслеживайте страницы в минуту, стоимость на документ, долю пустых ответов, низкий confidence и время старейшего задания. Эти показатели быстрее обнаружат ухудшение входных сканов или ошибку интеграции, чем общий график количества запросов.
Ответы на практические вопросы
Можно ли отправить PDF прямо в демонстрационную форму? Нет. Демонстрация принимает поддерживаемые изображения до 20 МБ, а PDF и TIFF обрабатываются файловыми методами через Cloud Storage либо синхронным малым пакетом API.
Можно ли получить DOCX или XLSX одним вызовом? Нет. Ответ содержит JSON с текстом, рамками и структурой. Экспорт в офисный формат выполняет приложение пользователя. Для таблиц и полей лучше использовать специализированный процессор или собственный разбор.
Нужно ли всегда задавать русский язык? Нет. Автоматическое определение обычно предпочтительнее. languageHints добавляют только при известном языке и подтверждённом улучшении на контрольных страницах.
Почему координаты иногда пустые? Нулевые x или y могут быть опущены из JSON. Пустой объект вершины следует интерпретировать как координату 0, а не как отсутствие рамки.
Как не платить за повторный разбор? Сохраняйте исходный JSON, хэш файла и конфигурацию. Если меняются только правила выделения полей, повторно обрабатывайте сохранённый ответ без нового OCR-вызова.
Расширенная диагностика производственного конвейера
Если ошибка проявляется только на части файлов, сформируйте таблицу с MIME-типом, размером, числом страниц, способом загрузки, режимом OCR, endpoint и кодом ответа. Сортировка по этим признакам часто показывает общий фактор: документы из одного сканера, PDF с определённым генератором, изображения после конкретного фильтра или задания, отправленные одной сервисной учётной записью. Не объединяйте все неудачи в категорию OCR ошибся, пока не исключены транспорт, декодирование и доступ к объекту.
При расхождении между демонстрацией и API проверьте функцию и модель. Демонстрация использует DOCUMENT_TEXT_DETECTION и builtin/latest, тогда как код может отправлять TEXT_DETECTION без model. Сравнивать два разных режима по одному изображению некорректно. Сохраните тела запросов, исключив токены и Base64, и сопоставьте feature.type, languageHints, model и фактический файл по SHA-256.
Если операция PDF завершилась успешно, но выходной префикс пуст, проверьте права записи сервисного субъекта и точность gcsDestination.uri. Префикс должен заканчиваться допустимым путём внутри бакета. Затем изучите error в самой операции: HTTP-ответ на создание задания не гарантирует успешное чтение каждой страницы. Не создавайте новый бакет с публичным доступом как способ диагностики; временно выдайте минимальную роль на тестовый префикс.
Если JSON-файлы существуют, но приложение не видит часть страниц, проверьте перечисление объектов и пагинацию Cloud Storage. Список может возвращаться несколькими страницами, а имена объектов — в лексикографическом порядке. Диапазон 100–199 способен оказаться до 20–29 при наивной сортировке строк. Извлекайте числовые границы и проверяйте непрерывность.
Если потребление памяти растёт на больших документах, не загружайте все выходные JSON в один объект. Обрабатывайте файл за файлом и страницу за страницей, записывайте нормализованные слова потоково, после чего освобождайте дерево. fullTextAnnotation с символами и координатами значительно объёмнее простого текста.
Если запросы проходят из Cloud Shell, но не проходят из Cloud Run, сравните principal. Cloud Shell действует от имени пользователя, контейнер — от имени назначенной сервисной учётной записи. Проверьте service account ресурса, роли на проекте и бакете, а также переменную проекта. Копирование пользовательского JSON-ключа в контейнер скрывает проблему прав и создаёт риск утечки.
Если ошибка возникает после переноса на endpoint EU или US, убедитесь, что библиотека действительно получила api_endpoint. Некоторые обёртки создают клиент раньше чтения конфигурации и продолжают использовать глобальный адрес. Запишите имя endpoint при старте процесса и добавьте интеграционный тест, который проверяет региональную конфигурацию без содержимого реального документа.
Если стоимость выше расчёта, сгруппируйте usage по функции. Один запрос с OCR, labels и safe search создаёт несколько оплачиваемых единиц на страницу. Проверьте повторные попытки, дубли событий и тестовые проекты. Сравните количество уникальных хэшей файлов с числом OCR-единиц; большой разрыв указывает на повторы или несколько функций.
Если текст выглядит правильно, но поиск не находит слова, проблема может быть в нормализации. OCR способен вернуть неразрывный пробел, перенос с дефисом, похожий символ другого алфавита или комбинируемый диакритический знак. Храните исходный Unicode, а для индекса применяйте нормализацию NFC, унификацию пробелов и контролируемый список замен. Не меняйте оригинал, иначе оператор не увидит источник расхождения.
Если рамки смещены на PDF, проверьте, из какого изображения получены width и height. Нормализованные координаты относятся к странице ответа, а визуализатор мог рендерить PDF с отступом, поворотом или другим DPI. Сначала преобразуйте координаты в пространство чистой страницы, затем применяйте масштаб и смещение viewport. Отдельно обрабатывайте CropBox и MediaBox, если библиотека PDF их различает.
Если строки перемешаны в двухколоночном документе, не полагайтесь на одну агрегированную строку. Группируйте blocks по горизонтальным областям, определяйте колонки по распределению x и сортируйте внутри каждой колонки. Заголовок, охватывающий всю ширину, нужно вынести перед колонками. Проверяйте чтение на разворотах, где две страницы попали в один скан.
Если confidence высокий, но поле неверно, помните, что confidence не является бизнес-валидацией. Модель может уверенно распознать похожий символ. Для критичных полей применяйте контрольную сумму, справочник, диапазон даты, математическую сверку сумм и повторное подтверждение оператором. Порог confidence без правила поля создаёт ложное чувство надёжности.
Если пользователь загружает фотографию с EXIF-поворотом, приведите изображение к фактической ориентации до отправки и удалите двусмысленный тег. Координаты должны соответствовать пикселям, которые показывает интерфейс. Храните матрицу преобразования, если исходник отображается без физического поворота пикселей.
Если в ответе нет текста, проверьте не только качество, но и выбранную страницу. В files:annotate список pages может исключить нужную страницу, а повреждённый многостраничный TIFF — открываться только частично. Сохраните миниатюру фактически отправленной страницы в защищённом диагностическом хранилище и удаляйте её по короткому сроку.
Если очередь растёт при неизменном трафике, измерьте время ожидания до OCR отдельно от времени самого вызова. Причиной может быть низкое число воркеров, блокировка на загрузке в Cloud Storage, квота in processing или медленная постобработка. Увеличивать параллелизм нужно после определения узкого места, иначе очередь переместится к следующему этапу.
Если требуется повторная обработка после изменения модели, создайте новую версию результата, а не перезаписывайте старую. Сравнение двух версий позволит обнаружить регрессии, а аудит сохранит, какой текст использовался в бизнес-решении. Статус активной версии можно переключить после приёмки контрольного набора.
Проверка OCR на разных типах документов
Для многоколоночных газет и журналов сначала определите области чтения по координатам блоков. Простая склейка всех слов сверху вниз часто соединяет заголовок первой колонки со строкой второй. Проверьте, не пересекают ли блоки центральный разделитель, вынесите общий заголовок перед колонками и сохраняйте номер области в нормализованном результате. Такой порядок легче проверить визуально и повторить после изменения алгоритма.
Термочеки требуют отдельного контрольного набора: выцветший текст, блики, длинная узкая страница и мелкие суммы дают другой профиль ошибок, чем офисный документ. Перед OCR полезно выровнять перспективу и контраст, но исходную фотографию следует сохранить. Даты, итог и налоговые суммы проверяйте регулярными выражениями и арифметикой, а позиции товара не объединяйте только по близости по вертикали — длинное название может переноситься на следующую строку.
На снимках экранов и интерфейсов OCR обычно видит подписи кнопок, меню и сообщения об ошибках, однако иконки и декоративные элементы могут разрывать строку. Для базы поддержки сохраняйте прямоугольник каждого фрагмента и контекст окна, чтобы найденный текст можно было показать пользователю на исходном кадре. Мелкий серый текст лучше проверять на исходном масштабе: увеличение после сильного JPEG-сжатия не возвращает утраченные контуры.
Этикетки на банках, бутылках и упаковке дают криволинейную перспективу, блики и несколько направлений письма. Не рассчитывайте, что один поворот исправит всю поверхность. Делайте несколько кадров с перекрытием, удаляйте дубликаты строк по нормализованному тексту и координатам, а обязательные поля сверяйте со словарём продукта. Случайное совпадение названия не должно автоматически подтверждать номер партии или срок годности.
В смешанном PDF часть страниц может содержать цифровой текст, а часть — только скан. Перед отправкой проверьте наличие полезного текстового слоя на каждой странице. Цифровые страницы можно извлечь без OCR, сохранив точные символы, а сканированные обработать Vision. После объединения результата храните признак происхождения фрагмента: встроенный текст, OCR или ручная правка. Это упрощает поиск причины опечатки.
При двустороннем сканировании в пачку часто попадают пустые обороты. Не удаляйте страницу только потому, что OCR вернул пустую строку: на ней может быть печать, подпись или слабая пометка. Сначала примените порог заполненности изображения, затем сохраните миниатюру для выборочной проверки. Номера страниц исходного файла нельзя перенумеровывать после фильтрации, иначе координаты ответа и ссылка из бизнес-системы разойдутся.
Печати, подписи и рукописные пометки могут перекрывать печатный текст. DOCUMENT_TEXT_DETECTION вернёт распознанные слова, но не сообщит юридическое значение подписи и не гарантирует отделение штампа от строки. Для таких страниц сохраняйте изображение области, отмечайте пересечение рамок и отправляйте документ на проверку, если перекрыто критичное поле. OCR не должен превращаться в автоматическое подтверждение подлинности.
Если пачка содержит страницы с разным поворотом, нормализуйте ориентацию отдельно для каждой страницы, а не для всего PDF. После поворота запишите матрицу преобразования, чтобы рамки можно было вернуть в координаты исходника. На контрольных примерах проверьте 0, 90, 180 и 270 градусов, включая страницы с короткими заголовками: по нескольким словам направление определяется менее устойчиво, чем по плотному абзацу.
Для процесса обезличивания сначала распознавайте документ в защищённой зоне, затем ищите кандидатов на персональные данные и применяйте маски к исходным координатам. Одного поиска строки недостаточно: имя может быть разбито на слова, а номер — содержать пробелы. После маскирования повторно запустите OCR на итоговом изображении и убедитесь, что закрытый текст больше не читается. Исходник и немаскированный JSON должны иметь более строгие права и срок хранения.
При создании поискового слоя PDF не подгоняйте невидимый текст только по общей рамке абзаца. Используйте координаты слов, учитывайте поворот страницы и размер рендера, а переносы строк восстанавливайте из detectedBreak. После сборки откройте файл в нескольких просмотрщиках, выделите произвольную строку и скопируйте её. Визуальная неизменность страницы ещё не доказывает, что слой совпадает с изображением и корректно ищется.
Для таблиц без специализированного парсера сначала находите строки и колонки геометрически, затем проверяйте структуру бизнес-правилами. Пустая ячейка, многострочный заголовок и объединённые колонки легко сдвигают все последующие значения. Сохраняйте связь каждой ячейки со словами и рамками, чтобы оператор видел основание результата. Когда важны строки, колонки и типы полей, предпочтительнее сервис, который возвращает структуру таблицы непосредственно.
При приёмочном тестировании разделите документы по типам, языкам, качеству скана и источнику. Общая точность по всей выборке скрывает провал на редкой, но критичной группе. Для каждой группы измеряйте долю пустых ответов, символьные ошибки, точность ключевых полей и время обработки. Контрольный набор фиксируйте по хэшам и не меняйте между сравнениями, иначе улучшение может оказаться следствием другой выборки.
Итоговый рабочий подход
Надёжный результат получается, когда OCR является измеряемым этапом, а не единственной кнопкой. Подготовьте изображение, выберите TEXT_DETECTION или DOCUMENT_TEXT_DETECTION, используйте правильный метод для изображения либо PDF, сохраните полный JSON и только затем формируйте текст, поля, поисковый индекс или PDF-слой.
Для единичной проверки достаточно демонстрационного окна. Для приложения настройте проект, ADC, Cloud Storage, очередь, лимиты повторов и мониторинг. Для сложных таблиц и форм сразу оцените Document AI или другой структурный парсер, чтобы не строить хрупкую семантику поверх одних координат.
Завершайте процесс визуальной проверкой проблемных страниц и храните связь результата с исходником. Тогда ошибки модели остаются обнаружимыми, обновление конфигурации контролируется, а архив можно переработать без потери доказуемости.