Skip to content
Tutoriales8 min de lectura

Dibujando Cuadros Delimitadores para Detección de Objetos

Crea una tarea de detección de objetos en Potato, desde una configuración inicial con tres etiquetas hasta una de producción para grabaciones de conducción, y exporta a COCO o YOLO.

Potato Team

Este tutorial construye una tarea de anotación para detección de objetos en Potato, desde una configuración con tres etiquetas hasta la exportación COCO o YOLO con la que se entrena un detector. Para ver la lista completa de herramientas de imagen y sus opciones, consulta la documentación de anotación de imágenes.

El Archivo de Datos

Cada línea del archivo de datos es una imagen. Potato necesita un identificador y un campo con la URL o la ruta de la imagen, y item_properties indica qué campo es cada uno:

json
{"id": "img_001", "image_url": "https://example.com/street_001.jpg"}
{"id": "img_002", "image_url": "/static/images/street_002.jpg"}

Una ruta relativa se resuelve contra media_directory, así que las imágenes locales no necesitan un servidor de archivos en marcha.

Una Configuración Mínima

El esquema image_annotation controla la superficie de dibujo. Necesita un nombre, una descripción que los anotadores leen como instrucción, las herramientas que se activan y el conjunto de etiquetas:

yaml
annotation_task_name: "Object Detection Annotation"
task_dir: "."
output_annotation_dir: "annotation_output/"
 
data_files:
  - "data/images.json"
 
item_properties:
  id_key: id
  text_key: image_url
 
annotation_schemes:
  - annotation_type: image_annotation
    name: objects
    description: "Draw a box around every car, person, and bicycle"
    tools:
      - bbox
    labels:
      - name: car
        color: "#FF6B6B"
      - name: person
        color: "#4ECDC4"
      - name: bicycle
        color: "#45B7D1"

Tres etiquetas es un punto de partida deliberado. Cada etiqueta que añades es una decisión que el anotador tiene que tomar en cada objeto, y un caso límite cuya resolución hay que explicarle, así que empieza con las clases que el modelo realmente necesita y añade el resto cuando las pautas se sostengan.

Inicia el servidor y abre la tarea:

bash
potato start config.yaml -p 8000

Lo Que Hace el Anotador

El anotador elige una etiqueta y luego arrastra un rectángulo alrededor de cada objeto, ajustando las esquinas hasta que el cuadro quede ceñido:

Interfaz de anotación de cuadros delimitadores para detección de objetosLa herramienta de cuadros delimitadores permite a los anotadores dibujar y etiquetar regiones rectangulares en imágenes

El zoom y el desplazamiento están activados por defecto, lo que importa con objetos pequeños o lejanos. Ambos se pueden desactivar con zoom_enabled: false y pan_enabled: false cuando las imágenes son uniformes y los controles adicionales solo estorban.

Atajos de Etiquetas

Con el perfil de teclas predeterminado v7, las herramientas usan teclas de letras: r selecciona la herramienta de cuadro, p el polígono y b el pincel. Los atajos de etiqueta se definen para cada etiqueta con key_value, y los dígitos son la opción segura, porque una etiqueta cuyo key_value coincide con una tecla de herramienta dispara las dos acciones a la vez:

yaml
annotation_schemes:
  - annotation_type: image_annotation
    name: objects
    description: "Annotate all visible objects"
    tools:
      - bbox
    labels:
      - name: person
        color: "#FF6B6B"
        key_value: "1"
 
      - name: car
        color: "#4ECDC4"
        key_value: "2"
 
      - name: motorcycle
        color: "#45B7D1"
        key_value: "3"
 
      - name: bicycle
        color: "#96CEB4"
        key_value: "4"
 
      - name: traffic_light
        color: "#FFEAA7"
        key_value: "5"
 
      - name: stop_sign
        color: "#DDA0DD"
        key_value: "6"

Vale la pena elegir los colores en lugar de aceptar los que vienen. En escenas de tráfico densas el anotador recorre la imagen buscando lo que se le ha escapado, y dos colores parecidos en clases contiguas hacen ese recorrido más lento. Usa keybinding_profile: legacy si tus anotadores aprendieron las teclas de Potato anteriores a la 2.8 y prefieres no volver a entrenarlos.

Agregar Atributos de Objeto

Potato no tiene un bloque de atributos por cuadro. De una etiqueta de image_annotation se leen name, color y key_value, y todo lo demás en el diccionario de la etiqueta se descarta, así que una lista anidada attributes: no hace nada y no aparece ninguna pregunta después de dibujar un cuadro.

Hay dos maneras de capturar la misma información. Puedes incorporar la distinción al conjunto de etiquetas, de modo que el atributo forme parte de lo que el anotador elige:

yaml
annotation_schemes:
  - annotation_type: image_annotation
    name: objects
    description: "Draw a box around each object"
    tools:
      - bbox
    labels:
      - name: person
        color: "#FF6B6B"
      - name: person_occluded
        color: "#C44536"

O puedes preguntar por la imagen en su conjunto con un segundo esquema. Eso se aplica al elemento y no a un cuadro concreto, y ese es el precio: sabes que algo en la imagen estaba ocluido, pero no qué cuadro era:

