Понимание изображения

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

  • Подписывайтесь и отвечайте на вопросы об изображениях
  • Транскрибируйте и анализируйте PDF-файлы, включая до 2 миллионов токенов
  • Обнаруживайте объекты на изображении и возвращайте для них координаты ограничивающей рамки.
  • Сегментируйте объекты внутри изображения

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

Прежде чем начать

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

Ввод изображения

Вы можете предоставить изображения в качестве входных данных для Gemini следующими способами:

  • Загрузите файл изображения с помощью File API, прежде чем отправлять запрос generateContent . Используйте этот метод для файлов размером более 20 МБ или если вы хотите повторно использовать файл для нескольких запросов.
  • Передайте встроенные данные изображения с запросом generateContent . Используйте этот метод для файлов меньшего размера (общий размер запроса <20 МБ) или изображений, полученных непосредственно с URL-адресов.

Загрузите файл изображения

Вы можете использовать Files API для загрузки файла изображения. Всегда используйте Files API, если общий размер запроса (включая файл, текстовое приглашение, системные инструкции и т. д.) превышает 20 МБ или если вы собираетесь использовать одно и то же изображение в нескольких приглашениях.

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

Питон

from google import genai

client = genai.Client(api_key="GOOGLE_API_KEY")

myfile = client.files.upload(file="path/to/sample.jpg")

response = client.models.generate_content(
    model="gemini-2.0-flash",
    contents=[myfile, "Caption this image."])

print(response.text)

JavaScript

import {
  GoogleGenAI,
  createUserContent,
  createPartFromUri,
} from "@google/genai";

const ai = new GoogleGenAI({ apiKey: "GOOGLE_API_KEY" });

async function main() {
  const myfile = await ai.files.upload({
    file: "path/to/sample.jpg",
    config: { mimeType: "image/jpeg" },
  });

  const response = await ai.models.generateContent({
    model: "gemini-2.0-flash",
    contents: createUserContent([
      createPartFromUri(myfile.uri, myfile.mimeType),
      "Caption this image.",
    ]),
  });
  console.log(response.text);
}

await main();

Идти

file, err := client.UploadFileFromPath(ctx, "path/to/sample.jpg", nil)
if err != nil {
    log.Fatal(err)
}
defer client.DeleteFile(ctx, file.Name)

model := client.GenerativeModel("gemini-2.0-flash")
resp, err := model.GenerateContent(ctx,
    genai.FileData{URI: file.URI},
    genai.Text("Caption this image."))
if err != nil {
    log.Fatal(err)
}

printResponse(resp)

ОТДЫХ

IMAGE_PATH="path/to/sample.jpg"
MIME_TYPE=$(file -b --mime-type "${IMAGE_PATH}")
NUM_BYTES=$(wc -c < "${IMAGE_PATH}")
DISPLAY_NAME=IMAGE

tmp_header_file=upload-header.tmp

# Initial resumable request defining metadata.
# The upload url is in the response headers dump them to a file.
curl "https://generativelanguage.googleapis.com/upload/v1beta/files?key=${GOOGLE_API_KEY}" \
  -D upload-header.tmp \
  -H "X-Goog-Upload-Protocol: resumable" \
  -H "X-Goog-Upload-Command: start" \
  -H "X-Goog-Upload-Header-Content-Length: ${NUM_BYTES}" \
  -H "X-Goog-Upload-Header-Content-Type: ${MIME_TYPE}" \
  -H "Content-Type: application/json" \
  -d "{'file': {'display_name': '${DISPLAY_NAME}'}}" 2> /dev/null

upload_url=$(grep -i "x-goog-upload-url: " "${tmp_header_file}" | cut -d" " -f2 | tr -d "\r")
rm "${tmp_header_file}"

# Upload the actual bytes.
curl "${upload_url}" \
  -H "Content-Length: ${NUM_BYTES}" \
  -H "X-Goog-Upload-Offset: 0" \
  -H "X-Goog-Upload-Command: upload, finalize" \
  --data-binary "@${IMAGE_PATH}" 2> /dev/null > file_info.json

file_uri=$(jq ".file.uri" file_info.json)
echo file_uri=$file_uri

# Now generate content using that file
curl "https://generativelanguage.googleapis.com/v1beta/models/gemini-2.0-flash:generateContent?key=$GOOGLE_API_KEY" \
    -H 'Content-Type: application/json' \
    -X POST \
    -d '{
      "contents": [{
        "parts":[
          {"file_data":{"mime_type": "${MIME_TYPE}", "file_uri": '$file_uri'}},
          {"text": "Caption this image."}]
        }]
      }' 2> /dev/null > response.json

