Aislar objetos de segmentación
Tras realizar la Tarea Segmento, a veces es conveniente extraer los objetos aislados de los resultados de la inferencia. Esta guía proporciona una receta genérica sobre cómo lograrlo utilizando elModo Predecir de Ultralytics .
Recorrido por las recetas
Consulta la sección Instalación rápida deUltralytics para obtener una guía rápida sobre la instalación de las bibliotecas necesarias.
Carga un modelo y ejecútalo
predict()
en una fuente.from ultralytics import YOLO # Load a model model = YOLO("yolo11n-seg.pt") # Run inference results = model.predict()
¿No hay argumentos de predicción?
Sin especificar una fuente, se utilizarán las imágenes de ejemplo de la biblioteca:
Esto es útil para realizar pruebas rápidas con el
predict()
método.Para obtener información adicional sobre los Modelos de Segmentación, visita la página Segmento Tarea página. Para saber más sobre
predict()
ver Modo Predecir de la Documentación.Ahora itera sobre los resultados y los contornos. Para los flujos de trabajo que quieren guardar una imagen en un archivo, la imagen de origen
base-name
y la detecciónclass-label
se recuperan para su uso posterior (opcional).from pathlib import Path import numpy as np # (2) Iterate detection results (helpful for multiple images) for r in res: img = np.copy(r.orig_img) img_name = Path(r.path).stem # source image base-name # Iterate each object contour (multiple detections) for ci, c in enumerate(r): # (1) Get detection class name label = c.names[c.boxes.cls.tolist().pop()]
- Para saber más sobre cómo trabajar con los resultados de la detección, consulta la Sección de recuadros para el modo Predecir.
- Para saber más sobre
predict()
resultados ver Trabajar con los resultados del modo Predecir
Bucle For
Una sola imagen sólo iterará el primer bucle una vez. Una sola imagen con una sola detección iterará cada bucle sólo una vez.
Empieza por generar una máscara binaria a partir de la imagen de origen y luego dibuja un contorno relleno sobre la máscara. Esto permitirá aislar el objeto de las demás partes de la imagen. Un ejemplo de
bus.jpg
para uno de los detectadosperson
se muestra a la derecha.import cv2 # Create binary mask b_mask = np.zeros(img.shape[:2], np.uint8) # (1) Extract contour result contour = c.masks.xy.pop() # (2) Changing the type contour = contour.astype(np.int32) # (3) Reshaping contour = contour.reshape(-1, 1, 2) # Draw contour onto mask _ = cv2.drawContours(b_mask, [contour], -1, (255, 255, 255), cv2.FILLED)
Para más información sobre
c.masks.xy
consulta Sección Máscaras del modo Predecir.Aquí los valores se introducen en
np.int32
para compatibilidad condrawContours()
función de OpenCV.El OpenCV
drawContours()
espera que los contornos tengan una forma de[N, 1, 2]
amplía la sección de abajo para más detalles.
Ampliar para comprender lo que ocurre al definir la
contour
variable.c.masks.xy
:: Proporciona las coordenadas de los puntos del contorno de la máscara en el formato(x, y)
. Para más detalles, consulta Sección Máscaras del modo Predecir..pop()
:: Comomasks.xy
es una lista que contiene un solo elemento, este elemento se extrae utilizando la funciónpop()
método..astype(np.int32)
:: Utilizandomasks.xy
devolverá con un tipo de datos defloat32
pero esto no será compatible con el OpenCVdrawContours()
así que esto cambiará el tipo de datos aint32
para la compatibilidad..reshape(-1, 1, 2)
:: Reformatea los datos en la forma requerida de[N, 1, 2]
dondeN
es el número de puntos del contorno, con cada punto representado por una única entrada1
y la entrada se compone de2
valores. En-1
denota que el número de valores a lo largo de esta dimensión es flexible.
Ampliar para una explicación de la
drawContours()
configuración.Encapsular la
contour
variable entre corchetes,[contour]
generó eficazmente la máscara de contorno deseada durante las pruebas.El valor
-1
especificado para eldrawContours()
indica a la función que dibuje todos los contornos presentes en la imagen.En
tuple
(255, 255, 255)
representa el color blanco, que es el color deseado para dibujar el contorno en esta máscara binaria.La adición de
cv2.FILLED
coloreará todos los píxeles encerrados por el límite del contorno de la misma manera, en este caso, todos los píxeles encerrados serán blancos.Consulta Documentación de OpenCV en
drawContours()
para más información.
A continuación hay 2 opciones sobre cómo avanzar con la imagen a partir de este punto y una opción posterior para cada una.
Opciones de aislamiento de objetos
Ejemplo
# Create 3-channel mask mask3ch = cv2.cvtColor(b_mask, cv2.COLOR_GRAY2BGR) # Isolate object with binary mask isolated = cv2.bitwise_and(mask3ch, img)
¿Cómo funciona?
En primer lugar, la máscara binaria se convierte de una imagen de un solo canal a una imagen de tres canales. Esta conversión es necesaria para el paso posterior en el que se combinan la máscara y la imagen original. Ambas imágenes deben tener el mismo número de canales para que sean compatibles con la operación de mezcla.
La imagen original y la máscara binaria de tres canales se fusionan utilizando la función OpenCV
bitwise_and()
. Esta operación conserva sólo valores de píxel mayores que cero(> 0)
de ambas imágenes. Como los píxeles de la máscara son mayores que cero(> 0)
sólo dentro de la región del contorno, los píxeles que quedan de la imagen original son los que se solapan con el contorno.
Aislar con píxeles negros: Subopciones
Imagen a tamaño completo
No se requieren pasos adicionales si mantienes la imagen a tamaño completo.
Objeto recortado Imagen
Pasos adicionales necesarios para recortar la imagen de modo que sólo incluya la región del objeto.
# (1) Bounding box coordinates x1, y1, x2, y2 = c.boxes.xyxy.cpu().numpy().squeeze().astype(np.int32) # Crop image to object region iso_crop = isolated[y1:y2, x1:x2]
- Para más información sobre los resultados de los recuadros delimitadores, consulta la sección Recuadros del modo Predecir
¿Qué hace este código?
En
c.boxes.xyxy.cpu().numpy()
recupera los recuadros delimitadores como una matriz NumPy en la funciónxyxy
formato, dondexmin
,ymin
,xmax
yymax
representan las coordenadas del rectángulo de la caja delimitadora. Consulta Sección Cajas del Modo Predecir para más detalles.En
squeeze()
elimina cualquier dimensión innecesaria de la matriz NumPy, garantizando que tenga la forma esperada.Convertir los valores de las coordenadas mediante
.astype(np.int32)
cambia el tipo de datos de las coordenadas de la casilla defloat32
aint32
haciéndolas compatibles para el recorte de imágenes mediante cortes índice.Por último, la región del cuadro delimitador se recorta de la imagen mediante el corte de índice. Los límites se definen mediante la función
[ymin:ymax, xmin:xmax]
coordenadas del cuadro delimitador de la detección.
# Isolate object with transparent background (when saved as PNG) isolated = np.dstack([img, b_mask])
¿Cómo funciona?
- Utilizar NumPy
dstack()
(apilamiento de matrices a lo largo del eje de profundidad) junto con la máscara binaria generada, creará una imagen con cuatro canales. Esto permite que todos los píxeles fuera del contorno del objeto sean transparentes al guardarlos como unPNG
archivo.
Aislar con píxeles transparentes: Subopciones
Imagen a tamaño completo
No se requieren pasos adicionales si mantienes la imagen a tamaño completo.
Objeto recortado Imagen
Pasos adicionales necesarios para recortar la imagen de modo que sólo incluya la región del objeto.
# (1) Bounding box coordinates x1, y1, x2, y2 = c.boxes.xyxy.cpu().numpy().squeeze().astype(np.int32) # Crop image to object region iso_crop = isolated[y1:y2, x1:x2]
- Para más información sobre los resultados de los recuadros delimitadores, consulta la sección Recuadros del modo Predecir
¿Qué hace este código?
Al utilizar
c.boxes.xyxy.cpu().numpy()
las cajas delimitadoras se devuelven como una matriz NumPy, utilizando la funciónxyxy
formato de coordenadas de casilla, que corresponden a los puntosxmin, ymin, xmax, ymax
para el cuadro delimitador (rectángulo), véase Sección Cajas del Modo Predecir para más información.Añadir
squeeze()
garantiza que se elimine cualquier dimensión extraña de la matriz NumPy.Convertir los valores de las coordenadas mediante
.astype(np.int32)
cambia el tipo de datos de las coordenadas de la casilla defloat32
aint32
que será compatible al recortar la imagen mediante cortes índice.Por último, la región de la imagen para el cuadro delimitador se recorta mediante el corte de índice, en el que los límites se establecen mediante la función
[ymin:ymax, xmin:xmax]
coordenadas del cuadro delimitador de la detección.
¿Y si quiero el objeto recortado incluyendo el fondo?
Se trata de una función integrada en la biblioteca Ultralytics . Consulta la página
save_crop
argumento para Argumentos de Inferencia del Modo Predecir para más detalles.Lo que se haga a continuación depende totalmente de ti como desarrollador. Se muestra un ejemplo básico de un posible paso siguiente (guardar la imagen en un archivo para utilizarla en el futuro).
- NOTA: este paso es opcional y puedes omitirlo si no es necesario para tu caso de uso específico.
Ejemplo Paso final
- En este ejemplo, la
img_name
es el nombre base del archivo de imagen de origen,label
es el nombre de la clase detectada, yci
es el índice de la detección de objetos (en caso de varias instancias con el mismo nombre de clase).
Código de ejemplo completo
Aquí, todos los pasos de la sección anterior se combinan en un único bloque de código. Para un uso repetido, lo óptimo sería definir una función que realice algunos o todos los comandos contenidos en el bloque de código for
-loops, pero eso es un ejercicio que se deja al lector.
from pathlib import Path
import cv2
import numpy as np
from ultralytics import YOLO
m = YOLO("yolo11n-seg.pt") # (4)!
res = m.predict() # (3)!
# Iterate detection results (5)
for r in res:
img = np.copy(r.orig_img)
img_name = Path(r.path).stem
# Iterate each object contour (6)
for ci, c in enumerate(r):
label = c.names[c.boxes.cls.tolist().pop()]
b_mask = np.zeros(img.shape[:2], np.uint8)
# Create contour mask (1)
contour = c.masks.xy.pop().astype(np.int32).reshape(-1, 1, 2)
_ = cv2.drawContours(b_mask, [contour], -1, (255, 255, 255), cv2.FILLED)
# Choose one:
# OPTION-1: Isolate object with black background
mask3ch = cv2.cvtColor(b_mask, cv2.COLOR_GRAY2BGR)
isolated = cv2.bitwise_and(mask3ch, img)
# OPTION-2: Isolate object with transparent background (when saved as PNG)
isolated = np.dstack([img, b_mask])
# OPTIONAL: detection crop (from either OPT1 or OPT2)
x1, y1, x2, y2 = c.boxes.xyxy.cpu().numpy().squeeze().astype(np.int32)
iso_crop = isolated[y1:y2, x1:x2]
# TODO your actions go here (2)
- La línea que rellena
contour
se combina aquí en una sola línea, donde antes se dividía en varias. - ¡Lo que vaya aquí depende de ti!
- Consulta el Modo Predecir para obtener información adicional.
- Para más información, consulta Tarea de segmento.
- Más información sobre Trabajar con resultados
- Más información sobre los Resultados de la Máscara de Segmentación
PREGUNTAS FRECUENTES
¿Cómo aíslo objetos utilizando Ultralytics YOLO11 para tareas de segmentación?
Para aislar objetos utilizando Ultralytics YOLO11, sigue estos pasos:
Carga el modelo y ejecuta la inferencia:
Genera una máscara binaria y dibuja contornos:
Aísla el objeto utilizando la máscara binaria:
Consulta la guía sobre el Modo Predecir y la Tarea Segmento para más información.
¿Qué opciones hay para guardar los objetos aislados después de la segmentación?
Ultralytics YOLO11 ofrece dos opciones principales para guardar objetos aislados:
Con fondo negro:
Con Fondo Transparente:
Para más detalles, visita la sección Modo Predecir.
¿Cómo puedo recortar objetos aislados a sus cuadros delimitadores utilizando Ultralytics YOLO11?
Para recortar objetos aislados a sus cuadros delimitadores:
Recupera las coordenadas de la caja delimitadora:
Recorta la imagen aislada:
Más información sobre los resultados del cuadro delimitador en la documentación del Modo Predecir.
¿Por qué debería utilizar Ultralytics YOLO11 para el aislamiento de objetos en tareas de segmentación?
Ultralytics YOLO11 proporciona:
- Detección y segmentación de objetos a alta velocidad y en tiempo real.
- Generación precisa de recuadros delimitadores y máscaras para aislar con precisión los objetos.
- Documentación completa y API fácil de usar para un desarrollo eficaz.
Explora las ventajas de utilizar YOLO en la documentación de la Tarea Segmento.
¿Puedo guardar objetos aislados, incluido el fondo, utilizando Ultralytics YOLO11?
Sí, es una función integrada en Ultralytics YOLO11. Utiliza la función save_crop
argumento en el predict()
método. Por ejemplo:
Más información sobre el save_crop
argumento en el Argumentos de Inferencia del Modo Predecir sección.