Comprensione delle immagini

I modelli Gemini possono elaborare immagini, consentendo molti casi d'uso di frontiera per gli sviluppatori che in passato avrebbero richiesto modelli specifici per dominio. Alcune delle funzionalità di visione di Gemini includono la possibilità di:

  • Aggiungere didascalie e rispondere a domande sulle immagini
  • Trascrivere e ragionare sui PDF, inclusi fino a 2 milioni di token
  • Rileva gli oggetti in un'immagine e restituisci le coordinate dei relativi riquadri di delimitazione
  • Segmentare gli oggetti all'interno di un'immagine

Gemini è stato progettato per essere multimodale fin dall'inizio e continuiamo a spingere i confini di ciò che è possibile. Questa guida mostra come utilizzare l'API Gemini per generare risposte di testo in base agli input di immagini ed eseguire attività comuni di comprensione delle immagini.

Prima di iniziare

Prima di chiamare l'API Gemini, assicurati di aver installato l'SDK che preferisci e di avere configurato e pronto all'uso una chiave API Gemini.

Input di immagini

Puoi fornire immagini come input a Gemini nei seguenti modi:

  • Carica un file immagine utilizzando l'API File prima di effettuare una richiesta a generateContent. Utilizza questo metodo per file di dimensioni superiori a 20 MB o quando vuoi riutilizzare il file in più richieste.
  • Trasmetti i dati delle immagini in linea con la richiesta a generateContent. Utilizza questo metodo per file di dimensioni inferiori (dimensioni totali della richiesta < 20 MB) o immagini recuperate direttamente dagli URL.

Carica un file immagine

Puoi utilizzare l'API Files per caricare un file immagine. Utilizza sempre l'API Files quando le dimensioni totali della richiesta (incluso il file, il prompt di testo, le istruzioni di sistema e così via) sono superiori a 20 MB o se intendi utilizzare la stessa immagine in più prompt.

Il seguente codice carica un file immagine e lo utilizza in una chiamata a generateContent.

Python

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

Vai

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)

REST

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

Per scoprire di più su come utilizzare i file multimediali, consulta l'API Files.

Passare i dati delle immagini in linea

Invece di caricare un file immagine, puoi passare i dati immagine in linea nella richiesta a generateContent. È adatto per immagini più piccole (dimensioni totali della richiesta inferiori a 20 MB) o immagini recuperate direttamente dagli URL.

Puoi fornire i dati immagine come stringhe con codifica Base64 o leggendo direttamente i file locali (a seconda dell'SDK).

File immagine locale:

Python

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

Vai

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

REST

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

Immagine da URL:

Python

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

Vai

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

}

REST

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

Ecco alcuni aspetti da tenere presente sui dati delle immagini in linea:

  • La dimensione massima della richiesta totale è 20 MB, inclusi i prompt di testo, le istruzioni di sistema e tutti i file forniti in linea. Se le dimensioni del file fanno superare i 20 MB di dimensioni totali della richiesta, utilizza l'API Files per caricare un file immagine da utilizzare nella richiesta.
  • Se utilizzi un esempio di immagine più volte, è più efficiente caricare un file immagine utilizzando l'API File.

Prompt con più immagini

Puoi fornire più immagini in un singolo prompt includendo più oggetti Part di immagini nell'array contents. Possono essere una combinazione di dati in linea (file locali o URL) e riferimenti all'API File.

Python

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

Vai

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

REST

# 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

Ottenere una casella delimitante per un oggetto

I modelli Gemini sono addestrati a identificare gli oggetti in un'immagine e a fornire le coordinate dei relativi riquadri di delimitazione. Le coordinate vengono restituite in base alle dimensioni dell'immagine, con una scala di [0, 1000]. Devi eseguire la descalazione di queste coordinate in base alle dimensioni dell'immagine originale.

Python

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.";

Vai

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."),
}

REST

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

Puoi utilizzare i riquadri di delimitazione per il rilevamento e la localizzazione degli oggetti all'interno di immagini e video. Identificando e delineando con precisione gli oggetti con le caselle delimitanti, puoi sbloccare una vasta gamma di applicazioni e migliorare l'intelligenza dei tuoi progetti.

Vantaggi principali

  • Semplice: integra facilmente le funzionalità di rilevamento degli oggetti nelle tue applicazioni, indipendentemente dalle tue competenze in materia di visione artificiale.
  • Personalizzabile: genera riquadri di selezione in base a istruzioni personalizzate (ad es. "Voglio vedere i riquadri di selezione di tutti gli oggetti verdi in questa immagine"), senza dover addestrare un modello personalizzato.

