공간 추론

공간 추론 (Spatial reasoning)

Gemini Robotics ER 모델은 객체를 가리키고(포인팅), 비디오에서 객체를 추적하며, 바운딩 박스로 감지하고, 이동 궤적(trajectory)을 생성할 수 있어요.

전체 실행 가능 코드는 Robotics cookbook을 확인하세요.

출처: 원문

본문

객체 가리키기 (Point to objects)

다음 예시는 이미지에서 특정 객체를 찾아 정규화된 [y, x] 좌표를 반환해요:

from google import genai

PROMPT = """
          Point to no more than 10 items in the image. The label returned
          should be an identifying name for the object detected.
          The answer should follow the json format: [{"point": <point>,
          "label": <label1>}, ...]. The points are in [y, x] format
          normalized to 0-1000.
        """
client = genai.Client()

uploaded_file = client.files.upload(file="my-image.png")

image_response = client.interactions.create(
    model="gemini-robotics-er-2-preview",
    input=[
        {
            "type": "image",
            "uri": uploaded_file.uri,
            "mime_type": uploaded_file.mime_type
        },
        {"type": "text", "text": PROMPT}
    ],
    generation_config={"thinking_level": "high"},
)

print(image_response.output_text)
# First, ensure you have the image file locally.
# Encode the image to base64
IMAGE_BASE64=$(base64 -w 0 my-image.png)

curl -X POST \
  "https://generativelanguage.googleapis.com/v1beta/interactions" \
  -H "x-goog-api-key: *** \
  -H "Content-Type: application/json" \
  -d '{
    "model": "gemini-robotics-er-2-preview",
    "input": {
      "parts": [
        {
          "inlineData": {
            "mimeType": "image/png",
            "data": "'"${IMAGE_BASE64}"'"
          }
        },
        {
          "text": "Point to no more than 10 items in the image. The label returned should be an identifying name for the object detected. The answer should follow the json format: [{\"point\": [y, x], \"label\": <label1>}, ...]. The points are in [y, x] format normalized to 0-1000."
        }
      ]
    },
    "generation_config": {
      "thinking_config": {
        "thinking_level": "high"
      }
    }
  }'

출력은 객체를 담은 JSON 배열이에요. 각 객체는 point(정규화된 [y, x] 좌표)와 객체를 식별하는 label을 가져요.

[
  {"point": [376, 508], "label": "small banana"},
  {"point": [287, 609], "label": "larger banana"},
  {"point": [223, 303], "label": "pink starfruit"},
  {"point": [435, 172], "label": "paper bag"},
  {"point": [270, 786], "label": "green plastic bowl"},
  {"point": [488, 775], "label": "metal measuring cup"},
  {"point": [673, 580], "label": "dark blue bowl"},
  {"point": [471, 353], "label": "light blue bowl"},
  {"point": [492, 497], "label": "bread"},
  {"point": [525, 429], "label": "lime"}
]

다음 이미지는 이 포인트들이 어떻게 표시될 수 있는지 보여주는 예시예요:

이미지 속 객체 포인트를 표시한 예시

비디오에서 객체 추적 (Tracking objects in a video)

Gemini Robotics ER 2는 비디오 프레임을 분석해 객체를 시간에 따라 추적할 수도 있어요. 지원되는 비디오 형식 목록은 Video inputs를 참고하세요.

from google import genai

client = genai.Client()

uploaded_file = client.files.upload(file="my-video.mp4")

prompt = """
          Point to the red ball in every frame where it appears.
          The answer should follow the json format: [{"point": [y, x],
          "label": <label>}, ...]. The points are in [y, x] format
          normalized to 0-1000. Return one entry per frame that contains
          the object.
        """

image_response = client.interactions.create(
  model="gemini-robotics-er-2-preview",
  input=[
    {
        "type": "video",
        "uri": uploaded_file.uri,
        "mime_type": uploaded_file.mime_type
    },
    {"type": "text", "text": prompt}
  ],
)

print(image_response.output_text)

객체 감지와 바운딩 박스 (Object detection and bounding boxes)

포인트 외에도 모델에 2D 바운딩 박스를 반환하도록 요청할 수 있어요. 바운딩 박스는 감지된 객체에 대한 더 많은 공간적 세부 정보를 제공하죠.

from google import genai

client = genai.Client()

uploaded_file = client.files.upload(file="my-image.png")

prompt = """
          Detect all objects in this image and return bounding boxes.
          The answer should follow the JSON format:
          [{"label": <label>, "y": <y_min>, "x": <x_min>,
            "y2": <y_max>, "x2": <x_max>}, ...]
          where coordinates are normalized to 0-1000.
        """

image_response = client.interactions.create(
  model="gemini-robotics-er-2-preview",
  input=[
    {
        "type": "image",
        "uri": uploaded_file.uri,
        "mime_type": uploaded_file.mime_type
    },
    {"type": "text", "text": prompt}
  ],
)

