Compreensão de imagens

Os modelos Gemini podem processar imagens, permitindo muitos casos de uso de desenvolvedores de fronteira que, historicamente, exigiriam modelos específicos de domínio. Alguns dos recursos de visão do Gemini incluem a capacidade de:

  • Adicionar legendas e responder a perguntas sobre imagens
  • Transcrever e analisar PDFs, incluindo até 2 milhões de tokens
  • Detectar objetos em uma imagem e retornar as coordenadas da caixa delimitadora
  • Segmentar objetos em uma imagem

O Gemini foi criado para ser multimodal desde o início, e continuamos avançando os limites do que é possível. Este guia mostra como usar a API Gemini para gerar respostas de texto com base em entradas de imagem e realizar tarefas comuns de compreensão de imagem.

Antes de começar

Antes de chamar a API Gemini, verifique se você tem o SDK de sua escolha instalado e uma chave da API Gemini configurada e pronta para uso.

Entrada de imagem

Você pode fornecer imagens como entrada para o Gemini das seguintes maneiras:

  • Faça upload de um arquivo de imagem usando a API File antes de fazer uma solicitação para generateContent. Use esse método para arquivos maiores que 20 MB ou quando você quiser reutilizar o arquivo em várias solicitações.
  • Transmita dados de imagem inline com a solicitação para generateContent. Use esse método para arquivos menores (<20 MB de tamanho total da solicitação) ou imagens extraídas diretamente de URLs.

Fazer upload de um arquivo de imagem

É possível usar a API Files para fazer upload de um arquivo de imagem. Sempre use a API Files quando o tamanho total da solicitação (incluindo o arquivo, o comando de texto, as instruções do sistema etc.) for maior que 20 MB ou se você quiser usar a mesma imagem em vários comandos.

O código abaixo faz upload de um arquivo de imagem e o usa em uma chamada para 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)
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

Para saber mais sobre como trabalhar com arquivos de mídia, consulte a API Files.

Transmitir dados de imagem inline

Em vez de fazer upload de um arquivo de imagem, é possível transmitir dados de imagem inline na solicitação para generateContent. Isso é adequado para imagens menores (tamanho de solicitação total de menos de 20 MB) ou imagens buscadas diretamente de URLs.

É possível fornecer dados de imagem como strings codificadas em Base64 ou lendo arquivos locais diretamente (dependendo do SDK).

Arquivo de imagem local:

  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)
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

Imagem do 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)
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

Alguns lembretes sobre os dados de imagem inline:

  • O tamanho máximo total da solicitação é de 20 MB, incluindo comandos de texto, instruções do sistema e todos os arquivos fornecidos inline. Se o tamanho do arquivo fizer com que o tamanho total da solicitação exceda 20 MB, use a API Files para fazer upload de um arquivo de imagem para usar na solicitação.
  • Se você estiver usando uma amostra de imagem várias vezes, será mais eficiente fazer upload de um arquivo de imagem usando a API File.

Solicitação com várias imagens

É possível fornecer várias imagens em um único comando incluindo vários objetos Part de imagem na matriz contents. Eles podem ser uma mistura de dados inline (arquivos locais ou URLs) e referências da API File.

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)
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

Extrair uma caixa delimitadora para um objeto

Os modelos do Gemini são treinados para identificar objetos em uma imagem e fornecer as coordenadas da caixa delimitadora. As coordenadas são retornadas em relação às dimensões da imagem, dimensionadas para [0, 1000]. É necessário redimensionar essas coordenadas com base no tamanho da imagem original.

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

É possível usar caixas delimitadoras para a detecção e a localização de objetos em imagens e vídeos. Ao identificar e delimitar objetos com caixas limitadoras, você pode desbloquear uma ampla gama de aplicativos e melhorar a inteligência dos seus projetos.

Principais vantagens

  • Simples:integre recursos de detecção de objetos aos seus aplicativos com facilidade, independentemente da sua experiência em visão computacional.
  • Personalizável:produz caixas delimitadoras com base em instruções personalizadas (por exemplo, "Quero ver caixas delimitadoras de todos os objetos verdes nesta imagem") sem precisar treinar um modelo personalizado.

