Ultralytics YOLO27:
Get Started

Cómo aislar objetos segmentados con Ultralytics YOLO#

La segmentación de instancias genera una máscara precisa a nivel de píxel para cada objeto detectado, lo que te permite extraer cada objeto de una imagen por separado. Esta guía te muestra cómo convertir los resultados de segmentación de Ultralytics YOLO en objetos aislados con Predict Mode y OpenCV, usando un fondo negro sólido o uno transparente para guardarlos como PNG.



Ver: Cómo eliminar el fondo y aislar objetos con la segmentación de Ultralytics YOLO y OpenCV en Python 🚀

¿Por qué aislar objetos segmentados?#

Extraer objetos individuales de una imagen permite llevar a cabo distintos flujos de trabajo posteriores:

  • Eliminación del fondo en imágenes de productos, catálogos o edición creativa.
  • Recortes por objeto para crear conjuntos de datos de clasificación a partir de tus detecciones.
  • Procesamiento focalizado para que los pasos posteriores, como el OCR, el análisis del color o las mediciones, solo procesen el objeto y no la escena que lo rodea.
  • Exportación a PNG transparente para componer objetos sobre fondos nuevos.

La receta funciona con cualquier modelo de segmentación de Ultralytics YOLO y consta de cuatro etapas: ejecutar la inferencia → extraer cada contorno → aislar el objeto → guardar el resultado.

Ejecutar la inferencia de segmentación#

Instala las bibliotecas necesarias y, después, carga un modelo de segmentación (el sufijo -seg, necesario para generar máscaras) y ejecuta la predicción en la imagen de origen:

from ultralytics import YOLO

# Cargar un modelo de segmentación
model = YOLO("yolo26n-seg.pt")

# Ejecutar la inferencia en una imagen de origen
results = model.predict(source="path/to/image.jpg")
¿No tienes una imagen de origen? YOLO usa las imágenes de ejemplo incluidas

Si llamas a model.predict() sin un source, Ultralytics usa las imágenes de ejemplo incluidas en el paquete (bus.jpg y zidane.jpg), algo práctico para probar rápidamente el flujo de trabajo.

Extraer los contornos de los objetos#

Cada elemento de results corresponde a una imagen, y al iterar sobre un resultado se obtiene una detección cada vez. Para cada detección, copia la imagen original, lee la etiqueta de clase y dibuja el contorno de la máscara del objeto sobre una máscara binaria vacía. La región blanca de esta máscara indica exactamente qué píxeles pertenecen al objeto.

Los fragmentos de código de esta sección y de la siguiente se ejecutan dentro del bucle de detección que aparece abajo; encontrarás el script completo, listo para copiar y pegar, en Ejemplo completo.

Binary Mask Image
from pathlib import Path

import cv2
import numpy as np

for r in results:
    img = np.copy(r.orig_img)
    img_name = Path(r.path).stem  # nombre base de la imagen de origen

    # Iterar por cada objeto detectado en la imagen
    for ci, c in enumerate(r):
        label = c.names[c.boxes.cls.tolist().pop()]  # nombre de la clase

        # Crear una máscara binaria y dibujar en ella el contorno del objeto
        b_mask = np.zeros(img.shape[:2], np.uint8)
        contour = c.masks.xy[0].astype(np.int32).reshape(-1, 1, 2)
        cv2.drawContours(b_mask, [contour], -1, (255, 255, 255), cv2.FILLED)
¿Qué hace `c.masks.xy[0].astype(np.int32).reshape(-1, 1, 2)`?
  • c.masks.xy[0] devuelve el contorno de la máscara como coordenadas de puntos (x, y) del objeto en este resultado de una sola detección.
  • .astype(np.int32) convierte los puntos de float32, que drawContours() de OpenCV no acepta.
  • .reshape(-1, 1, 2) reorganiza los puntos según el formato [N, 1, 2] que espera drawContours(), donde N es el número de puntos del contorno.

Al pasar [contour] con el índice -1, se dibujan todos los puntos del contorno proporcionado y cv2.FILLED rellena de blanco todos los píxeles encerrados.

Aislar el objeto#

Con la máscara binaria lista, combínala con la imagen original. Hay dos estilos habituales, según el fondo que quieras:

Elige un estilo de aislamiento

Convierte la máscara a tres canales y conserva solo los píxeles que se solapan con el objeto. Todo lo que quede fuera del contorno se vuelve negro:

# Aislar el objeto con un fondo negro
mask3ch = cv2.cvtColor(b_mask, cv2.COLOR_GRAY2BGR)
isolated = cv2.bitwise_and(mask3ch, img)
Example Full size Isolated Object Image Black Background
Objeto a tamaño completo sobre fondo negro
Recortar al cuadro delimitador

Para conservar solo la región del objeto en lugar de la imagen completa, recórtala según el cuadro delimitador de la detección:

# Coordenadas del cuadro delimitador
x1, y1, x2, y2 = c.boxes.xyxy.cpu().numpy().squeeze().astype(np.int32)
# Recortar la imagen aislada a la región del objeto
iso_crop = isolated[y1:y2, x1:x2]
Example Crop Isolated Object Image Black Background
Objeto recortado al cuadro delimitador
¿Necesitas el recorte con el fondo original?

