Распознавание текста (Vision OCR)

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

Функциональность Vision OCR доступна через gRPC и REST API. Спецификация API опубликована на GitHub.

Принципы работы распознавания

При распознавании текста Vision OCR выделяет текст на изображении и группирует его по уровням: слова — в строки, строки — в блоки, блоки — в страницы.

image

В результате распознавания произвольного текста сервис возвращает объект в формате JSON Lines: каждая строка JSON-файла соответствует одной распознанной странице или изображению. Этот объект содержит следующие уровни:

Уровень Параметр Содержимое
Страница pages[] Размер страницы.
Блок текста blocks[] Расположение текста на странице и его тип (LayoutType).
Строка lines[] Расположение строк.
Слово words[] Расположение слов, текст и язык распознавания.
Изображение pictures[] Расположение изображений в документе.

Свойство LayoutType указывает тип блока:

Значение Описание
LAYOUT_TYPE_UNSPECIFIED Не установлено.
LAYOUT_TYPE_UNKNOWN Не найдено.
LAYOUT_TYPE_TEXT Текст.
LAYOUT_TYPE_HEADER Заголовок.
LAYOUT_TYPE_SECTION_HEADER Заголовок раздела.
LAYOUT_TYPE_FOOTER Нижнее примечание.
LAYOUT_TYPE_FOOTNOTE Примечание.
LAYOUT_TYPE_PICTURE Текст на изображении.
LAYOUT_TYPE_CAPTION Подпись.
LAYOUT_TYPE_TITLE Название.
LAYOUT_TYPE_LIST Список.

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

Координаты прямоугольника считаются от левого верхнего угла и указываются против часовой стрелки:

1←4
        ↓ ↑
        2→3
        
