Ultralytics YOLO27 :
Get Started

Comment isoler des objets segmentés avec Ultralytics YOLO#

La segmentation d’instances produit un masque précis au pixel près pour chaque objet détecté, ce qui te permet d’extraire individuellement chaque objet d’une image. Ce guide t’explique comment transformer les résultats de segmentation d’Ultralytics YOLO en objets isolés à l’aide du mode Predict et d’OpenCV, avec un arrière-plan noir uni ou transparent pour l’enregistrement au format PNG.



À regarder : Comment supprimer l’arrière-plan et isoler des objets avec la segmentation Ultralytics YOLO et OpenCV en Python 🚀

Pourquoi isoler des objets segmentés ?#

Extraire des objets individuels d’une image ouvre la voie à divers flux de travail en aval :

  • Suppression de l’arrière-plan pour les photos de produits, les catalogues ou la retouche créative.
  • Recadrages par objet pour créer des jeux de données de classification à partir de tes détections.
  • Traitement ciblé pour que les étapes suivantes, comme l’OCR, l’analyse des couleurs ou la mesure, ne portent que sur l’objet et non sur la scène environnante.
  • Exportation PNG avec transparence pour placer les objets sur de nouveaux arrière-plans.

Cette méthode fonctionne avec n’importe quel modèle de segmentation Ultralytics YOLO et comporte quatre étapes : exécuter l’inférence → extraire chaque contour → isoler l’objet → enregistrer le résultat.

Exécuter l’inférence de segmentation#

Installe les bibliothèques requises, puis charge un modèle de segmentation (le suffixe -seg, requis pour produire des masques) et lance la prédiction sur ton image source :

from ultralytics import YOLO

# Charger un modèle de segmentation
model = YOLO("yolo26n-seg.pt")

# Exécuter l’inférence sur une source
results = model.predict(source="path/to/image.jpg")
Tu n’as pas de source ? YOLO utilise les images d’exemple incluses

Si tu appelles model.predict() sans source, Ultralytics utilise les images d’exemple fournies avec le paquet (bus.jpg et zidane.jpg), ce qui est pratique pour tester rapidement le flux de travail.

Extraire les contours des objets#

Chaque élément de results correspond à une image, et parcourir un résultat renvoie une détection à la fois. Pour chaque détection, copie l’image d’origine, lis l’étiquette de classe et trace le contour du masque de l’objet sur un masque binaire vierge. La zone blanche de ce masque indique précisément les pixels appartenant à l’objet.

Les extraits de code de cette section et de la suivante s’exécutent à l’intérieur de la boucle de détection ci-dessous ; le script complet, prêt à copier-coller, se trouve dans Exemple complet.

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  # nom de base de l’image source

    # Parcourir chaque objet détecté dans l’image
    for ci, c in enumerate(r):
        label = c.names[c.boxes.cls.tolist().pop()]  # nom de la classe

        # Créer un masque binaire et y tracer le contour de l’objet
        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)
Que fait `c.masks.xy[0].astype(np.int32).reshape(-1, 1, 2)` ?
  • c.masks.xy[0] renvoie le contour du masque sous forme de coordonnées de points (x, y) pour l’objet dans ce résultat de détection unique.
  • .astype(np.int32) convertit les points de float32, que drawContours() d’OpenCV ne prend pas en charge.
  • .reshape(-1, 1, 2) remet les points en forme selon la disposition [N, 1, 2] attendue par drawContours(), où N correspond au nombre de points du contour.

En transmettant [contour] avec l’indice -1, tu traces tous les points du contour fourni, et cv2.FILLED remplit en blanc chaque pixel à l’intérieur du contour.

Isoler l’objet#

Une fois le masque binaire prêt, combine-le avec l’image d’origine. Il existe deux méthodes courantes, selon l’arrière-plan souhaité :

Choisir une méthode d’isolation

Convertis le masque en trois canaux et conserve uniquement les pixels qui recouvrent l’objet. Tout ce qui se trouve à l’extérieur du contour devient noir :

# Isoler l’objet avec un arrière-plan noir
mask3ch = cv2.cvtColor(b_mask, cv2.COLOR_GRAY2BGR)
isolated = cv2.bitwise_and(mask3ch, img)
Example Full size Isolated Object Image Black Background
Objet en taille réelle sur fond noir
Recadrer selon la boîte englobante

Pour ne conserver que la région de l’objet au lieu de l’image entière, découpe l’image selon la boîte englobante de la détection :

# Coordonnées de la boîte englobante
x1, y1, x2, y2 = c.boxes.xyxy.cpu().numpy().squeeze().astype(np.int32)
# Recadrer l’image isolée à la région de l’objet
iso_crop = isolated[y1:y2, x1:x2]
Example Crop Isolated Object Image Black Background
Objet recadré selon sa boîte englobante
Tu as besoin du recadrage avec son arrière-plan d’origine ?

Cette fonction est intégrée. Passe save_crop=True à predict() et Ultralytics enregistre automatiquement les recadrages des boîtes englobantes, sans masque.

Enregistrer le résultat (facultatif)#

Tu es libre de choisir quoi faire de chaque objet isolé. Une étape suivante courante consiste à l’écrire sur le disque pour une utilisation ultérieure :

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

Ici, img_name correspond au nom de base de l’image source, label au nom de la classe et ci à l’indice de détection ; ainsi, plusieurs instances d’une même classe obtiennent des noms de fichier uniques. Remplace isolated par iso_crop si tu as effectué le recadrage facultatif ci-dessus.

Exemple complet#

Le script ci-dessous regroupe toutes les étapes dans un seul bloc exécutable. Il utilise un arrière-plan noir par défaut ; remplace la ligne indiquée par np.dstack([img, b_mask]) pour obtenir plutôt un PNG transparent :

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])

Pour une utilisation répétée, place le corps de la boucle dans une fonction afin de pouvoir l’appeler pour de nombreuses images.

Conclusion#

Tu disposes maintenant d’une méthode complète pour isoler des objets segmentés avec Ultralytics YOLO : exécuter l’inférence, créer un masque binaire à partir de chaque contour, puis extraire l’objet sur un arrière-plan noir ou transparent et, éventuellement, le recadrer selon sa boîte englobante. Consulte la documentation complète sur la tâche Segment et le mode Predict pour adapter le flux de travail à tes propres classes.

FAQ#

  • Charge un modèle de segmentation, lance l’inférence, crée un masque binaire à partir du contour de chaque détection, puis combine-le avec l’image d’origine :

    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)

    Consulte l’exemple complet pour voir la boucle complète sur chaque détection.

  • Il existe deux méthodes principales. Pour un arrière-plan noir, convertis le masque en trois canaux et utilise cv2.bitwise_and(). Pour un arrière-plan transparent (lors de l’enregistrement au format PNG), empile le masque en tant que quatrième canal alpha avec np.dstack([img, b_mask]). Les deux méthodes sont présentées dans Isoler l’objet.

  • Lis les coordonnées de la boîte englobante dans la détection et découpe l’image isolée :

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

    Pour en savoir plus sur les résultats des boîtes englobantes, consulte la documentation du mode Predict.

  • Ultralytics YOLO fournit une segmentation d’instances rapide et en temps réel, avec une génération précise de masques et de boîtes englobantes, ainsi qu’une API Python simple qui transforme les résultats d’inférence en objets isolés en quelques lignes de code OpenCV.

  • Oui. Utilise l’argument save_crop dans predict() pour enregistrer des recadrages de boîtes englobantes avec leur arrière-plan d’origine :

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

    Pour en savoir plus, consulte la section Arguments d’inférence du mode Predict.

Commentaires