Comment isoler des objets segmentés avec Ultralytics YOLO#
La segmentation d’instances produit un masque précis au niveau du pixel pour chaque objet détecté, ce qui signifie que tu peux extraire chaque objet individuellement d’une image. Ce guide te montre comment transformer les résultats de segmentation d’Ultralytics YOLO en objets isolés à l’aide du mode Prédiction et d’OpenCV, avec un arrière-plan noir uni ou transparent pour un enregistrement au format PNG.
Watch: How to Remove Background and Isolate Objects with Ultralytics YOLO Segmentation & OpenCV in Python 🚀
Pourquoi isoler les objets segmentés ?#
L’extraction d’objets individuels d’une image ouvre la voie à de nombreux workflows 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é afin que les étapes suivantes, comme l’OCR, l’analyse des couleurs ou la mesure, ne voient que l’objet et non la scène environnante.
- Export PNG transparent pour composer les objets sur de nouveaux arrière-plans.
Cette méthode fonctionne avec n’importe quel modèle de segmentation Ultralytics YOLO et suit 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 exécute la prédiction sur ton image source :
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")Si tu appelles model.predict() sans source, Ultralytics utilise par défaut les images d’exemple fournies avec le paquet (bus.jpg et zidane.jpg), ce qui est pratique pour tester rapidement le workflow.
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 originale, lis l’étiquette de classe et dessine le contour du masque de l’objet sur un masque binaire vierge. La région blanche de ce masque indique exactement quels pixels appartiennent à 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 à être copié-collé, se trouve dans Exemple complet.
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]renvoie le contour du masque sous forme de coordonnées de points(x, y)pour l’objet dans ce résultat contenant une seule détection..astype(np.int32)convertit les points depuisfloat32, quedrawContours()d’OpenCV n’accepte pas..reshape(-1, 1, 2)remodèle les points selon la disposition[N, 1, 2]attendue pardrawContours(), oùNcorrespond au nombre de points du contour.
Le passage de [contour] avec l’indice -1 dessine tous les points du contour fourni, tandis que cv2.FILLED remplit en blanc chaque pixel délimité.
Isoler l’objet#
Une fois le masque binaire prêt, combine-le avec l’image originale. Il existe deux styles courants, selon l’arrière-plan que tu souhaites obtenir :
Convertis le masque en trois canaux et conserve uniquement les pixels qui se superposent à l’objet. Tout ce qui se trouve à l’extérieur du contour devient noir :
# Isolate object with a black background
mask3ch = cv2.cvtColor(b_mask, cv2.COLOR_GRAY2BGR)
isolated = cv2.bitwise_and(mask3ch, img)
Pour ne conserver que la région de l’objet au lieu de l’image en taille réelle, découpe-la selon la boîte englobante de la détection :
# 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]
C’est intégré. Passe save_crop=True à predict() et Ultralytics enregistre automatiquement les recadrages selon la boîte englobante, sans nécessiter de masquage.
Enregistrer le résultat (facultatif)#
Ce que tu fais de chaque objet isolé ne dépend que de toi. 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 de la même classe obtiennent des noms de fichier uniques. Remplace isolated par iso_crop si tu as appliqué le recadrage facultatif ci-dessus.
Exemple complet#
Le script ci-dessous regroupe toutes les étapes dans un bloc unique et exécutable. Il utilise par défaut un arrière-plan noir ; remplace la ligne indiquée par np.dstack([img, b_mask]) pour obtenir 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, encapsule le corps de la boucle dans une fonction afin de pouvoir l’appeler sur 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, construire un masque binaire à partir de chaque contour, puis extraire l’objet sur un arrière-plan noir ou transparent et, si nécessaire, le recadrer selon sa boîte englobante. Consulte la documentation complète sur la tâche Segment et le mode Prédiction pour adapter ce workflow à tes propres classes.
FAQ#
Il existe deux styles principaux. 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 comme quatrième canal alpha avecnp.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, puis 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 Prédiction.
Ultralytics YOLO fournit une segmentation d’instances rapide et en temps réel, avec une génération précise des masques et des 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_cropdanspredict()pour enregistrer des recadrages selon la boîte englobante 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 Prédiction.
Charge un modèle de segmentation, exécute l’inférence, construis un masque binaire à partir du contour de chaque détection, puis combine-le avec l’image originale :
Consulte l’Exemple complet pour découvrir la boucle complète appliquée à chaque détection.