Vai al contenuto

Isolamento degli oggetti di segmentazione

Dopo aver eseguito la Segment Task, a volte è auspicabile estrarre gli oggetti isolati dai risultati dell'inferenza. Questa guida fornisce una ricetta generica su come realizzare questo obiettivo utilizzando la Predict Mode di Ultralytics.

Esempio di segmentazione di un oggetto isolato

Guida pratica alla ricetta

  1. Consulta la sezione di installazione rapida di Ultralytics per una rapida panoramica sull'installazione delle librerie richieste.


  2. Carica un modello ed esegui predict() method su una source.

    from ultralytics import YOLO
    
    # Load a model
    model = YOLO("yolo11n-seg.pt")
    
    # Run inference
    results = model.predict()
    

    Nessun argomento di previsione?

    Senza specificare una sorgente, verranno utilizzate le immagini di esempio dalla libreria:

    'ultralytics/assets/bus.jpg'
    'ultralytics/assets/zidane.jpg'
    

    Questo è utile per test rapidi con il predict() metodo.

    Per ulteriori informazioni sui modelli di segmentazione, visitare la pagina Segment Task page. Per saperne di più su predict() metodo, vedi Modalità di previsione sezione della documentazione.


  3. Ora scorri i risultati e i contorni. Per i flussi di lavoro che desiderano salvare un'immagine su file, l'immagine sorgente base-name e il rilevamento class-label vengono recuperati per un uso successivo (opzionale).

    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()]
    
    1. Per ulteriori informazioni sull'utilizzo dei risultati del detection, consultare la Sezione Riquadri per la modalità Predict.
    2. Per saperne di più su predict() risultati vedi Lavorare con i risultati per la modalità Predict
    For-Loop

    Una singola immagine itererà il primo ciclo solo una volta. Una singola immagine con una sola rilevazione itererà ogni ciclo solo una volta.


  4. Inizia generando una maschera binaria dall'immagine sorgente e poi disegna un contorno riempito sulla maschera. Questo permetterà all'oggetto di essere isolato dalle altre parti dell'immagine. Un esempio da bus.jpg per uno degli elementi rilevati person gli oggetti classe sono mostrati sulla destra.

    Immagine Maschera Binaria

    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)
    
    1. Per maggiori informazioni su c.masks.xy vedi Sezione Maschere dalla Modalità Predict.

    2. Qui i valori vengono convertiti in np.int32 per la compatibilità con drawContours() funzione da OpenCV.

    3. OpenCV drawContours() La funzione prevede che i contorni abbiano una forma di [N, 1, 2] espandi la sezione sottostante per maggiori dettagli.

    Espandi per capire cosa succede quando si definisce il contour variabile.

    - c.masks.xy :: Fornisce le coordinate dei punti del contorno della maschera nel formato (x, y). Per maggiori dettagli, fare riferimento al Sezione Maschere dalla Modalità Predict. - .pop() :: Come masks.xy è una lista contenente un singolo elemento; questo elemento viene estratto usando il/la pop() metodo. - .astype(np.int32) :: Utilizzando masks.xy restituirà un tipo di dati di float32, ma questo non sarà compatibile con OpenCV drawContours() funzione, quindi questo cambierà il tipo di dati in int32 per la compatibilità. - .reshape(-1, 1, 2) :: Riformatta i dati nella forma richiesta di [N, 1, 2] dove N è il numero di punti di contorno, con ogni punto rappresentato da una singola voce 1, e la voce è composta da 2 valori. La -1 indica che il numero di valori lungo questa dimensione è flessibile.

    Espandi per una spiegazione del drawContours() configurazione.

    - Incapsulando il contour variabile tra parentesi quadre, [contour], si è rivelato efficace nel generare la maschera di contorno desiderata durante i test. - Il valore -1 specificato per il drawContours() parametro indica alla funzione di disegnare tutti i contorni presenti nell'immagine. - Il tuple (255, 255, 255) rappresenta il colore bianco, che è il colore desiderato per disegnare il contorno in questa maschera binaria. - L'aggiunta di cv2.FILLED colorerà tutti i pixel racchiusi dal contorno allo stesso modo, in questo caso, tutti i pixel racchiusi saranno bianchi. - Vedi Documentazione OpenCV su drawContours() per maggiori informazioni.


  5. Successivamente, ci sono 2 opzioni su come procedere con l'immagine da questo punto e una successiva opzione per ciascuna.

    Opzioni di isolamento degli oggetti

    Esempio

    # Create 3-channel mask
    mask3ch = cv2.cvtColor(b_mask, cv2.COLOR_GRAY2BGR)
    
    # Isolate object with binary mask
    isolated = cv2.bitwise_and(mask3ch, img)
    
    Come funziona?
    • Innanzitutto, la maschera binaria viene convertita da un'immagine a canale singolo a un'immagine a tre canali. Questa conversione è necessaria per il passaggio successivo in cui la maschera e l'immagine originale vengono combinate. Entrambe le immagini devono avere lo stesso numero di canali per essere compatibili con l'operazione di fusione.

    • L'immagine originale e la maschera binaria a tre canali vengono unite utilizzando la funzione OpenCV bitwise_and(). Questa operazione conserva solo valori dei pixel superiori a zero (> 0) da entrambe le immagini. Poiché i pixel della maschera sono maggiori di zero (> 0) solo all'interno della regione del contorno, i pixel rimanenti dall'immagine originale sono quelli che si sovrappongono al contorno.

    Isolare con pixel neri: Sotto-opzioni

    Immagine a dimensione intera

    Non sono necessari passaggi aggiuntivi se si mantiene l'immagine a dimensione intera.

    Esempio di immagine a dimensione intera di un oggetto isolato con sfondo nero
    Esempio di output a dimensione intera

    Immagine dell'oggetto ritagliato

    Passaggi aggiuntivi necessari per ritagliare l'immagine in modo da includere solo la regione dell'oggetto.

    Esempio di ritaglio di immagine di oggetto isolato con sfondo nero

    # (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]
    

    1. Per maggiori informazioni sui risultati dei bounding box, consulta la Sezione Box della Modalità Predict.
    Cosa fa questo codice?
    • Il c.boxes.xyxy.cpu().numpy() la chiamata recupera le caselle di delimitazione come array NumPy nel xyxy formato, dove xmin, ymin, xmax, e ymax rappresentano le coordinate del rettangolo di delimitazione. Vedi Sezione Riquadri dalla modalità Predict per maggiori dettagli.

    • Il squeeze() L'operazione rimuove qualsiasi dimensione non necessaria dall'array NumPy, assicurando che abbia la forma prevista.

    • Conversione dei valori delle coordinate utilizzando .astype(np.int32) modifica il tipo di dati delle coordinate della casella da float32 a int32, rendendoli compatibili per il ritaglio delle immagini utilizzando le sezioni di indice.

    • Infine, la regione del riquadro di delimitazione viene ritagliata dall'immagine utilizzando l'indicizzazione a fette. I limiti sono definiti dal [ymin:ymax, xmin:xmax] coordinate del riquadro di delimitazione del rilevamento.

    # Isolate object with transparent background (when saved as PNG)
    isolated = np.dstack([img, b_mask])
    
    Come funziona?
    • Utilizzando NumPy dstack() La funzione (stacking di array lungo l'asse della profondità) in combinazione con la maschera binaria generata, creerà un'immagine con quattro canali. Ciò consente a tutti i pixel al di fuori del contorno dell'oggetto di essere trasparenti quando si salva come PNG file.

    Isolare con pixel trasparenti: Sotto-opzioni

    Immagine a dimensione intera

    Non sono necessari passaggi aggiuntivi se si mantiene l'immagine a dimensione intera.

    Esempio di immagine a dimensione intera di un oggetto isolato senza sfondo
    Esempio di output a dimensione intera + sfondo trasparente

    Immagine dell'oggetto ritagliato

    Passaggi aggiuntivi necessari per ritagliare l'immagine in modo da includere solo la regione dell'oggetto.

    Esempio di ritaglio di immagine di oggetto isolato senza sfondo

    # (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]
    

    1. Per maggiori informazioni sui risultati dei bounding box, consulta la Sezione Box della Modalità Predict.
    Cosa fa questo codice?
    • Quando si utilizza c.boxes.xyxy.cpu().numpy(), i riquadri di delimitazione vengono restituiti come array NumPy, utilizzando il xyxy formato delle coordinate del riquadro, che corrispondono ai punti xmin, ymin, xmax, ymax per il riquadro di delimitazione (rettangolo), vedere Sezione Riquadri dalla modalità Predict per maggiori informazioni.

    • Aggiunta squeeze() assicura che qualsiasi dimensione estranea venga rimossa dall'array NumPy.

    • Conversione dei valori delle coordinate utilizzando .astype(np.int32) modifica il tipo di dati delle coordinate della casella da float32 a int32 che sarà compatibile quando si ritaglia l'immagine usando le sezioni di indice.

    • Infine, la regione dell'immagine per il riquadro di delimitazione viene ritagliata utilizzando l'indicizzazione a fette, dove i limiti sono impostati utilizzando il [ymin:ymax, xmin:xmax] coordinate del riquadro di delimitazione del rilevamento.

    Cosa succede se voglio l'oggetto ritagliato incluso lo sfondo?

    Questa è una funzionalità integrata per la libreria Ultralytics. Vedi il save_crop argomento per Argomenti di inferenza della modalità di previsione per i dettagli.


  6. Cosa fare dopo è interamente lasciato a te come sviluppatore. Viene mostrato un esempio base di un possibile passo successivo (salvare l'immagine in un file per un uso futuro).

    • NOTA: questo passaggio è facoltativo e può essere saltato se non è necessario per il caso d'uso specifico.
    Esempio di fase finale
    # Save isolated object to file
    _ = cv2.imwrite(f"{img_name}_{label}-{ci}.png", iso_crop)
    
    • In questo esempio, il img_name è il nome base del file immagine sorgente, label è il nome della classe rilevata, e ci è l'indice del il rilevamento di oggetti (in caso di più istanze con lo stesso nome di classe).

Codice di esempio completo

Qui, tutti i passaggi della sezione precedente sono combinati in un unico blocco di codice. Per un uso ripetuto, sarebbe ottimale definire una funzione per eseguire alcuni o tutti i comandi contenuti nel for-loop, ma questo è un esercizio lasciato al lettore.

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)
  1. La riga che popola contour è combinato in un'unica riga qui, mentre sopra era diviso in più righe.
  2. Ciò che viene inserito qui dipende da te!
  3. Consulta la Modalità Predict per ulteriori informazioni.
  4. Consulta Segment Task per maggiori informazioni.
  5. Scopri di più su Come lavorare con i risultati
  6. Scopri di più sui Risultati della maschera di segmentazione

FAQ

Come posso isolare gli oggetti utilizzando Ultralytics YOLO11 per attività di segmentazione?

Per isolare gli oggetti utilizzando Ultralytics YOLO11, segui questi passaggi:

  1. Carica il modello ed esegui l'inferenza:

    from ultralytics import YOLO
    
    model = YOLO("yolo11n-seg.pt")
    results = model.predict(source="path/to/your/image.jpg")
    
  2. Genera una maschera binaria e disegna i contorni:

    import cv2
    import numpy as np
    
    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)
    
  3. Isolare l'oggetto usando la maschera binaria:

    mask3ch = cv2.cvtColor(b_mask, cv2.COLOR_GRAY2BGR)
    isolated = cv2.bitwise_and(mask3ch, img)
    

