Ultralytics YOLO27:
Get Started

Come isolare gli oggetti segmentati con Ultralytics YOLO#

La segmentazione di istanze produce una maschera precisa a livello di pixel per ogni oggetto rilevato, permettendoti di estrarre separatamente ogni oggetto dall'immagine. Questa guida mostra come trasformare i risultati della segmentazione di Ultralytics YOLO in oggetti isolati usando la modalità Predict e OpenCV, con uno sfondo nero uniforme oppure trasparente per salvarli come PNG.



Guarda: Come rimuovere lo sfondo e isolare gli oggetti con la segmentazione Ultralytics YOLO e OpenCV in Python 🚀

Perché isolare gli oggetti segmentati?#

Estrarre i singoli oggetti da un'immagine apre la strada a diversi flussi di lavoro successivi:

  • Rimozione dello sfondo per foto di prodotti, cataloghi o modifiche creative.
  • Ritagli per singolo oggetto per creare dataset di classificazione a partire dai rilevamenti.
  • Elaborazione mirata, affinché le fasi successive, come OCR, analisi del colore o misurazione, considerino solo l'oggetto e non la scena circostante.
  • Esportazione PNG trasparente per sovrapporre gli oggetti a nuovi sfondi.

La procedura funziona con qualsiasi modello di segmentazione Ultralytics YOLO e si articola in quattro fasi: esegui l'inferenza → estrai ogni contorno → isola l'oggetto → salva il risultato.

Esegui l'inferenza di segmentazione#

Installa le librerie necessarie, quindi carica un modello di segmentazione (il suffisso -seg, necessario per produrre le maschere) ed esegui la predizione sull'immagine sorgente:

from ultralytics import YOLO

# Carica un modello di segmentazione
model = YOLO("yolo26n-seg.pt")

# Esegui l'inferenza su una sorgente
results = model.predict(source="path/to/image.jpg")
Non hai una sorgente? YOLO usa le immagini di esempio incluse

Se chiami model.predict() senza un source, Ultralytics usa le immagini di esempio incluse nel pacchetto (bus.jpg e zidane.jpg), una soluzione pratica per testare rapidamente il flusso di lavoro.

Estrai i contorni degli oggetti#

Ogni elemento in results corrisponde a un'immagine e scorrere un risultato restituisce 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 della maschera indica esattamente quali pixel appartengono all'oggetto.

Gli snippet di questa sezione e della successiva vengono eseguiti all'interno del ciclo di rilevamento qui sotto; lo script completo, pronto da copiare e incollare, si trova in Esempio 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  # nome base dell'immagine sorgente

    # Itera su ogni oggetto rilevato nell'immagine
    for ci, c in enumerate(r):
        label = c.names[c.boxes.cls.tolist().pop()]  # nome della classe

        # Crea una maschera binaria e disegnaci sopra il contorno dell'oggetto
        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)
Cosa fa `c.masks.xy[0].astype(np.int32).reshape(-1, 1, 2)`?
  • c.masks.xy[0] restituisce il contorno della maschera come coordinate dei punti (x, y) dell'oggetto in questo risultato con un singolo rilevamento.
  • .astype(np.int32) converte i punti di float32, che drawContours() di OpenCV non accetta.
  • .reshape(-1, 1, 2) rimodella i punti nel formato [N, 1, 2] previsto da drawContours(), dove N è il numero di punti del contorno.

Passare [contour] con l'indice -1 disegna tutti i punti del contorno fornito, mentre cv2.FILLED riempie di bianco ogni pixel racchiuso.

Isola l'oggetto#

Una volta pronta la maschera binaria, combinala con l'immagine originale. Puoi scegliere tra due modalità comuni, a seconda dello sfondo desiderato:

Scegli una modalità di isolamento

Converti la maschera in tre canali e mantieni solo i pixel che si sovrappongono all'oggetto. Tutto ciò che si trova fuori dal contorno diventa nero:

# Isola l'oggetto con uno sfondo nero
mask3ch = cv2.cvtColor(b_mask, cv2.COLOR_GRAY2BGR)
isolated = cv2.bitwise_and(mask3ch, img)
Example Full size Isolated Object Image Black Background
Oggetto a grandezza naturale su sfondo nero
Ritaglia sul riquadro di delimitazione

Per mantenere solo la regione dell'oggetto invece dell'immagine a dimensione intera, ritagliala sul riquadro di delimitazione del rilevamento:

# Coordinate del riquadro di delimitazione
x1, y1, x2, y2 = c.boxes.xyxy.cpu().numpy().squeeze().astype(np.int32)
# Ritaglia l'immagine isolata per mantenere la regione dell'oggetto
iso_crop = isolated[y1:y2, x1:x2]
Example Crop Isolated Object Image Black Background
Oggetto ritagliato in base al riquadro di delimitazione
Ti serve il ritaglio con lo sfondo originale?

La funzione è integrata. Passa save_crop=True a predict() e Ultralytics salverà automaticamente i ritagli dei riquadri di delimitazione, senza bisogno di maschere.

Salva il risultato (facoltativo)#

Decidi tu cosa fare con ogni oggetto isolato. Un passaggio successivo comune consiste nello scriverlo su disco per utilizzarlo in seguito:

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

Qui img_name è il nome base dell'immagine sorgente, label è il nome della classe e ci è l'indice del rilevamento, così le diverse istanze della stessa classe ottengono nomi di file univoci. Sostituisci isolated con iso_crop se hai applicato il ritaglio facoltativo descritto sopra.

Esempio completo#

Lo script qui sotto riunisce tutti i passaggi in un unico blocco eseguibile. Per impostazione predefinita usa uno sfondo nero; modifica l'unica riga contrassegnata impostando 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])

Se vuoi riutilizzarlo, racchiudi il corpo del ciclo in una funzione per poterla chiamare su molte immagini.

Conclusione#

Ora hai una procedura completa per isolare gli oggetti segmentati con Ultralytics YOLO: esegui l'inferenza, crea una maschera binaria a partire da ogni contorno, quindi estrai l'oggetto su uno sfondo nero o trasparente e, facoltativamente, ritaglialo sul relativo riquadro di delimitazione. Consulta la documentazione completa di Attività di segmentazione e Modalità Predict per adattare il flusso di lavoro alle tue classi.

Domande frequenti#

  • Carica un modello di segmentazione, esegui l'inferenza, crea una maschera binaria a partire dal contorno di ogni rilevamento 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 l'Esempio completo per vedere il ciclo completo per ogni rilevamento.

  • Ci sono due modalità principali. Per uno sfondo nero, converti la maschera in tre canali e usa cv2.bitwise_and(). Per uno sfondo trasparente (quando salvi come PNG), aggiungi la maschera come quarto canale alfa con np.dstack([img, b_mask]). Entrambe le modalità sono illustrate in Isola l'oggetto.

  • Leggi le coordinate del riquadro di delimitazione dal rilevamento 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 dei riquadri di delimitazione nella documentazione della modalità Predict.

  • Ultralytics YOLO offre una segmentazione delle istanze rapida 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 con poche righe di codice OpenCV.

  • Sì. Usa l'argomento save_crop in predict() per salvare i ritagli dei riquadri di delimitazione con lo sfondo originale:

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

    Leggi di più nella sezione Argomenti di inferenza della modalità di previsione.

Commenti