Detalhes técnicos

  • Entrada:seu comando e as imagens ou frames de vídeo associados.
  • Saída:caixas delimitadoras no formato [y_min, x_min, y_max, x_max]. O canto superior esquerdo é a origem. Os eixos x e y vão horizontalmente e verticalmente, respectivamente. Os valores de coordenadas são normalizados de 0 a 1.000 para cada imagem.
  • Visualização:os usuários do AI Studio vão ver as caixas de limite plotadas na interface.

Para desenvolvedores Python, teste o notebook de compreensão espacial 2D ou o notebook experimental de ponteiro 3D.

Normalizar coordenadas

O modelo retorna coordenadas da caixa delimitadora no formato [y_min, x_min, y_max, x_max]. Para converter essas coordenadas normalizadas nas coordenadas de pixel da imagem original, siga estas etapas:

  1. Divida cada coordenada de saída por 1.000.
  2. Multiplique as coordenadas x pela largura da imagem original.
  3. Multiplique as coordenadas y pela altura da imagem original.

Para conferir exemplos mais detalhados de como gerar coordenadas de caixa delimitadora e visualizá-las em imagens, consulte o exemplo de livro de receitas de Detecção de objetos.

Segmentação de imagens

A partir dos modelos Gemini 2.5, os modelos Gemini são treinados para não apenas detectar itens, mas também segmentá-los e fornecer uma máscara dos contornos.

O modelo prevê uma lista JSON, em que cada item representa uma máscara de segmentação. Cada item tem uma caixa delimitadora ("box_2d") no formato [y0, x0, y1, x1] com coordenadas normalizadas entre 0 e 1000, um rótulo ("label") que identifica o objeto e, por fim, a máscara de segmentação dentro da caixa delimitadora, como png codificado em base64, que é um mapa de probabilidade com valores entre 0 e 255. A máscara precisa ser redimensionada para corresponder às dimensões da caixa delimitadora e, em seguida, binarizada no limite de confiança (127 para o ponto médio).

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.
"""
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.
'''
Uma mesa com cupcakes, com objetos de madeira e vidro destacados
Máscara dos objetos de madeira e vidro encontrados na imagem

Confira o exemplo de segmentação no guia de manual para conferir um exemplo mais detalhado.

Formatos de imagem compatíveis

O Gemini é compatível com os seguintes tipos MIME de formato de imagem:

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

Detalhes técnicos sobre imagens

  • Limite de arquivos: o Gemini 2.5 Pro, 2.0 Flash, 1.5 Pro e 1.5 Flash oferecem suporte a um máximo de 3.600 arquivos de imagem por solicitação.
  • Cálculo de tokens:
    • Gemini 1.5 Flash e Gemini 1.5 Pro: 258 tokens se ambas as dimensões forem <= 384 pixels. Imagens maiores são divididas em blocos (mínimo de 256 x 256 pixels, máximo de 768 x 768 pixels, redimensionado para 768 x 768), e cada bloco custa 258 tokens.
    • Gemini 2.0 Flash: 258 tokens se as duas dimensões forem <= 384 pixels. Imagens maiores são divididas em blocos de 768 x 768 pixels, cada um custando 258 tokens.
  • Práticas recomendadas:
    • Verifique se as imagens estão giradas corretamente.
    • Use imagens claras e não desfocadas.
    • Ao usar uma única imagem com texto, coloque o comando de texto após a parte da imagem na matriz contents.

A seguir

Este guia mostra como fazer upload de arquivos de imagem e gerar saídas de texto a partir de entradas de imagem. Para saber mais, consulte os seguintes recursos:

  • Instruções do sistema: permitem orientar o comportamento do modelo com base nas suas necessidades e casos de uso específicos.
  • Compreensão de vídeo: aprenda a trabalhar com entradas de vídeo.
  • API Files: saiba como fazer upload e gerenciar arquivos para uso com o Gemini.
  • Estratégias de solicitação de arquivo: a API Gemini oferece suporte a solicitações com dados de texto, imagem, áudio e vídeo, também conhecidas como solicitações multimodais.
  • Orientações de segurança: às vezes, os modelos de IA generativa produzem resultados inesperados, como resultados imprecisos, parciais ou ofensivos. O pós-processamento e a avaliação humana são essenciais para limitar o risco de danos causados por essas saídas.