Skip to content

Anotación de imágenes

Configura la anotación de imágenes en Potato con cuadros delimitadores, polígonos, máscaras y puntos de referencia. Muestra imágenes con instance_display y exporta a COCO o YOLO.

Potato admite la anotación de imágenes para tareas de clasificación, detección de objetos, segmentación y puntos clave.

Mostrar una imagen

Mostrar una imagen y recoger una anotación son dos ajustes distintos. instance_display indica lo que ve el anotador y annotation_schemes indica lo que responde. Al mantenerlos separados, cualquier tipo de contenido puede combinarse con cualquier tipo de pregunta:

yaml
instance_display:
  fields:
    - key: image_url          # Field name in your data file
      type: image
      label: "Image to classify"
      display_options:
        max_width: 600
        zoomable: true

El esquema image_annotation sirve para dibujar sobre una imagen, no para mostrarla. Una tarea de clasificación solo necesita el campo de visualización de arriba más un esquema radio o multiselect.

Opciones de visualización

OpciónDescripción
max_widthAncho máximo de renderizado en píxeles
max_heightAlto máximo de renderizado en píxeles
zoomableActiva el zoom al hacer clic
object_fitCómo llena la imagen su recuadro
alt_textTexto alternativo para lectores de pantalla

Un nombre de opción que Potato no reconoce es un error de configuración, no una clave que se ignora en silencio, y el mensaje sugiere la opción real más cercana.

Formato de datos

Referencia las imágenes en tu archivo de datos:

json
{"id": "img_001", "image_url": "https://example.com/photo_001.jpg"}
{"id": "img_002", "image_url": "/static/images/photo_002.png"}

data_files es una lista de rutas, e item_properties asigna tus nombres de campo a los que lee Potato:

yaml
data_files:
  - "data/image_tasks.json"
 
item_properties:
  id_key: id
  text_key: image_url   # The field holding the image URL

Clasificación de imágenes

Clasifica imágenes completas:

yaml
annotation_schemes:
  - annotation_type: radio
    name: category
    description: "What is shown in this image?"
    labels:
      - Cat
      - Dog
      - Bird
      - Other
 
  - annotation_type: multiselect
    name: attributes
    description: "Select all that apply"
    labels:
      - Indoor
      - Outdoor
      - Multiple animals
      - Human present

Clasificación multietiqueta

yaml
annotation_schemes:
  - annotation_type: multiselect
    name: objects
    description: "What objects are visible?"
    labels:
      - Person
      - Car
      - Building
      - Tree
      - Animal
      - Furniture
      - Food
      - Electronic device

Evaluación de la calidad de imagen

yaml
annotation_schemes:
  - annotation_type: likert
    name: quality
    description: "Overall image quality"
    size: 5
    min_label: "Very poor"
    max_label: "Excellent"
 
  - annotation_type: multiselect
    name: issues
    description: "Select any quality issues"
    labels:
      - Blurry
      - Overexposed
      - Underexposed
      - Noisy
      - Low resolution
      - Watermark visible

Dibujar sobre imágenes

El esquema image_annotation requiere tanto tools como labels. Merece la pena añadir a cada etiqueta un color y un key_value, porque los anotadores asignan etiquetas con el teclado mucho más rápido que con clics:

yaml
annotation_schemes:
  - annotation_type: image_annotation
    name: object_detection
    description: "Draw boxes around objects"
    tools:
      - bbox
      - polygon
    labels:
      - name: person
        color: "#FF6B6B"
        key_value: "1"
      - name: vehicle
        color: "#4ECDC4"
        key_value: "2"
      - name: animal
        color: "#45B7D1"
        key_value: "3"
    min_annotations: 1
    zoom_enabled: true
    pan_enabled: true