print(image_response.output_text)

궤적 (Trajectories)

Gemini Robotics ER 2는 궤적을 정의하는 점들의 시퀀스를 생성할 수 있어요. 로봇 이동을 안내할 때 유용하죠.

이 예시는 빨간 펜을 오거나이저(organizer)로 옮기는 궤적을 요청하며, 중간 웨이포인트의 추정치도 포함해요. 코드는 프롬프트만 보여주도록 줄였어요.

prompt = """
          Generate a trajectory for the robotic arm to pick up the red pen
          and place it in the organizer. Return a list of waypoints as JSON:
          [{"step": <int>, "point": [y, x], "action": <description>}, ...]
          where coordinates are normalized to 0-1000.
        """

노트북 자리 만들기 (Making room for a laptop)

이 예시는 Gemini Robotics ER이 공간을 어떻게 추론하는지 보여줘요. 프롬프트는 다른 아이템을 위한 공간을 만들기 위해 어떤 객체를 옮겨야 하는지 식별하도록 모델에 요청해요.

from google import genai

client = genai.Client()

uploaded_file = client.files.upload(file="path/to/image-with-objects.jpg")

prompt = """
          Point to the object that I need to remove to make room for my laptop
          The answer should follow the JSON format: [{"point": <point>,
          "label": <label1>}, ...]. The points are in [y, x] format normalized to 0-1000.
        """

image_response = client.interactions.create(
  model="gemini-robotics-er-2-preview",
  input=[
    {
        "type": "image",
        "uri": uploaded_file.uri,
        "mime_type": uploaded_file.mime_type
    },
    {"type": "text", "text": prompt}
  ],
)

print(image_response.output_text)

응답에는 사용자 질문에 답하는 객체의 2D 좌표가 들어 있어요. 이 경우엔 노트북을 위한 공간을 만들기 위해 옮겨야 하는 객체죠.

[ { "point" : [ 672 , 301 ], "label" : "The object that I need to remove to make room for my laptop" } ]

다른 객체를 위해 어떤 객체를 옮겨야 하는지 보여주는 예시

점심 싸기 (Packing a lunch)

모델은 다단계 작업에 대한 지시를 제공하고 각 단계의 관련 객체를 가리킬 수도 있어요. 이 예시는 점심 가방을 싸는 일련의 단계를 모델이 계획하는 방법을 보여줘요.

from google import genai

client = genai.Client()

uploaded_file = client.files.upload(file="path/to/image-of-lunch.jpg")

prompt = """
          Explain how to pack the lunch box and lunch bag. Point to each
          object that you refer to. Each point should be in the format:
          [{"point": [y, x], "label": }], where the coordinates are
          normalized between 0-1000.
        """

image_response = client.interactions.create(
  model="gemini-robotics-er-2-preview",
  input=[
    {
        "type": "image",
        "uri": uploaded_file.uri,
        "mime_type": uploaded_file.mime_type
    },
    {"type": "text", "text": prompt}
  ],
)

print(image_response.output_text)

이 프롬프트의 응답은 이미지 입력에서 점심 가방을 싸는 방법에 대한 단계별 지시의 집합이에요.

입력 이미지

점심 상자와 그 안에 넣을 아이템 이미지

모델 출력

이미지에 기반해 점심 상자와 가방을 싸는 계획은 이렇습니다:

  1. 과일을 점심 상자에 담으세요. 사과, 바나나, [빨간 포도](red grapes), [초록 포도](green grapes)를 [파란 점심 상자](blue lunch box)에 넣으세요.
  2. 숟가락을 점심 상자에 추가하세요. [파란 숟가락](blue spoon)도 점심 상자 안에 넣으세요.
  3. 점심 상자를 닫으세요. [파란 점심 상자](blue lunch box)의 뚜껑을 고정하세요.
  4. 점심 상자를 점심 가방 안에 넣으세요. 닫힌 [파란 점심 상자](blue lunch box)를 [갈색 점심 가방](brown lunch bag)에 넣으세요.
  5. 남은 아이템을 점심 가방에 싸세요. [파란 스낵 바](blue snack bar)와 [갈색 스낵 바](brown snack bar)를 [갈색 점심 가방](brown lunch bag)에 넣으세요.

객체와 위치 목록은 다음과 같아요:

  • [{"point": [899, 440], "label": "apple"}]
  • [{"point": [814, 363], "label": "banana"}]
  • [{"point": [727, 470], "label": "red grapes"}]
  • [{"point": [675, 608], "label": "green grapes"}]
  • [{"point": [706, 529], "label": "blue lunch box"}]
  • [{"point": [864, 517], "label": "blue spoon"}]
  • [{"point": [499, 401], "label": "blue snack bar"}]
  • [{"point": [614, 705], "label": "brown snack bar"}]
  • [{"point": [448, 501], "label": "brown lunch bag"}]

다음 단계 (What's next)

더 알아보기 (Learn more)