Come isolare oggetti di segmentazione con Ultralytics YOLO#
Instance segmentation produce una maschera pixel-precisa per ogni oggetto rilevato, il che significa che puoi estrarre ciascun oggetto da un'immagine autonomamente. Questa guida ti mostra come trasformare i risultati della segmentazione di Ultralytics YOLO in oggetti isolati utilizzando la Predict Mode e OpenCV, con uno sfondo nero pieno o trasparente per il salvataggio in formato PNG.
Watch: How to Remove Background and Isolate Objects with Ultralytics YOLO Segmentation & OpenCV in Python 🚀
Perché isolare gli oggetti di segmentazione?#
Estrarre singoli oggetti da un'immagine apre una serie di flussi di lavoro a valle:
- Rimozione dello sfondo per foto di prodotti, cataloghi o editing creativo.
- Ritagli per oggetto per costruire dataset di classificazione dalle tue rilevazioni.
- Elaborazione mirata affinché i passaggi successivi, come OCR, analisi del colore o misurazioni, vedano solo l'oggetto e non la scena circostante.
- Esportazione PNG trasparente per comporre oggetti su nuovi sfondi.
La procedura funziona con qualsiasi modello di segmentazione Ultralytics YOLO e segue quattro fasi: eseguire l'inferenza → estrarre ogni contorno → isolare l'oggetto → salvare il risultato.
Esegui inferenza di segmentazione#
Installa le librerie richieste, quindi carica un modello di segmentazione (il suffisso -seg, necessario per produrre le maschere) ed esegui la predizione sulla tua immagine di origine:
from ultralytics import YOLO
# Load a segmentation model
model = YOLO("yolo26n-seg.pt")
# Run inference on a source
results = model.predict(source="path/to/image.jpg")Se chiami model.predict() senza un source, Ultralytics passa automaticamente alle immagini di esempio fornite con il pacchetto (bus.jpg e zidane.jpg), il che è utile per testare rapidamente il flusso di lavoro.
Estrai contorni oggetto#
Ciascun elemento in results corrisponde a un'immagine e l'iterazione su un risultato produce un rilevamento alla volta. Per ogni rilevamento, copia l'immagine originale, leggi l'etichetta della classe e disegna il contorno della maschera dell'oggetto su una maschera binaria vuota. La regione bianca di questa maschera contrassegna esattamente quali pixel appartengono all'oggetto.
I frammenti di codice in questa sezione e nella successiva vengono eseguiti all'interno del ciclo di rilevamento sottostante; lo script completo e pronto da copiare si trova in Full Example.
{ width="240", align="right" }
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 # source image base-name
# Iterate each detected object in the image
for ci, c in enumerate(r):
label = c.names[c.boxes.cls.tolist().pop()] # class name
# Build a binary mask and draw the object contour onto it
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)c.masks.xy[0]restituisce il contorno della mask come coordinate dei punti(x, y)per l'oggetto in questo risultato a rilevamento singolo..astype(np.int32)converte i punti dafloat32, che la funzionedrawContours()di OpenCV non accetta..reshape(-1, 1, 2)rimodella i punti nel layout[N, 1, 2]atteso dadrawContours(), doveNè il numero di punti del contorno.
Passando [contour] con l'indice -1 vengono disegnati tutti i punti del contorno fornito, e cv2.FILLED riempie di bianco ogni pixel racchiuso.
Isola l'oggetto#
Con la maschera binaria pronta, combinala con l'immagine originale. Esistono due stili comuni, a seconda di quale sfondo desideri:
Converti la maschera in tre canali e mantieni solo i pixel che si sovrappongono all'oggetto. Tutto ciò che è esterno al contorno diventa nero:
# Isolate object with a black background
mask3ch = cv2.cvtColor(b_mask, cv2.COLOR_GRAY2BGR)
isolated = cv2.bitwise_and(mask3ch, img)Per mantenere solo la regione dell'oggetto anziché l'immagine a dimensione intera, ritagliala al riquadro di delimitazione della rilevazione:
# Bounding box coordinates
x1, y1, x2, y2 = c.boxes.xyxy.cpu().numpy().squeeze().astype(np.int32)
# Crop the isolated image to the object region
iso_crop = isolated[y1:y2, x1:x2]Questa funzione è integrata. Passa save_crop=True a predict() e Ultralytics salverà automaticamente i ritagli delle bounding-box, senza che sia richiesta alcuna maschera.
Salva il risultato (opzionale)#
Cosa fare con ogni oggetto isolato dipende da te. Un passaggio successivo comune è salvarlo su disco per un uso futuro:
# Save the isolated object to file
cv2.imwrite(f"{img_name}_{label}-{ci}.png", isolated)Qui img_name è la radice del nome dell'immagine di origine, label è il nome della classe e ci è l'indice di rilevamento, così istanze multiple della stessa classe otterranno nomi di file univoci. Sostituisci isolated con iso_crop se hai applicato il ritaglio opzionale precedente.
Esempio Completo#
Lo script sottostante unisce ogni passaggio in un unico blocco eseguibile. Utilizza uno sfondo nero per impostazione predefinita; modifica la singola riga contrassegnata in np.dstack([img, b_mask]) per ottenere invece un PNG trasparente:
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])Per un uso ripetuto, racchiudi il corpo del ciclo in una funzione così da poterlo richiamare su molte immagini.
Conclusione#
Ora disponi di una procedura completa per isolare gli oggetti segmentati con Ultralytics YOLO: esegui l'inferenza, crea una maschera binaria da ciascun contorno, estrai quindi l'oggetto su uno sfondo nero o trasparente e facoltativamente ritaglialo rispetto alla sua bounding box. Esplora la documentazione completa di Segment Task e Predict Mode per adattare il flusso di lavoro alle tue classi.
FAQ#
Carica un modello di segmentazione, esegui l'inferenza, costruisci una maschera binaria dal contorno di ogni rilevazione e combinala con l'immagine originale:
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 il Full Example per il ciclo completo per ogni rilevamento.
Esistono due stili principali. Per uno sfondo nero, converti la maschera in tre canali e usa
cv2.bitwise_and(). Per uno sfondo trasparente (durante il salvataggio come PNG), impila la maschera come quarto canale alfa connp.dstack([img, b_mask]). Entrambi sono illustrati in Isolate the Object.Leggi le coordinate del riquadro di delimitazione dalla rilevazione e ritaglia l'immagine isolata:
x1, y1, x2, y2 = results[0].boxes.xyxy[0].cpu().numpy().astype(np.int32) iso_crop = isolated[y1:y2, x1:x2]Scopri di più sui risultati delle bounding box nella documentazione della Predict Mode.
Ultralytics YOLO offre una segmentazione delle istanze veloce e in tempo reale con generazione accurata di maschere e riquadri di delimitazione, oltre a una semplice API Python che trasforma i risultati dell'inferenza in oggetti isolati in poche righe di codice OpenCV.
Sì. Usa l'argomento
save_cropinpredict()per salvare i ritagli delle bounding box mantenendo il loro sfondo originale:results = model.predict(source="path/to/your/image.jpg", save_crop=True)Leggi di più nella sezione Predict Mode Inference Arguments.