cat response.json
echo

jq ".candidates[].content.parts[].text" response.json

Дополнительные сведения о работе с медиафайлами см. в разделе Files API .

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

Вместо загрузки файла изображения вы можете передать встроенные данные изображения в запросе generateContent . Это подходит для изображений меньшего размера (общий размер запроса менее 20 МБ) или изображений, полученных непосредственно с URL-адресов.

Вы можете предоставить данные изображения в виде строк в кодировке Base64 или напрямую прочитать локальные файлы (в зависимости от SDK).

Локальный файл изображения:

Питон

  from google.genai import types

  with open('path/to/small-sample.jpg', 'rb') as f:
      img_bytes = f.read()

  response = client.models.generate_content(
    model='gemini-2.0-flash',
    contents=[
      types.Part.from_bytes(
        data=img_bytes,
        mime_type='image/jpeg',
      ),
      'Caption this image.'
    ]
  )

  print(response.text)

JavaScript

import { GoogleGenAI } from "@google/genai";
import * as fs from "node:fs";

const ai = new GoogleGenAI({ apiKey: "GOOGLE_API_KEY" });
const base64ImageFile = fs.readFileSync("path/to/small-sample.jpg", {
  encoding: "base64",
});

const contents = [
  {
    inlineData: {
      mimeType: "image/jpeg",
      data: base64ImageFile,
    },
  },
  { text: "Caption this image." },
];

const response = await ai.models.generateContent({
  model: "gemini-2.0-flash",
  contents: contents,
});
console.log(response.text);

Идти

model := client.GenerativeModel("gemini-2.0-flash")

bytes, err := os.ReadFile("path/to/small-sample.jpg")
if err != nil {
  log.Fatal(err)
}

prompt := []genai.Part{
  genai.Blob{MIMEType: "image/jpeg", Data: bytes},
  genai.Text("Caption this image."),
}

resp, err := model.GenerateContent(ctx, prompt...)
if err != nil {
  log.Fatal(err)
}

for _, c := range resp.Candidates {
  if c.Content != nil {
    fmt.Println(*c.Content)
  }
}

ОТДЫХ

IMG_PATH=/path/to/your/image1.jpg

if [[ "$(base64 --version 2>&1)" = *"FreeBSD"* ]]; then
  B64FLAGS="--input"
else
  B64FLAGS="-w0"
fi

curl "https://generativelanguage.googleapis.com/v1beta/models/gemini-2.0-flash:generateContent?key=$GOOGLE_API_KEY" \
    -H 'Content-Type: application/json' \
    -X POST \
    -d '{
      "contents": [{
        "parts":[
            {
              "inline_data": {
                "mime_type":"image/jpeg",
                "data": "'\$(base64 \$B64FLAGS \$IMG_PATH)'"
              }
            },
            {"text": "Caption this image."},
        ]
      }]
    }' 2> /dev/null

Изображение с URL:

Питон

from google import genai
from google.genai import types

import requests

image_path = "https://goo.gle/instrument-img"
image = requests.get(image_path)

client = genai.Client(api_key="GOOGLE_API_KEY")
response = client.models.generate_content(
    model="gemini-2.0-flash-exp",
    contents=["What is this image?",
              types.Part.from_bytes(data=image.content, mime_type="image/jpeg")])

print(response.text)

JavaScript

import { GoogleGenAI } from "@google/genai";

async function main() {
  const ai = new GoogleGenAI({ apiKey: process.env.GOOGLE_API_KEY });

  const imageUrl = "https://goo.gle/instrument-img";

  const response = await fetch(imageUrl);
  const imageArrayBuffer = await response.arrayBuffer();
  const base64ImageData = Buffer.from(imageArrayBuffer).toString('base64');

  const result = await ai.models.generateContent({
    model: "gemini-2.0-flash",
    contents: [
    {
      inlineData: {
        mimeType: 'image/jpeg',
        data: base64ImageData,
      },
    },
    { text: "Caption this image." }
  ],
  });
  console.log(result.text);
}

main();

Идти