Consulta la guida sulla Modalità Predict e l'Attività Segment per maggiori informazioni.

Quali opzioni sono disponibili per salvare gli oggetti isolati dopo la segmentazione?

Ultralytics YOLO11 offre due opzioni principali per il salvataggio di oggetti isolati:

  1. Con uno sfondo nero:

    mask3ch = cv2.cvtColor(b_mask, cv2.COLOR_GRAY2BGR)
    isolated = cv2.bitwise_and(mask3ch, img)
    
  2. Con uno sfondo trasparente:

    isolated = np.dstack([img, b_mask])
    

Per maggiori dettagli, visita la sezione Modalità Predict.

Come posso ritagliare oggetti isolati alle loro bounding box utilizzando Ultralytics YOLO11?

Per ritagliare gli oggetti isolati alle loro bounding box:

  1. Recupera le coordinate del riquadro di delimitazione:

    x1, y1, x2, y2 = results[0].boxes.xyxy[0].cpu().numpy().astype(np.int32)
    
  2. Ritaglia l'immagine isolata:

    iso_crop = isolated[y1:y2, x1:x2]
    

Scopri di più sui risultati dei riquadri di delimitazione nella documentazione della Modalità di previsione.

Perché dovrei usare Ultralytics YOLO11 per l'isolamento di oggetti in attività di segmentazione?

Ultralytics YOLO11 offre:

  • Rilevamento e segmentazione di oggetti in tempo reale ad alta velocità.
  • Generazione accurata di riquadri di delimitazione e maschere per un isolamento preciso degli oggetti.
  • Documentazione completa e API di facile utilizzo per uno sviluppo efficiente.

Esplora i vantaggi dell'utilizzo di YOLO nella documentazione sull'attività di segmentazione.

Posso salvare oggetti isolati incluso lo sfondo utilizzando Ultralytics YOLO11?

Sì, questa è una funzionalità integrata in Ultralytics YOLO11. Usa l'argomento save_crop argomento nel predict() metodo. Per esempio:

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

Scopri di più su save_crop argomento nel Argomenti di inferenza della modalità di previsione sezione.



📅 Creato 1 anno fa ✏️ Aggiornato 2 mesi fa

Commenti