Распознать текст на изображении
Чтобы распознать текст на изображении, используйте OCR API. Это обновленный интерфейс с расширенными возможностями, включая распознавание многоколоночного текста. В примерах ниже используется модель page, подходящая для распознавания печатного текста на всех поддерживаемых языках, а также рукописного текста на русском и английском языках. Эта же инструкция подойдет и для других задач — достаточно изменить параметр model. Например, укажите table для распознавания таблиц.
Перед началом работы
Чтобы воспользоваться примером, вам понадобится сервисный аккаунт с ролью ai.vision.user и API-ключ с областью действия yc.ai.foundationModels.execute. API-ключ, который вы можете создать в AI Studio, имеет такие разрешения. Пример того, как настроить рабочее окружение, можно найти в разделе Начало работы.
Подготовьте файл изображения, соответствующий требованиям:
- Поддерживаемые форматы файлов: JPEG, PNG, PDF. MIME-тип файла указывайте в свойстве
mime_type. По умолчаниюimage. - Максимальный размер файла: 10 МБ.
- Размер изображения не должен превышать 20 мегапикселей (длина × ширина).
Распознать текст на изображении с помощью OCR API
Совет
Нужен пример? Скачайте изображение дорожного знака, предупреждающего о пингвинах.
import requests
import json
import base64
import os
YANDEX_API_KEY = os.environ["YANDEX_API_KEY"]
YANDEX_FOLDER_ID = os.environ["YANDEX_FOLDER_ID"]
def encode_file(file_path):
with open(file_path, "rb") as f:
return base64.b64encode(f.read()).decode("utf-8")
image_path = "penguins_sample.jpg"
content = encode_file(image_path)
data = {
"mimeType": "JPEG",
"languageCodes": ["*"],
"model": "page",
"content": content
}
headers = {
"Content-Type": "application/json",
"Authorization": f"Api-Key {YANDEX_API_KEY}",
"x-folder-id": YANDEX_FOLDER_ID,
"x-data-logging-enabled": "true"
}
response = requests.post(
"https://ai.api.cloud.yandex.net/ocr/v1/recognizeText",
headers=headers,
data=json.dumps(data)
)
print(json.dumps(response.json(), ensure_ascii=False, indent=2))
Где:
YANDEX_API_KEY— API-ключ для работы с Vision OCR.YANDEX_FOLDER_ID— идентификатор каталога сервисного аккаунта.image_path— путь к файлу изображения. Файл должен соответствовать требованиям.mimeType— MIME-тип файла изображения:JPEG,PNG,PDFи другие.languageCodes— список языков для распознавания. Значение["*"]означает автоматическое определение языка.model— модель распознавания. Значениеpageподходит для любого текста.
Пример результата
{
"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"
}
}
import fs from "fs";
const YANDEX_API_KEY = process.env.YANDEX_API_KEY;
const YANDEX_FOLDER_ID = process.env.YANDEX_FOLDER_ID;
const imagePath = "penguins_sample.jpg";
const content = fs.readFileSync(imagePath).toString("base64");
const body = {
mimeType: "JPEG",
languageCodes: ["*"],
model: "page",
content,
};
const response = await fetch("https://ai.api.cloud.yandex.net/ocr/v1/recognizeText", {
method: "POST",
headers: {
"Content-Type": "application/json",
Authorization: `Api-Key ${YANDEX_API_KEY}`,
"x-folder-id": YANDEX_FOLDER_ID,
"x-data-logging-enabled": "true",
},
body: JSON.stringify(body),
});
const result = await response.json();
console.log(JSON.stringify(result, null, 2));
Где:
YANDEX_API_KEY— API-ключ для работы с Vision OCR.YANDEX_FOLDER_ID— идентификатор каталога сервисного аккаунта.imagePath— путь к файлу изображения. Файл должен соответствовать требованиям.mimeType— MIME-тип файла изображения:JPEG,PNG,PDFи другие.languageCodes— список языков для распознавания. Значение["*"]означает автоматическое определение языка.model— модель распознавания. Значениеpageподходит для любого текста.
Пример результата
{
"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"
}
}
package main
import (
"bytes"
"encoding/base64"
"encoding/json"
"fmt"
"io"
"log"
"net/http"
"os"
)
var (
YANDEX_API_KEY = os.Getenv("YANDEX_API_KEY")
YANDEX_FOLDER_ID = os.Getenv("YANDEX_FOLDER_ID")
)
func main() {
imagePath := "penguins_sample.jpg"
imageData, err := os.ReadFile(imagePath)
if err != nil {
log.Fatalf("Ошибка чтения файла: %v", err)
}
content := base64.StdEncoding.EncodeToString(imageData)
body := map[string]interface{}{
"mimeType": "image/jpeg",
"languageCodes": []string{"*"},
"model": "page",
"content": content,
}
bodyBytes, err := json.Marshal(body)
if err != nil {
log.Fatalf("Ошибка сериализации: %v", err)
}
req, err := http.NewRequest("POST",
"https://ai.api.cloud.yandex.net/ocr/v1/recognizeText",
bytes.NewReader(bodyBytes))
if err != nil {
log.Fatalf("Ошибка создания запроса: %v", err)
}
req.Header.Set("Content-Type", "application/json")
req.Header.Set("Authorization", "Api-Key "+YANDEX_API_KEY)
req.Header.Set("x-folder-id", YANDEX_FOLDER_ID)
req.Header.Set("x-data-logging-enabled", "true")
resp, err := http.DefaultClient.Do(req)
if err != nil {
log.Fatalf("Ошибка запроса: %v", err)
}
defer resp.Body.Close()
respBody, err := io.ReadAll(resp.Body)
if err != nil {
log.Fatalf("Ошибка чтения ответа: %v", err)
}
if resp.StatusCode != http.StatusOK {
log.Fatalf("Сервис вернул статус %d: %s", resp.StatusCode, bytes.TrimSpace(respBody))
}
var pretty bytes.Buffer
if err := json.Indent(&pretty, respBody, "", " "); err != nil {
log.Fatalf("Ошибка форматирования JSON: %v", err)
}
fmt.Println(pretty.String())
}
Где:
YANDEX_API_KEY— API-ключ для работы с Vision OCR.YANDEX_FOLDER_ID— идентификатор каталога сервисного аккаунта.imagePath— путь к файлу изображения. Файл должен соответствовать требованиям.mimeType— MIME-тип файла изображения:JPEG,PNG,PDFи другие.languageCodes— список языков для распознавания. Значение["*"]означает автоматическое определение языка.model— модель распознавания. Значениеpageподходит для любого текста.
Пример результата
{
"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"
}
}
-
Закодируйте файл изображения в формат Base64 и сохраните результат в файл, например
encoded.txt. -
Создайте файл с телом запроса, например
body.json:{ "mimeType": "JPEG", "languageCodes": ["*"], "model": "page", "content": "<изображение_в_кодировке_base64>" }В свойстве
contentукажите содержимое файлаencoded.txt. -
Отправьте запрос:
export YANDEX_API_KEY=<API-ключ> export YANDEX_FOLDER_ID=<идентификатор_каталога> curl \ --request POST \ --header "Content-Type: application/json" \ --header "Authorization: Api-Key ${YANDEX_API_KEY}" \ --header "x-folder-id: ${YANDEX_FOLDER_ID}" \ --header "x-data-logging-enabled: true" \ --data "@body.json" \ https://ai.api.cloud.yandex.net/ocr/v1/recognizeText \ --output output.jsonГде:
<API-ключ>— API-ключ для работы с Vision OCR.<идентификатор_каталога>— идентификатор каталога сервисного аккаунта.
Пример результата
{
"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"
}
}
Результат содержит распознанные блоки текста, строки и слова с указанием их местоположения на изображении. Чтобы получить все распознанные слова, найдите все значения со свойством text или используйте поле fullText.
Примечание
Если полученные координаты не соответствуют отображаемому положению элементов, настройте в вашем средстве просмотра изображений поддержку метаданных exif, либо при передаче в сервис удаляйте из секции exif изображения атрибут Orientation.
Полезные ссылки
- Распознавание текста (Vision OCR)
- Кодирование файла в Base64
- Распознавание рукописного текста
- Распознать таблицу
Каталог — пространство, в котором содержатся ресурсы Yandex Cloud. Для аутентификации в AI Studio необходим идентификатор каталога. Чтобы его получить, в интерфейсе AI Studio наведите указатель на название каталога, расположенное в верхней части экрана, и нажмите