func main() {
ctx := context.Background()
client, err := genai.NewClient(ctx, option.WithAPIKey(os.Getenv("GOOGLE_API_KEY")))
if err != nil {
  log.Fatal(err)
}
defer client.Close()

model := client.GenerativeModel("gemini-2.0-flash")

// Download the image.
imageResp, err := http.Get("https://goo.gle/instrument-img")
if err != nil {
  panic(err)
}
defer imageResp.Body.Close()

imageBytes, err := io.ReadAll(imageResp.Body)
if err != nil {
  panic(err)
}

// Create the request.
req := []genai.Part{
  genai.ImageData("jpeg", imageBytes),

  genai.Text("Caption this image."),
}

// Generate content.
resp, err := model.GenerateContent(ctx, req...)
if err != nil {
  panic(err)
}

// Handle the response of generated text.
for _, c := range resp.Candidates {
  if c.Content != nil {
    fmt.Println(*c.Content)
  }
}

}

ОТДЫХ

IMG_URL="https://goo.gle/instrument-img"

MIME_TYPE=$(curl -sIL "$IMG_URL" | grep -i '^content-type:' | awk -F ': ' '{print $2}' | sed 's/\r$//' | head -n 1)
if [[ -z "$MIME_TYPE" || ! "$MIME_TYPE" == image/* ]]; then
  MIME_TYPE="image/jpeg"
fi

if [[ "$(base64 --version 2>&1)" = *"FreeBSD"* ]]; then
  B64FLAGS="--input"
else
  B64FLAGS="-w0"
fi

curl "https://generativelanguage.googleapis.com/v1beta/models/gemini-2.0-flash:generateContent?key=$GOOGLE_API_KEY" \
    -H 'Content-Type: application/json' \
    -X POST \
    -d '{
      "contents": [{
        "parts":[
            {
              "inline_data": {
                "mime_type":"'"$MIME_TYPE"'",
                "data": "'$(curl -sL "$IMG_URL" | base64 $B64FLAGS)'"
              }
            },
            {"text": "Caption this image."}
        ]
      }]
    }' 2> /dev/null

Несколько вещей, которые следует учитывать при работе с данными встроенных изображений:

  • Максимальный общий размер запроса составляет 20 МБ, включая текстовые подсказки, системные инструкции и все встроенные файлы. Если размер вашего файла превышает общий размер запроса 20 МБ, используйте Files API, чтобы загрузить файл изображения для использования в запросе.
  • Если вы используете образец изображения несколько раз, эффективнее загрузить файл изображения с помощью File API.

Подсказка с несколькими изображениями

Вы можете предоставить несколько изображений в одном приглашении, включив несколько объектов Part изображения в массив contents . Это может быть сочетание встроенных данных (локальных файлов или URL-адресов) и ссылок на файловый API.

Питон

from google import genai
from google.genai import types

client = genai.Client(api_key="GOOGLE_API_KEY")

# Upload the first image
image1_path = "path/to/image1.jpg"
uploaded_file = client.files.upload(file=image1_path)

# Prepare the second image as inline data
image2_path = "path/to/image2.png"
with open(image2_path, 'rb') as f:
    img2_bytes = f.read()

# Create the prompt with text and multiple images
response = client.models.generate_content(
    model="gemini-2.0-flash",
    contents=[
        "What is different between these two images?",
        uploaded_file,  # Use the uploaded file reference
        types.Part.from_bytes(
            data=img2_bytes,
            mime_type='image/png'
        )
    ]
)

print(response.text)

JavaScript

import {
  GoogleGenAI,
  createUserContent,
  createPartFromUri,
} from "@google/genai";
import * as fs from "node:fs";

const ai = new GoogleGenAI({ apiKey: "GOOGLE_API_KEY" });

async function main() {
  // Upload the first image
  const image1_path = "path/to/image1.jpg";
  const uploadedFile = await ai.files.upload({
    file: image1_path,
    config: { mimeType: "image/jpeg" },
  });

  // Prepare the second image as inline data
  const image2_path = "path/to/image2.png";
  const base64Image2File = fs.readFileSync(image2_path, {
    encoding: "base64",
  });

  // Create the prompt with text and multiple images
  const response = await ai.models.generateContent({
    model: "gemini-2.0-flash",
    contents: createUserContent([
      "What is different between these two images?",
      createPartFromUri(uploadedFile.uri, uploadedFile.mimeType),
      {
        inlineData: {
          mimeType: "image/png",
          data: base64Image2File,
        },
      },
    ]),
  });
  console.log(response.text);
}

await main();

Идти

+    // Upload the first image
image1Path := "path/to/image1.jpg"
uploadedFile, err := client.UploadFileFromPath(ctx, image1Path, nil)
if err != nil {
    log.Fatal(err)
}
defer client.DeleteFile(ctx, uploadedFile.Name)

// Prepare the second image as inline data
image2Path := "path/to/image2.png"
img2Bytes, err := os.ReadFile(image2Path)
if err != nil {
  log.Fatal(err)
}

// Create the prompt with text and multiple images
model := client.GenerativeModel("gemini-2.0-flash")
prompt := []genai.Part{
  genai.Text("What is different between these two images?"),
  genai.FileData{URI: uploadedFile.URI},
  genai.Blob{MIMEType: "image/png", Data: img2Bytes},
}

resp, err := model.GenerateContent(ctx, prompt...)
if err != nil {
  log.Fatal(err)
}

printResponse(resp)

ОТДЫХ

# Upload the first image
IMAGE1_PATH="path/to/image1.jpg"
MIME1_TYPE=$(file -b --mime-type "${IMAGE1_PATH}")
NUM1_BYTES=$(wc -c < "${IMAGE1_PATH}")
DISPLAY_NAME1=IMAGE1

tmp_header_file1=upload-header1.tmp

curl "https://generativelanguage.googleapis.com/upload/v1beta/files?key=${GOOGLE_API_KEY}" \
  -D upload-header1.tmp \
  -H "X-Goog-Upload-Protocol: resumable" \
  -H "X-Goog-Upload-Command: start" \
  -H "X-Goog-Upload-Header-Content-Length: ${NUM1_BYTES}" \
  -H "X-Goog-Upload-Header-Content-Type: ${MIME1_TYPE}" \
  -H "Content-Type: application/json" \
  -d "{'file': {'display_name': '${DISPLAY_NAME1}'}}" 2> /dev/null

upload_url1=$(grep -i "x-goog-upload-url: " "${tmp_header_file1}" | cut -d" " -f2 | tr -d "\r")
rm "${tmp_header_file1}"

curl "${upload_url1}" \
  -H "Content-Length: ${NUM1_BYTES}" \
  -H "X-Goog-Upload-Offset: 0" \
  -H "X-Goog-Upload-Command: upload, finalize" \
  --data-binary "@${IMAGE1_PATH}" 2> /dev/null > file_info1.json

file1_uri=$(jq ".file.uri" file_info1.json)
echo file1_uri=$file1_uri

# Prepare the second image (inline)
IMAGE2_PATH="path/to/image2.png"
MIME2_TYPE=$(file -b --mime-type "${IMAGE2_PATH}")

if [[ "$(base64 --version 2>&1)" = *"FreeBSD"* ]]; then
  B64FLAGS="--input"
else
  B64FLAGS="-w0"
fi
IMAGE2_BASE64=$(base64 $B64FLAGS $IMAGE2_PATH)

# Now generate content using both images
curl "https://generativelanguage.googleapis.com/v1beta/models/gemini-2.0-flash:generateContent?key=$GOOGLE_API_KEY" \
    -H 'Content-Type: application/json' \
    -X POST \
    -d '{
      "contents": [{
        "parts":[
          {"text": "What is different between these two images?"},
          {"file_data":{"mime_type": "'"${MIME1_TYPE}"'", "file_uri": '$file1_uri'}},
          {
            "inline_data": {
              "mime_type":"'"${MIME2_TYPE}"'",
              "data": "'"$IMAGE2_BASE64"'"
            }
          }
        ]
      }]
    }' 2> /dev/null > response.json

cat response.json
echo

jq ".candidates[].content.parts[].text" response.json

Получить ограничивающую рамку для объекта

Модели Gemini обучены идентифицировать объекты на изображении и предоставлять координаты их ограничивающей рамки. Координаты возвращаются относительно размеров изображения, масштабированных до [0, 1000]. Вам необходимо уменьшить масштаб этих координат в зависимости от исходного размера изображения.

Питон

prompt = "Detect the all of the prominent items in the image. The box_2d should be [ymin, xmin, ymax, xmax] normalized to 0-1000."

JavaScript

const prompt = "Detect the all of the prominent items in the image. The box_2d should be [ymin, xmin, ymax, xmax] normalized to 0-1000.";

Идти

prompt := []genai.Part{
    genai.FileData{URI: sampleImage.URI},
    genai.Text("Detect the all of the prominent items in the image. The box_2d should be [ymin, xmin, ymax, xmax] normalized to 0-1000."),
}

ОТДЫХ

PROMPT="Detect the all of the prominent items in the image. The box_2d should be [ymin, xmin, ymax, xmax] normalized to 0-1000."

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

Ключевые преимущества

  • Просто: с легкостью интегрируйте возможности обнаружения объектов в свои приложения, независимо от вашего опыта в области компьютерного зрения.
  • Настраиваемость: создавайте ограничивающие рамки на основе пользовательских инструкций (например, «Я хочу видеть ограничивающие рамки всех зеленых объектов на этом изображении») без необходимости обучения пользовательской модели.

Технические детали

  • Входные данные: ваше приглашение и связанные с ним изображения или видеокадры.
  • Вывод: ограничивающие рамки в формате [y_min, x_min, y_max, x_max] . Верхний левый угол — это начало координат. Ось x и y проходят горизонтально и вертикально соответственно. Значения координат нормализуются до 0–1000 для каждого изображения.
  • Визуализация: пользователи AI Studio увидят ограничивающие рамки, нанесенные в пользовательском интерфейсе.

Разработчики Python могут попробовать блокнот для 2D-пространства или экспериментальный блокнот для 3D-указания .

Нормализовать координаты

Модель возвращает координаты ограничивающего прямоугольника в формате [y_min, x_min, y_max, x_max] . Чтобы преобразовать эти нормализованные координаты в координаты пикселей исходного изображения, выполните следующие действия:

  1. Разделите каждую выходную координату на 1000.
  2. Умножьте координаты x на исходную ширину изображения.
  3. Умножьте координаты Y на исходную высоту изображения.

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

Сегментация изображений

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

Модель прогнозирует список JSON, где каждый элемент представляет собой маску сегментации. Каждый элемент имеет ограничивающую рамку (« box_2d ») в формате [y0, x0, y1, x1] с нормализованными координатами от 0 до 1000, метку (« label »), которая идентифицирует объект, и, наконец, маску сегментации внутри ограничивающей рамки в виде PNG в кодировке Base64, которая представляет собой карту вероятности со значениями от 0 до 255. Размер маски необходимо изменить, чтобы она соответствовала размерам ограничивающей рамки, а затем бинаризировать ее по вашему доверительному порогу. (127 для средней точки).

Питон

prompt = """
  Give the segmentation masks for the wooden and glass items.
  Output a JSON list of segmentation masks where each entry contains the 2D
  bounding box in the key "box_2d", the segmentation mask in key "mask", and
  the text label in the key "label". Use descriptive labels.
"""

JavaScript

const prompt = `
  Give the segmentation masks for the wooden and glass items.
  Output a JSON list of segmentation masks where each entry contains the 2D
  bounding box in the key "box_2d", the segmentation mask in key "mask", and
  the text label in the key "label". Use descriptive labels.
`;    

Идти

prompt := []genai.Part{
    genai.FileData{URI: sampleImage.URI},
    genai.Text(`
      Give the segmentation masks for the wooden and glass items.
      Output a JSON list of segmentation masks where each entry contains the 2D
      bounding box in the key "box_2d", the segmentation mask in key "mask", and
      the text label in the key "label". Use descriptive labels.
    `),
}

ОТДЫХ

PROMPT='''
  Give the segmentation masks for the wooden and glass items.
  Output a JSON list of segmentation masks where each entry contains the 2D
  bounding box in the key "box_2d", the segmentation mask in key "mask", and
  the text label in the key "label". Use descriptive labels.
'''
Стол с кексами, на котором выделены деревянные и стеклянные предметы.
Маска из деревянных и стеклянных предметов, найденных на картинке.

Более подробный пример можно найти в примере сегментации в руководстве по кулинарной книге.

Поддерживаемые форматы изображений

Gemini поддерживает следующие типы MIME форматов изображений:

  • PNG - image/png
  • JPEG — image/jpeg
  • WEBP — image/webp
  • HEIC — image/heic
  • HEIF - image/heif

Технические подробности об изображениях

  • Ограничение количества файлов : Gemini 2.5 Pro, 2.0 Flash, 1.5 Pro и 1.5 Flash поддерживают максимум 3600 файлов изображений на запрос.
  • Расчет токена :
    • Gemini 1.5 Flash и Gemini 1.5 Pro : 258 токенов, если оба размера <= 384 пикселей. Изображения большего размера разбиты на плитки (минимум 256 пикселей, максимум 768 пикселей, размер изменен до 768x768), причем каждая плитка стоит 258 жетонов.
    • Gemini 2.0 Flash : 258 токенов, если оба размера <= 384 пикселей. Изображения большего размера разбиты на плитки размером 768x768 пикселей, каждая из которых стоит 258 жетонов.
  • Лучшие практики :
    • Убедитесь, что изображения правильно повернуты.
    • Используйте четкие, не размытые изображения.
    • При использовании одного изображения с текстом поместите текстовую подсказку после части изображения в массиве contents .

Что дальше

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

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