color debe ser hexadecimal (#rgb, #rrggbb o #rrggbbaa). Los nombres de color CSS y rgb() no se leen. Las formas se verían bien, pero las máscaras se pintan píxel a píxel y recurren al rojo.

Herramientas disponibles

HerramientaDescripción
bboxCuadros delimitadores rectangulares
polygonPolígonos cerrados de varios puntos
polylineTrazados abiertos de varios puntos, para marcas de carril, vasos sanguíneos, grietas o líneas de costa
ellipseElipses y círculos, para células, núcleos, ruedas o caras
keypoint_setEsqueletos ordenados, para la pose humana o animal y los puntos faciales
cuboid_2dCajas 3D proyectadas en la imagen, al estilo de KITTI
samVarita mágica: haces clic en un objeto y un modelo lo segmenta
freeformDibujo a mano alzada
landmarkMarcadores de un solo punto
brushPincel de segmentación para máscaras a nivel de píxel
eraserBorra regiones de la máscara
fillRelleno por inundación para regiones cerradas

Un polígono es cerrado y encierra un área. Una polilínea es abierta y tiene longitud pero no interior. La diferencia importa al exportar, donde una polilínea se escribe con area: 0 y nunca se trata como una región.

Anotación con polígonos

Para regiones no rectangulares:

yaml
annotation_schemes:
  - annotation_type: image_annotation
    name: regions
    description: "Outline regions of interest"
    tools:
      - polygon
    labels:
      - name: Building
      - name: Road
      - name: Vegetation
      - name: Water

Máscaras de segmentación

Para trabajar a nivel de píxel, activa las herramientas de pintura. Las máscaras se guardan con codificación por longitud de series (run-length encoding) en lugar de como matrices por píxel, y eso es lo que mantiene pequeña una máscara de la imagen completa:

yaml
annotation_schemes:
  - annotation_type: image_annotation
    name: segmentation
    description: "Paint regions using the brush tool"
    tools:
      - brush
      - eraser
      - fill
    labels:
      - name: road
        color: "#45B7D1"
      - name: sidewalk
        color: "#96CEB4"
    brush_size: 20
    mask_opacity: 0.5
    mask_mode: semantic

mask_mode: semantic fusiona todos los trazos de una clase en una sola región. Usa instance cuando dos objetos de la misma clase deban mantenerse separados.

Formato de salida

Las anotaciones se guardan como un array JSON plano, con todas las formas y máscaras en la misma lista. Las coordenadas se normalizan al rango de 0 a 1 respecto a la imagen, así que las anotaciones siguen siendo correctas cuando la imagen se sirve a otro tamaño:

json
[
  {
    "type": "bbox",
    "label": "person",
    "color": "#FF6B6B",
    "coordinates": {"x": 0.125, "y": 0.104, "width": 0.3125, "height": 0.625}
  },
  {
    "type": "polygon",
    "label": "vehicle",
    "color": "#4ECDC4",
    "coordinates": [
      {"x": 0.02, "y": 0.04}, {"x": 0.20, "y": 0.04},
      {"x": 0.20, "y": 0.21}, {"x": 0.02, "y": 0.21}
    ]
  },
  {
    "type": "mask",
    "label": "road",
    "color": "#45B7D1",
    "rle": {"counts": [12, 40, 8], "size": [480, 640]}
  }
]

La clave de geometría depende del tipo:

TipoClave de geometríaForma
bboxcoordinates{x, y, width, height}, normalizado
polygoncoordinateslista de {x, y}, normalizados
landmarkcoordinates{x, y}, normalizado
freeformcoordinates{path, left, top, scaleX, scaleY}
maskrle{counts: [ints], size: [height, width]}

rle.size es [height, width], en ese orden. Para convertir desde y hacia estas formas en Python, usa normalize_annotation_object() y to_client_object() de potato.export.cv_utils en lugar de leer los campos directamente.

De dónde viene una forma

Una detección del modelo aceptada y un cuadro dibujado a mano son idénticos una vez guardados, así que cada forma registra su propio origen. Sin eso, un proyecto que preetiqueta con un modelo no puede calcular su propia tasa de aceptación a partir de sus propios datos:

json
{
  "type": "bbox",
  "label": "person",
  "coordinates": {"x": 0.125, "y": 0.104, "width": 0.3125, "height": 0.625},
  "source": "ai",
  "ai_model": "yolov8n",
  "confidence": 0.82,
  "edited": true
}
ClaveSignificado
sourcehuman (dibujada en el navegador), ai (la propuso un modelo y el anotador la aceptó), import (llegó con los datos)
ai_modelQué modelo, cuando el endpoint lo indica
confidenceLa puntuación que el propio detector asignó a esta forma
editedEl anotador ha movido, redimensionado o reetiquetado después una forma que no era suya
carried_overCopiada desde la imagen anterior en lugar de creada en esta

edited es lo que distingue aceptar un cuadro tal cual de aceptarlo y luego corregirlo. Solo lo primero es acuerdo con el modelo.

Revisar anotaciones existentes

Para revisar formas que ya existen, impórtalas en lugar de añadirlas a un campo de datos. potato import convierte un archivo COCO en un proyecto listo para ejecutar y marca cada forma con source: import:

bash
potato import --input instances_val2017.json \
    --image-dir /data/val2017 \
    --image-url-prefix /files \
    --output-dir my-project/ \
    --schema-name object_detection
 
potato start my-project/config.yaml -p 8000

Después, los anotadores corrigen las formas importadas en el sitio, y la exportación conserva la división entre humano y modelo a lo largo de todo el recorrido.

Comparación de imágenes

Compara dos imágenes con el esquema pairwise. items_key indica el campo de datos que contiene el par:

yaml
annotation_schemes:
  - annotation_type: pairwise
    name: preference
    description: "Which image looks better?"
    mode: binary
    items_key: images
    show_labels: true
    labels:
      - "Original"
      - "Edited"
    allow_tie: true
    tie_label: "About the same"

Descripción de imágenes

yaml
annotation_schemes:
  - annotation_type: text
    name: caption
    description: "Write a caption for this image"
    rows: 4
    placeholder: "Describe what you see..."

Revisión de la calidad de las descripciones

Muestra la imagen y la descripción generada una junto a otra y luego valora la descripción:

yaml
instance_display:
  fields:
    - key: image_url
      type: image
      label: "Image"
    - key: generated_caption
      type: text
      label: "Generated caption"
 
annotation_schemes:
  - annotation_type: likert
    name: accuracy
    description: "How accurate is this caption?"
    size: 5
    min_label: "Very inaccurate"
    max_label: "Very accurate"
 
  - annotation_type: likert
    name: fluency
    description: "How natural is the language?"
    size: 5
    min_label: "Very awkward"
    max_label: "Very natural"
 
  - annotation_type: text
    name: improved_caption
    description: "Suggest a better caption (optional)"
    rows: 4
    label_requirement:
      required: false

Moderación de contenido

yaml
annotation_schemes:
  - annotation_type: radio
    name: safe_for_work
    description: "Is this image safe for work?"
    labels:
      - Safe
      - Questionable
      - Not Safe
 
  - annotation_type: multiselect
    name: violation_types
    description: "Select all violations (if any)"
    labels:
      - Violence
      - Adult content
      - Hate symbols
      - Graphic content
      - Spam/advertisement

Formatos de intercambio

Potato lee COCO JSON, incluidas todas las codificaciones de segmentación y las regiones de multitud (crowd), y escribe COCO, YOLO, Pascal VOC y PNG de máscara por etiqueta:

bash
python -m potato.export -c my-project/config.yaml -f coco -o ./export/

YOLO y Pascal VOC solo admiten cuadros delimitadores, así que las demás formas se reducen a su cuadro envolvente.

Ejemplo completo: revisión de detección de objetos

yaml
annotation_task_name: "Object Detection Verification"
task_dir: "."
 
data_files:
  - "data/detections.json"
 
item_properties:
  id_key: id
  text_key: image_url
 
instance_display:
  fields:
    - key: image_url
      type: image
      label: "Image"
      display_options:
        max_width: 1000
        zoomable: true
 
annotation_schemes:
  # Correct the boxes
  - annotation_type: image_annotation
    name: objects
    description: "Verify and correct object boxes"
    tools:
      - bbox
    labels:
      - name: Person
        key_value: "1"
      - name: Vehicle
        key_value: "2"
      - name: Animal
        key_value: "3"
      - name: Object
        key_value: "4"
    zoom_enabled: true
    pan_enabled: true
 
  # Overall assessment
  - annotation_type: radio
    name: prediction_quality
    description: "How accurate were the predictions?"
    labels:
      - All correct
      - Minor corrections needed
      - Major corrections needed
      - Mostly incorrect
 
  - annotation_type: number
    name: missed_objects
    description: "How many objects were missed?"
    min: 0
    max: 50
 
  - annotation_type: text
    name: notes
    description: "Any issues or comments?"
    rows: 4
    label_requirement:
      required: false
 
output_annotation_dir: "output/"
export_annotation_format: jsonl
 
user_config:
  allow_all_users: true

Inicia el servidor:

bash
potato start config.yaml -p 8000

Consejos de rendimiento

  1. Redimensiona antes de anotar: las imágenes de origen grandes ralentizan la carga sin mejorar la anotación
  2. Usa JPEG para fotos: archivos más pequeños, carga más rápida
  3. Usa PNG para gráficos: mejor calidad para diagramas y capturas de pantalla
  4. Limita el tamaño de renderizado: define max_width para que el navegador no tenga que escalar una imagen enorme en cada instancia
  5. Preprocesa de forma coherente: normaliza tamaños y formatos en todo el conjunto de datos