Пример распознанного изображения с координатами
{
            "result": {
                "textAnnotation": {
                    "width": "1920",
                    "height": "1280",
                    "blocks": [
                        {
                            "boundingBox": {
                                "vertices": [
                                    {
                                        "x": "460",
                                        "y": "777"
                                    },
                                    {
                                        "x": "460",
                                        "y": "906"
                                    },
                                    {
                                        "x": "810",
                                        "y": "906"
                                    },
                                    {
                                        "x": "810",
                                        "y": "777"
                                    }
                                ]
                            },
                            "lines": [
                                {
                                    "boundingBox": {
                                        "vertices": [
                                            {
                                                "x": "460",
                                                "y": "777"
                                            },
                                            {
                                                "x": "460",
                                                "y": "820"
                                            },
                                            {
                                                "x": "802",
                                                "y": "820"
                                            },
                                            {
                                                "x": "802",
                                                "y": "777"
                                            }
                                        ]
                                    },
                                    "text": "PENGUINS",
                                    "words": [
                                        {
                                            "boundingBox": {
                                                "vertices": [
                                                    {
                                                        "x": "460",
                                                        "y": "768"
                                                    },
                                                    {
                                                        "x": "460",
                                                        "y": "830"
                                                    },
                                                    {
                                                        "x": "802",
                                                        "y": "830"
                                                    },
                                                    {
                                                        "x": "802",
                                                        "y": "768"
                                                    }
                                                ]
                                            },
                                            "text": "PENGUINS",
                                            "entityIndex": "-1",
                                            "textSegments": [
                                                {
                                                    "startIndex": "0",
                                                    "length": "8"
                                                }
                                            ]
                                        }
                                    ],
                                    "textSegments": [
                                        {
                                            "startIndex": "0",
                                            "length": "8"
                                        }
                                    ],
                                    "orientation": "ANGLE_0"
                                },
                                {
                                    "boundingBox": {
                                        "vertices": [
                                            {
                                                "x": "489",
                                                "y": "861"
                                            },
                                            {
                                                "x": "489",
                                                "y": "906"
                                            },
                                            {
                                                "x": "810",
                                                "y": "906"
                                            },
                                            {
                                                "x": "810",
                                                "y": "861"
                                            }
                                        ]
                                    },
                                    "text": "CROSSING",
                                    "words": [
                                        {
                                            "boundingBox": {
                                                "vertices": [
                                                    {
                                                        "x": "489",
                                                        "y": "852"
                                                    },
                                                    {
                                                        "x": "489",
                                                        "y": "916"
                                                    },
                                                    {
                                                        "x": "810",
                                                        "y": "916"
                                                    },
                                                    {
                                                        "x": "810",
                                                        "y": "852"
                                                    }
                                                ]
                                            },
                                            "text": "CROSSING",
                                            "entityIndex": "-1",
                                            "textSegments": [
                                                {
                                                    "startIndex": "9",
                                                    "length": "8"
                                                }
                                            ]
                                        }
                                    ],
                                    "textSegments": [
                                        {
                                            "startIndex": "9",
                                            "length": "8"
                                        }
                                    ],
                                    "orientation": "ANGLE_0"
                                }
                            ],
                            "languages": [
                                {
                                    "languageCode": "en"
                                }
                            ],
                            "textSegments": [
                                {
                                    "startIndex": "0",
                                    "length": "17"
                                }
                            ],
                            "layoutType": "LAYOUT_TYPE_TEXT"
                        },
                        {
                            "boundingBox": {
                                "vertices": [
                                    {
                                        "x": "547",
                                        "y": "989"
                                    },
                                    {
                                        "x": "547",
                                        "y": "1046"
                                    },
                                    {
                                        "x": "748",
                                        "y": "1046"
                                    },
                                    {
                                        "x": "748",
                                        "y": "989"
                                    }
                                ]
                            },
                            "lines": [
                                {
                                    "boundingBox": {
                                        "vertices": [
                                            {
                                                "x": "547",
                                                "y": "989"
                                            },
                                            {
                                                "x": "547",
                                                "y": "1046"
                                            },
                                            {
                                                "x": "748",
                                                "y": "1046"
                                            },
                                            {
                                                "x": "748",
                                                "y": "989"
                                            }
                                        ]
                                    },
                                    "text": "SLOW",
                                    "words": [
                                        {
                                            "boundingBox": {
                                                "vertices": [
                                                    {
                                                        "x": "547",
                                                        "y": "983"
                                                    },
                                                    {
                                                        "x": "547",
                                                        "y": "1054"
                                                    },
                                                    {
                                                        "x": "748",
                                                        "y": "1054"
                                                    },
                                                    {
                                                        "x": "748",
                                                        "y": "983"
                                                    }
                                                ]
                                            },
                                            "text": "SLOW",
                                            "entityIndex": "-1",
                                            "textSegments": [
                                                {
                                                    "startIndex": "18",
                                                    "length": "4"
                                                }
                                            ]
                                        }
                                    ],
                                    "textSegments": [
                                        {
                                            "startIndex": "18",
                                            "length": "4"
                                        }
                                    ],
                                    "orientation": "ANGLE_0"
                                }
                            ],
                            "languages": [
                                {
                                    "languageCode": "en"
                                }
                            ],
                            "textSegments": [
                                {
                                    "startIndex": "18",
                                    "length": "4"
                                }
                            ],
                            "layoutType": "LAYOUT_TYPE_TEXT"
                        }
                    ],
                    "entities": [],
                    "tables": [],
                    "fullText": "PENGUINS\nCROSSING\nSLOW\n",
                    "rotate": "ANGLE_0",
                    "markdown": " ",
                    "pictures": []
                },
                "page": "0"
            }
        }
        

Совет

В некоторых случаях координаты в ответе могут не совпадать с отображением текста в обработчике изображений. Это происходит, если обработчик некорректно обрабатывает метаданные exif: сервис учитывает значение атрибута Orientation из секции exif, а некоторые средства просмотра его игнорируют.

Чтобы устранить несоответствие, измените настройки обработчика изображений так, чтобы при просмотре учитывался угол поворота из секции exif, или удалите из секции exif атрибут Orientation перед отправкой изображения в сервис (либо установите для него значение 0).

При распознавании шаблонных документов модель возвращает массив entities

Требования к изображениям

  • Поддерживаемые форматы файлов: JPEG, PNG, PDF. MIME-тип файла указывайте в свойстве mime_type. По умолчанию image.
  • Максимальный размер файла: 10 МБ.
  • Размер изображения не должен превышать 20 мегапикселей (длина × ширина).

Полезные ссылки