Ya está integrado. Pasa save_crop=True a predict() y Ultralytics guardará automáticamente los recortes de los cuadros delimitadores, sin necesidad de enmascarar.

Guardar el resultado (opcional)#

Tú decides qué hacer con cada objeto aislado. Un paso habitual es guardarlo en disco para usarlo más adelante:

# Save the isolated object to file
cv2.imwrite(f"{img_name}_{label}-{ci}.png", isolated)

Aquí, img_name es el nombre base de la imagen de origen, label es el nombre de la clase y ci es el índice de detección, de modo que las distintas instancias de una misma clase obtienen nombres de archivo únicos. Sustituye isolated por iso_crop si has aplicado el recorte opcional anterior.

Ejemplo completo#

El siguiente script combina todos los pasos en un único bloque ejecutable. Usa un fondo negro de forma predeterminada; cambia la única línea indicada por np.dstack([img, b_mask]) para obtener un PNG transparente:

from pathlib import Path

import cv2
import numpy as np

from ultralytics import YOLO

model = YOLO("yolo26n-seg.pt")
results = model.predict(source="path/to/image.jpg")

for r in results:
    img = np.copy(r.orig_img)
    img_name = Path(r.path).stem

    for ci, c in enumerate(r):
        label = c.names[c.boxes.cls.tolist().pop()]

        # Build a binary mask from the object contour
        b_mask = np.zeros(img.shape[:2], np.uint8)
        contour = c.masks.xy[0].astype(np.int32).reshape(-1, 1, 2)
        cv2.drawContours(b_mask, [contour], -1, (255, 255, 255), cv2.FILLED)

        # Isolate the object (black background)
        mask3ch = cv2.cvtColor(b_mask, cv2.COLOR_GRAY2BGR)
        isolated = cv2.bitwise_and(mask3ch, img)  # transparent PNG: isolated = np.dstack([img, b_mask])

        # Save or add your custom post-processing here
        cv2.imwrite(f"{img_name}_{label}-{ci}.png", isolated)

        # Optional: crop to the bounding box before saving
        # x1, y1, x2, y2 = c.boxes.xyxy.cpu().numpy().squeeze().astype(np.int32)
        # cv2.imwrite(f"{img_name}_{label}-{ci}.png", isolated[y1:y2, x1:x2])

Si vas a usarlo repetidamente, mete el cuerpo del bucle en una función para poder llamarla con muchas imágenes.

Conclusión#

Ya tienes una receta completa para aislar objetos segmentados con Ultralytics YOLO: ejecuta la inferencia, crea una máscara binaria a partir de cada contorno y, después, extrae el objeto sobre un fondo negro o transparente y, si quieres, recórtalo a su cuadro delimitador. Explora la documentación completa de Segment Task y Predict Mode para adaptar el flujo de trabajo a tus propias clases.

Preguntas frecuentes#

  • Carga un modelo de segmentación, ejecuta la inferencia, crea una máscara binaria a partir del contorno de cada detección y combínala con la imagen original:

    import cv2
    import numpy as np
    
    from ultralytics import YOLO
    
    model = YOLO("yolo26n-seg.pt")
    results = model.predict(source="path/to/your/image.jpg")
    
    img = np.copy(results[0].orig_img)
    b_mask = np.zeros(img.shape[:2], np.uint8)
    contour = results[0].masks.xy[0].astype(np.int32).reshape(-1, 1, 2)
    cv2.drawContours(b_mask, [contour], -1, (255, 255, 255), cv2.FILLED)
    
    mask3ch = cv2.cvtColor(b_mask, cv2.COLOR_GRAY2BGR)
    isolated = cv2.bitwise_and(mask3ch, img)

    Consulta el Ejemplo completo para ver el bucle completo de cada detección.

  • Hay dos estilos principales. Para un fondo negro, convierte la máscara a tres canales y usa cv2.bitwise_and(). Para un fondo transparente (al guardar como PNG), apila la máscara como un cuarto canal alfa con np.dstack([img, b_mask]). Ambos se muestran en Aislar el objeto.

  • Lee las coordenadas del cuadro delimitador de la detección y recorta la imagen aislada:

    x1, y1, x2, y2 = results[0].boxes.xyxy[0].cpu().numpy().astype(np.int32)
    iso_crop = isolated[y1:y2, x1:x2]

    Encontrarás más información sobre los resultados de los cuadros delimitadores en la documentación de Predict Mode.

  • Ultralytics YOLO ofrece segmentación de instancias rápida y en tiempo real, con generación precisa de máscaras y cuadros delimitadores, además de una API de Python sencilla que convierte los resultados de inferencia en objetos aislados con unas pocas líneas de código de OpenCV.

  • Sí. Usa el argumento save_crop en predict() para guardar recortes de cuadros delimitadores con su fondo original:

    results = model.predict(source="path/to/your/image.jpg", save_crop=True)

    Encontrarás más información en la sección Argumentos de inferencia del modo de predicción.

Comentarios