Распознавание таблицы
Чтобы распознать текст внутри таблицы, вы можете использовать OCR API с моделью распознавания table
. Эта модель позволяет распознавать таблицы на русском, английском и турецком языках.
Перед началом работы
Чтобы воспользоваться примерами, установите cURL
Получите данные вашего аккаунта для аутентификации:
-
Получите IAM-токен для аккаунта на Яндексе или федеративного аккаунта.
-
Получите идентификатор каталога, на который у вашего аккаунта есть роль
ai.vision.user
или выше. -
При обращении к Vision OCR через API в каждом запросе передавайте полученные параметры:
-
Для Vision API и Classifier API:
Указывайте IAM-токен в заголовке
Authorization
в следующем формате:Authorization: Bearer <IAM-токен>
Идентификатор каталога указывайте в теле запроса в параметре
folderId
. -
Для OCR API:
- в заголовке
Authorization
указывайте IAM-токен; - в заголовке
x-folder-id
указывайте идентификатор каталога.
Authorization: Bearer <IAM-токен> x-folder-id <идентификатор_каталога>
- в заголовке
-
Vision OCR поддерживает два способа аутентификации с сервисным аккаунтом:
-
С помощью IAM-токена:
-
Полученный IAM-токен передавайте в заголовке
Authorization
в следующем формате:Authorization: Bearer <IAM-токен>
-
С помощью API-ключей.
Используйте API-ключи, если у вас нет возможности автоматически запрашивать IAM-токен.
-
Полученный API-ключ передавайте в заголовке
Authorization
в следующем формате:Authorization: Api-Key <API-ключ>
Не указывайте в запросах идентификатор каталога — сервис использует каталог, в котором был создан сервисный аккаунт.
Распознать таблицу
Распознавание текста на изображении реализовано в методе recognize OCR API.
-
Подготовьте файл изображения, соответствующий требованиям:
- Поддерживаемые форматы файлов: JPEG, PNG, PDF. MIME-тип
файла указывайте в свойствеmime_type
. По умолчаниюimage
. - Максимальный размер файла: 10 МБ.
- Размер изображения не должен превышать 20 мегапикселей (длина × ширина).
- Поддерживаемые форматы файлов: JPEG, PNG, PDF. MIME-тип
-
Кодируйте файл с изображением в формат Base64:
UNIXWindowsPowerShellPythonNode.jsJavaGobase64 -i input.jpg > output.txt
C:> Base64.exe -e input.jpg > output.txt
[Convert]::ToBase64String([IO.File]::ReadAllBytes("./input.jpg")) > output.txt
# Импортируйте библиотеку для кодирования в Base64 import base64 # Создайте функцию, которая кодирует файл и возвращает результат. def encode_file(file_path): with open(file_path, "rb") as fid: file_content = fid.read() return base64.b64encode(file_content).decode("utf-8")
// Считайте содержимое файла в память. var fs = require('fs'); var file = fs.readFileSync('/path/to/file'); // Получите содержимое файла в формате Base64. var encoded = Buffer.from(file).toString('base64');
// Импортируйте библиотеку для кодирования в Base64. import org.apache.commons.codec.binary.Base64; // Получите содержимое файла в формате Base64. byte[] fileData = Base64.encodeBase64(yourFile.getBytes());
import ( "bufio" "encoding/base64" "io/ioutil" "os" ) // Откройте файл f, _ := os.Open("/path/to/file") // Прочитайте содержимое файла. reader := bufio.NewReader(f) content, _ := ioutil.ReadAll(reader) // Получите содержимое файла в формате Base64. base64.StdEncoding.EncodeToString(content)
-
Создайте файл с телом запроса, например
body.json
.body.json:
{ "mimeType": "JPEG", "languageCodes": ["ru","en"], "model": "table", "content": "<изображение_в_кодировке_base64>" }
В свойстве
content
укажите содержимое файла, полученное при переводе изображения в формат Base64. -
UNIXPython
export IAM_TOKEN=<IAM-токен> curl \ --request POST \ --header "Content-Type: application/json" \ --header "Authorization: Bearer ${IAM_TOKEN}" \ --header "x-folder-id: <идентификатор_каталога>" \ --header "x-data-logging-enabled: true" \ --data "@body.json" \ https://ocr.api.cloud.yandex.net/ocr/v1/recognizeText \ --output output.json
Где:
<IAM-токен>
— полученный ранее IAM-токен.<идентификатор_каталога>
— полученный ранее идентификатор каталога.
data = {"mimeType": <mime_type>, "languageCodes": ["*"], "content": content} url = "https://ocr.api.cloud.yandex.net/ocr/v1/recognizeText" headers= {"Content-Type": "application/json", "Authorization": "Bearer {:s}".format(<IAM-токен>), "x-folder-id": "<идентификатор_каталога>", "x-data-logging-enabled": "true"} w = requests.post(url=url, headers=headers, data=json.dumps(data))
Результат будет состоять из распознанных блоков текста, строк и слов с указанием их местоположения на изображении.
Результат:
{ "result": { "textAnnotation": { "width": "724", "height": "131", "blocks": [ { "boundingBox": { "vertices": [ { "x": "68", "y": "42" }, { "x": "68", "y": "60" }, { "x": "194", "y": "60" }, { "x": "194", "y": "42" } ] }, "lines": [ { "boundingBox": { "vertices": [ { "x": "68", "y": "42" }, { "x": "68", "y": "60" }, { "x": "194", "y": "60" }, { "x": "194", "y": "42" } ] }, "text": "Фамилия", "words": [ { "boundingBox": { "vertices": [ { "x": "68", "y": "40" }, { "x": "68", "y": "63" }, { "x": "194", "y": "63" }, { "x": "194", "y": "40" } ] }, "text": "Фамилия", "entityIndex": "-1", "textSegments": [ { "startIndex": "0", "length": "7" } ] } ], "textSegments": [ { "startIndex": "0", "length": "7" } ] } ], "languages": [ { "languageCode": "ru" } ], "textSegments": [ { "startIndex": "0", "length": "7" } ] }, { "boundingBox": { "vertices": [ { "x": "307", "y": "40" }, { "x": "307", "y": "61" }, { "x": "372", "y": "61" }, { "x": "372", "y": "40" } ] }, "lines": [ { "boundingBox": { "vertices": [ { "x": "307", "y": "40" }, { "x": "307", "y": "61" }, { "x": "372", "y": "61" }, { "x": "372", "y": "40" } ] }, "text": "Имя", "words": [ { "boundingBox": { "vertices": [ { "x": "307", "y": "39" }, { "x": "307", "y": "63" }, { "x": "372", "y": "63" }, { "x": "372", "y": "39" } ] }, "text": "Имя", "entityIndex": "-1", "textSegments": [ { "startIndex": "8", "length": "3" } ] } ], "textSegments": [ { "startIndex": "8", "length": "3" } ] } ], "languages": [ { "languageCode": "ru" } ], "textSegments": [ { "startIndex": "8", "length": "3" } ] }, { "boundingBox": { "vertices": [ { "x": "506", "y": "43" }, { "x": "506", "y": "59" }, { "x": "632", "y": "59" }, { "x": "632", "y": "43" } ] }, "lines": [ { "boundingBox": { "vertices": [ { "x": "506", "y": "43" }, { "x": "506", "y": "59" }, { "x": "632", "y": "59" }, { "x": "632", "y": "43" } ] }, "text": "Отчество", "words": [ { "boundingBox": { "vertices": [ { "x": "506", "y": "40" }, { "x": "506", "y": "63" }, { "x": "632", "y": "63" }, { "x": "632", "y": "40" } ] }, "text": "Отчество", "entityIndex": "-1", "textSegments": [ { "startIndex": "12", "length": "8" } ] } ], "textSegments": [ { "startIndex": "12", "length": "8" } ] } ], "languages": [ { "languageCode": "ru" } ], "textSegments": [ { "startIndex": "12", "length": "8" } ] }, { "boundingBox": { "vertices": [ { "x": "80", "y": "81" }, { "x": "80", "y": "98" }, { "x": "179", "y": "98" }, { "x": "179", "y": "81" } ] }, "lines": [ { "boundingBox": { "vertices": [ { "x": "80", "y": "81" }, { "x": "80", "y": "98" }, { "x": "179", "y": "98" }, { "x": "179", "y": "81" } ] }, "text": "Иванов", "words": [ { "boundingBox": { "vertices": [ { "x": "80", "y": "79" }, { "x": "80", "y": "101" }, { "x": "179", "y": "101" }, { "x": "179", "y": "79" } ] }, "text": "Иванов", "entityIndex": "-1", "textSegments": [ { "startIndex": "21", "length": "6" } ] } ], "textSegments": [ { "startIndex": "21", "length": "6" } ] } ], "languages": [ { "languageCode": "ru" } ], "textSegments": [ { "startIndex": "21", "length": "6" } ] }, { "boundingBox": { "vertices": [ { "x": "302", "y": "80" }, { "x": "302", "y": "98" }, { "x": "370", "y": "98" }, { "x": "370", "y": "80" } ] }, "lines": [ { "boundingBox": { "vertices": [ { "x": "302", "y": "80" }, { "x": "302", "y": "98" }, { "x": "370", "y": "98" }, { "x": "370", "y": "80" } ] }, "text": "Иван", "words": [ { "boundingBox": { "vertices": [ { "x": "302", "y": "78" }, { "x": "302", "y": "101" }, { "x": "370", "y": "101" }, { "x": "370", "y": "78" } ] }, "text": "Иван", "entityIndex": "-1", "textSegments": [ { "startIndex": "28", "length": "4" } ] } ], "textSegments": [ { "startIndex": "28", "length": "4" } ] } ], "languages": [ { "languageCode": "ru" } ], "textSegments": [ { "startIndex": "28", "length": "4" } ] }, { "boundingBox": { "vertices": [ { "x": "504", "y": "82" }, { "x": "504", "y": "98" }, { "x": "630", "y": "98" }, { "x": "630", "y": "82" } ] }, "lines": [ { "boundingBox": { "vertices": [ { "x": "504", "y": "82" }, { "x": "504", "y": "98" }, { "x": "630", "y": "98" }, { "x": "630", "y": "82" } ] }, "text": "Иванович", "words": [ { "boundingBox": { "vertices": [ { "x": "504", "y": "80" }, { "x": "504", "y": "101" }, { "x": "630", "y": "101" }, { "x": "630", "y": "80" } ] }, "text": "Иванович", "entityIndex": "-1", "textSegments": [ { "startIndex": "33", "length": "8" } ] } ], "textSegments": [ { "startIndex": "33", "length": "8" } ] } ], "languages": [ { "languageCode": "ru" } ], "textSegments": [ { "startIndex": "33", "length": "8" } ] } ], "entities": [], "tables": [ { "boundingBox": { "vertices": [ { "x": "34", "y": "30" }, { "x": "687", "y": "41" }, { "x": "686", "y": "119" }, { "x": "33", "y": "108" } ] }, "rowCount": "2", "columnCount": "3", "cells": [ { "boundingBox": { "vertices": [ { "x": "35", "y": "30" }, { "x": "242", "y": "33" }, { "x": "241", "y": "64" }, { "x": "34", "y": "61" } ] }, "rowIndex": "0", "columnIndex": "0", "columnSpan": "1", "rowSpan": "1", "text": "Фамилия", "textSegments": [ { "startIndex": "0", "length": "7" } ] }, { "boundingBox": { "vertices": [ { "x": "242", "y": "33" }, { "x": "444", "y": "37" }, { "x": "444", "y": "67" }, { "x": "241", "y": "64" } ] }, "rowIndex": "0", "columnIndex": "1", "columnSpan": "1", "rowSpan": "1", "text": "Имя", "textSegments": [ { "startIndex": "8", "length": "3" } ] }, { "boundingBox": { "vertices": [ { "x": "444", "y": "37" }, { "x": "686", "y": "40" }, { "x": "685", "y": "71" }, { "x": "444", "y": "67" } ] }, "rowIndex": "0", "columnIndex": "2", "columnSpan": "1", "rowSpan": "1", "text": "Отчество", "textSegments": [ { "startIndex": "12", "length": "8" } ] }, { "boundingBox": { "vertices": [ { "x": "34", "y": "61" }, { "x": "241", "y": "64" }, { "x": "241", "y": "108" }, { "x": "34", "y": "105" } ] }, "rowIndex": "1", "columnIndex": "0", "columnSpan": "1", "rowSpan": "1", "text": "Иванов", "textSegments": [ { "startIndex": "21", "length": "6" } ] }, { "boundingBox": { "vertices": [ { "x": "241", "y": "64" }, { "x": "444", "y": "67" }, { "x": "443", "y": "111" }, { "x": "241", "y": "108" } ] }, "rowIndex": "1", "columnIndex": "1", "columnSpan": "1", "rowSpan": "1", "text": "Иван", "textSegments": [ { "startIndex": "28", "length": "4" } ] }, { "boundingBox": { "vertices": [ { "x": "444", "y": "67" }, { "x": "685", "y": "71" }, { "x": "684", "y": "115" }, { "x": "443", "y": "111" } ] }, "rowIndex": "1", "columnIndex": "2", "columnSpan": "1", "rowSpan": "1", "text": "Иванович", "textSegments": [ { "startIndex": "33", "length": "8" } ] } ] } ], "fullText": "Фамилия\nИмя\nОтчество\nИванов\nИван\nИванович\n" }, "page": "0" } }
-
Чтобы получить все распознанные на изображении слова, найдите все значения со свойством
text
.
Примечание
Если полученные координаты не соответствуют отображаемому положению элементов, настройте в вашем средстве просмотра изображений поддержку метаданных exif
, либо при передаче в сервис удаляйте из секции exif
изображения атрибут Orientation
.