yaml
  - annotation_type: multiselect
    name: image_conditions
    description: "Conditions affecting this image"
    labels:
      - Heavy occlusion
      - Truncated objects
      - Low light

Importar desde VIA es el único caso en que los atributos se conservan. via_importer lee los region_attributes de cada región y los incorpora a la etiqueta. Es un concepto del momento de importación, no de la configuración.

Exigir al Menos un Cuadro

Una imagen sin cuadros es ambigua, porque puede significar que el anotador no encontró nada o que se saltó el elemento. min_annotations obliga a distinguir ambos casos rechazando un envío con menos formas que el mínimo, de modo que una imagen realmente vacía necesita una etiqueta negativa explícita:

yaml
annotation_schemes:
  - annotation_type: image_annotation
    name: objects
    description: "Draw a box around every traffic participant"
    tools:
      - bbox
    labels: [...]
    min_annotations: 1

Controlar el Tamaño con que se Muestra la Imagen

La superficie de dibujo sigue a la imagen renderizada, así que una imagen que se muestra pequeña le da al anotador un lienzo pequeño. instance_display fija el tamaño, y el zoom sigue disponible para el trabajo de detalle:

yaml
instance_display:
  fields:
    - key: image_url
      type: image
      label: "Frame"
      display_options:
        max_width: 1200
        max_height: 800
        zoomable: true

Una Configuración de Producción

La configuración de conducción de abajo incluye las cinco clases que necesita un conjunto de datos de detección. Las etiquetas mantienen atajos numéricos para que la mano izquierda del anotador se quede en la fila de números, y min_annotations: 1 se cumple porque cada fotograma de este corpus contiene al menos un participante del tráfico:

yaml
annotation_task_name: "Autonomous Driving - Object Detection"
task_dir: "."
output_annotation_dir: "annotation_output/"
 
data_files:
  - "data/driving_frames.json"
 
item_properties:
  id_key: id
  text_key: frame_path
 
annotation_schemes:
  - annotation_type: image_annotation
    name: objects
    description: "Annotate all traffic participants and objects"
    tools:
      - bbox
    min_annotations: 1
    labels:
      - name: vehicle
        color: "#FF6B6B"
        key_value: "1"
 
      - name: pedestrian
        color: "#4ECDC4"
        key_value: "2"
 
      - name: cyclist
        color: "#45B7D1"
        key_value: "3"
 
      - name: traffic_sign
        color: "#FFEAA7"
        key_value: "4"
 
      - name: traffic_light
        color: "#DDA0DD"
        key_value: "5"

Cinco clases ya están en el límite de lo que los atajos numéricos cubren con comodidad. Por encima de diez, el anotador busca teclas en lugar de leer el fotograma, y a partir de ahí conviene dividir la tarea en dos antes que añadir otra etiqueta.

Cómo Son las Anotaciones

Potato guarda todas las formas de una imagen en un array JSON plano, sea cual sea la herramienta que las dibujó. Las coordenadas se normalizan al rango de 0 a 1 respecto a la imagen, de modo que las anotaciones siguen siendo correctas si más tarde la imagen se sirve con otro tamaño:

json
[
  {
    "type": "bbox",
    "label": "vehicle",
    "color": "#FF6B6B",
    "coordinates": {"x": 0.234, "y": 0.352, "width": 0.120, "height": 0.130}
  },
  {
    "type": "bbox",
    "label": "pedestrian",
    "color": "#4ECDC4",
    "coordinates": {"x": 0.427, "y": 0.370, "width": 0.026, "height": 0.139}
  }
]

Un bbox lleva su geometría en coordinates como {x, y, width, height}. Los polígonos llevan una lista de puntos bajo la misma clave, y las máscaras llevan codificación run-length bajo rle.

Exportar para Entrenamiento

El código de entrenamiento de detectores lee COCO o YOLO, y Potato escribe ambos:

bash
python -m potato.export --config config.yaml --format coco --output ./export/
python -m potato.export --config config.yaml --format yolo --output ./export/

Las dos exportaciones difieren en algo más que la sintaxis. COCO escribe un único annotations.json con cuadros en píxeles como [x, y, width, height], y no copia las imágenes, así que los valores de file_name apuntan a donde ya estén las imágenes. YOLO escribe un archivo de texto por imagen con coordenadas del centro normalizadas, separa imágenes y etiquetas en directorios train/ y val/, y añade data.yaml y classes.txt para que un entrenamiento pueda leer la lista de clases sin que haya que indicársela aparte.

Mantener la Consistencia de los Cuadros

Dibuja los cuadros ceñidos al objeto, porque cada píxel de fondo dentro del cuadro es un píxel que el modelo aprende a llamar primer plano. Deja por escrito cómo tratar los casos difíciles (oclusión, objetos cortados en el borde del fotograma, reflejos) y revisa juntos un lote de ejemplos durante la primera semana, mientras cambiar la pauta todavía cuesta poco. Vigila el número de cuadros y la distribución de tamaños por anotador mientras avanza el estudio, porque un cambio repentino suele significar que una persona ha empezado a interpretar una regla de otra manera, no que hayan cambiado las imágenes.

Próximos Pasos

Para el resto de opciones de imagen, consulta Anotación de Imágenes.