Dettagli tecnici

  • Input: il prompt e le immagini o gli frame video associati.
  • Output: riquadri di delimitazione nel formato [y_min, x_min, y_max, x_max]. L'angolo superior sinistro è l'origine. Gli assi x e y vanno rispettivamente in orizzontale e in verticale. I valori delle coordinate sono normalizzati in modo da avere come intervallo 0-1000 per ogni immagine.
  • Visualizzazione: gli utenti di AI Studio vedranno le caselle delimitanti tracciate all'interno dell'UI.

Gli sviluppatori Python possono provare il notebook di comprensione spaziale 2D o il notebook sperimentale di indicazione 3D.

Normalizzare le coordinate

Il modello restituisce le coordinate del riquadro di delimitazione nel formato[y_min, x_min, y_max, x_max]. Per convertire queste coordinate normalizzate nelle coordinate in pixel dell'immagine originale:

  1. Dividi ogni coordinata di output per 1000.
  2. Moltiplica le coordinate x per la larghezza dell'immagine originale.
  3. Moltiplica le coordinate Y per l'altezza dell'immagine originale.

Per esplorare esempi più dettagliati di generazione delle coordinate del riquadro di delimitazione e visualizzarle sulle immagini, consulta l'esempio di ricetta del rilevamento degli oggetti.

Segmentazione dell'immagine

A partire dai modelli Gemini 2.5, i modelli Gemini vengono addestrati non solo per rilevare gli elementi, ma anche per segmentarli e fornire una maschera dei loro contorni.

Il modello prevede un elenco JSON, in cui ogni elemento rappresenta una maschera di segmentazione. Ogni elemento ha una scatola delimitante ("box_2d") nel formato [y0, x0, y1, x1] con coordinate normalizzate tra 0 e 1000, un'etichetta ("label") che identifica l'oggetto e infine la maschera di segmentazione all'interno della scatola delimitante, come immagine png con codifica base64 che è una mappa di probabilità con valori compresi tra 0 e 255. La maschera deve essere ridimensionata in modo da corrispondere alle dimensioni della casella delimitante, quindi deve essere spianata in base alla soglia di confidenza (127 per il punto intermedio).

Python

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.
`;    

Vai

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.
    `),
}

REST

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.
'''
Un tavolo con cupcake, con gli oggetti in legno e vetro evidenziati
Maschera degli oggetti in legno e vetro trovati nella foto

Per un esempio più dettagliato, consulta l'esempio di segmentazione nella guida del cookbook.

Formati di immagine supportati

Gemini supporta i seguenti tipi MIME di formato immagine:

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

Dettagli tecnici sulle immagini

  • Limite di file: Gemini 2.5 Pro, 2.0 Flash, 1.5 Pro e 1.5 Flash supportano un massimo di 3600 file immagine per richiesta.
  • Calcolo dei token:
    • Gemini 1.5 Flash e Gemini 1.5 Pro: 258 token se entrambe le dimensioni <= 384 pixel. Le immagini più grandi vengono suddivise in riquadri (riquadro minimo 256 px, massimo 768 px, ridimensionato a 768 x 768), con un costo di 258 token per ogni riquadro.
    • Gemini 2.0 Flash: 258 token se entrambe le dimensioni sono <= 384 pixel. Le immagini più grandi vengono suddivise in riquadri di 768 x 768 pixel, ciascuno dei quali ha un costo di 258 token.
  • Best practice:
    • Assicurati che le immagini siano ruotate correttamente.
    • Utilizza immagini chiare e non sfocate.
    • Quando utilizzi una singola immagine con testo, posiziona il prompt di testo dopo la parte di immagine nell'array contents.

Passaggi successivi

Questa guida mostra come caricare file di immagini e generare output di testo da input di immagini. Per saperne di più, consulta le seguenti risorse:

  • Istruzioni di sistema: le istruzioni di sistema ti consentono di indirizzare il comportamento del modello in base alle tue esigenze e ai tuoi casi d'uso specifici.
  • Comprensione dei video: scopri come utilizzare gli input video.
  • API Files: scopri di più sul caricamento e sulla gestione dei file da utilizzare con Gemini.
  • Strategie di prompt dei file: l'API Gemini supporta i prompt con dati di testo, immagini, audio e video, noti anche come prompt multimodali.
  • Indicazioni per la sicurezza: a volte i modelli di IA generativa producono output inaspettati, ad esempio imprecisi, biassati o offensivi. Il post-trattamento e la valutazione umana sono essenziali per limitare il rischio di danni derivanti da questi output.