Isolation des objets de segmentation
Après avoir effectué la tâche de segmentation, il est parfois souhaitable d'extraire les objets isolés des résultats de l'inférence. Ce guide fournit une recette générique sur la façon d'y parvenir en utilisant le mode de prédiction Ultralytics.
Procédure pas à pas de la recette
-
Consultez la section Installation rapide d'Ultralytics pour une présentation rapide de l'installation des bibliothèques requises.
-
Charger un modèle et l'exécuter
predict()
méthode sur une source.from ultralytics import YOLO # Load a model model = YOLO("yolo11n-seg.pt") # Run inference results = model.predict()
Aucun argument de prédiction ?
Si aucune source n'est spécifiée, les exemples d'images de la bibliothèque seront utilisés :
'ultralytics/assets/bus.jpg' 'ultralytics/assets/zidane.jpg'
Ceci est utile pour des tests rapides avec le
predict()
méthode.Pour plus d'informations sur les modèles de segmentation, consultez le Tâche Segment page. Pour en savoir plus sur
predict()
méthode, voir Mode de prédiction section de la documentation.
-
Maintenant, itérez sur les résultats et les contours. Pour les flux de travail qui souhaitent enregistrer une image dans un fichier, l'image source
base-name
et la détectionclass-label
sont récupérées pour une utilisation ultérieure (facultatif).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()]
- Pour en savoir plus sur l'utilisation des résultats de détection, consultez la Section Boîtes pour le mode Predict.
- Pour en savoir plus sur
predict()
résultats voir Travailler avec les résultats pour le mode Predict
Boucle For
Une seule image n'itérera la première boucle qu'une seule fois. Une seule image avec une seule détection n'itérera chaque boucle qu'une seule fois.
-
Commencez par générer un masque binaire à partir de l'image source, puis dessinez un contour rempli sur le masque. Cela permettra d'isoler l'objet des autres parties de l'image. Un exemple de
bus.jpg
pour l'un des éléments détectésperson
les objets de classe sont affichés à droite.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)
-
Pour plus d'informations sur
c.masks.xy
voir Section des masques du mode de prédiction. -
Ici, les valeurs sont converties en
np.int32
pour la compatibilité avecdrawContours()
fonction de module DNN d'OpenCV. -
OpenCV
drawContours()
la fonction attend que les contours aient une forme de[N, 1, 2]
développer la section ci-dessous pour plus de détails.
Développer pour comprendre ce qui se passe lors de la définition du
contour
variable.-
c.masks.xy
:: Fournit les coordonnées des points de contour du masque au format(x, y)
. Pour plus de détails, consultez la section Section des masques du mode de prédiction. -.pop()
:: En tant quemasks.xy
est une liste contenant un seul élément, cet élément est extrait en utilisant lepop()
méthode. -.astype(np.int32)
:: En utilisantmasks.xy
renverra un type de données defloat32
, mais cela ne sera pas compatible avec OpenCVdrawContours()
fonction, cela changera donc le type de données enint32
pour la compatibilité. -.reshape(-1, 1, 2)
:: Reformate les données dans la forme requise de[N, 1, 2]
oùN
est le nombre de points de contour, chaque point étant représenté par une seule entrée1
, et l'entrée est composée de2
valeurs. Le-1
indique que le nombre de valeurs le long de cette dimension est flexible.Développer pour une explication du
drawContours()
configuration.- Encapsulation du
contour
variable entre crochets,[contour]
, s'est avéré efficace pour générer le masque de contour souhaité pendant les tests. - La valeur-1
spécifié pour ledrawContours()
paramètre indique à la fonction de dessiner tous les contours présents dans l'image. - Letuple
(255, 255, 255)
représente la couleur blanche, qui est la couleur souhaitée pour dessiner le contour dans ce masque binaire. - L'ajout decv2.FILLED
coloriera tous les pixels enfermés par la limite du contour de la même couleur, dans ce cas, tous les pixels enfermés seront blancs. - Voir Documentation OpenCV surdrawContours()
pour plus d'informations.
-
-
Ensuite, il existe 2 options quant à la manière de traiter l'image à partir de ce point, ainsi qu'une option subséquente pour chacune.
Options d'isolation d'objets
Exemple
# Create 3-channel mask mask3ch = cv2.cvtColor(b_mask, cv2.COLOR_GRAY2BGR) # Isolate object with binary mask isolated = cv2.bitwise_and(mask3ch, img)
Comment cela fonctionne-t-il ?
-
Tout d'abord, le masque binaire est d'abord converti d'une image à canal unique en une image à trois canaux. Cette conversion est nécessaire pour l'étape suivante où le masque et l'image originale sont combinés. Les deux images doivent avoir le même nombre de canaux pour être compatibles avec l'opération de fusion.
-
L'image originale et le masque binaire à trois canaux sont fusionnés à l'aide de la fonction OpenCV
bitwise_and()
. Cette opération conserve seulement valeurs de pixel supérieures à zéro(> 0)
des deux images. Puisque les pixels du masque sont supérieurs à zéro(> 0)
seulement dans la région du contour, les pixels restants de l'image originale sont ceux qui chevauchent le contour.
Isoler avec des pixels noirs : Sous-options
Image en taille réelle
Aucune étape supplémentaire n'est requise si vous conservez l'image en taille réelle.
Exemple de sortie en taille réelle Image de l'objet rogné
Étapes supplémentaires nécessaires pour recadrer l'image afin d'inclure uniquement la région de l'objet.
# (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]
- Pour plus d'informations sur les résultats des boîtes englobantes, consultez la Section Boîtes du Mode Predict.
Que fait ce code ?
-
L'argument
c.boxes.xyxy.cpu().numpy()
l'appel récupère les boîtes englobantes sous forme de tableau NumPy dans lexyxy
format, oùxmin
,ymin
,xmax
, etymax
représentent les coordonnées du rectangle de la boîte englobante. Voir Section Boîtes du mode Prédiction pour plus de détails. -
L'argument
squeeze()
supprime toutes les dimensions inutiles du tableau NumPy, garantissant ainsi qu'il a la forme attendue. -
Conversion des valeurs de coordonnées à l'aide de
.astype(np.int32)
modifie le type de données des coordonnées de la boîte defloat32
àint32
, les rendant compatibles pour le recadrage d'images à l'aide de tranches d'index. -
Enfin, la région de la boîte englobante est recadrée à partir de l'image en utilisant le découpage d'index. Les limites sont définies par le
[ymin:ymax, xmin:xmax]
coordonnées de la boîte englobante de détection.
# Isolate object with transparent background (when saved as PNG) isolated = np.dstack([img, b_mask])
Comment cela fonctionne-t-il ?
- Utilisation de NumPy
dstack()
fonction (empilement de tableaux le long de l'axe de profondeur) en conjonction avec le masque binaire généré, créera une image avec quatre canaux. Cela permet à tous les pixels en dehors du contour de l'objet d'être transparents lors de l'enregistrement en tant quePNG
.
Isoler avec des pixels transparents : Sous-options
Image en taille réelle
Aucune étape supplémentaire n'est requise si vous conservez l'image en taille réelle.
Exemple de sortie en taille réelle + arrière-plan transparent Image de l'objet rogné
Étapes supplémentaires nécessaires pour recadrer l'image afin d'inclure uniquement la région de l'objet.
# (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]
- Pour plus d'informations sur les résultats des boîtes englobantes, consultez la Section Boîtes du Mode Predict.
Que fait ce code ?
-
Lors de l'utilisation
c.boxes.xyxy.cpu().numpy()
, les boîtes englobantes sont retournées sous forme de tableau NumPy, en utilisant lexyxy
format des coordonnées de la boîte, qui correspondent aux pointsxmin, ymin, xmax, ymax
pour le cadre de délimitation (rectangle), voir Section Boîtes du mode Prédiction pour plus d'informations. -
Ajout de
squeeze()
garantit que toutes les dimensions superflues sont supprimées du tableau NumPy. -
Conversion des valeurs de coordonnées à l'aide de
.astype(np.int32)
modifie le type de données des coordonnées de la boîte defloat32
àint32
qui sera compatible lors du recadrage de l'image à l'aide de tranches d'index. -
Enfin, la région de l'image pour la boîte englobante est recadrée à l'aide du découpage d'index, où les limites sont définies à l'aide du
[ymin:ymax, xmin:xmax]
coordonnées de la boîte englobante de détection.
Que faire si je veux l’objet recadré y compris l’arrière-plan ?
Il s'agit d'une fonctionnalité intégrée à la bibliothèque Ultralytics. Voir le
save_crop
argument pour Arguments d'inférence du mode de prédiction pour plus de détails.
-
-
Ce qu’il faut faire ensuite vous est entièrement laissé en tant que développeur. Un exemple de base d’une prochaine étape possible (enregistrer l’image dans un fichier pour une utilisation future) est présenté.
- REMARQUE : cette étape est facultative et peut être ignorée si elle n’est pas requise pour votre cas d’utilisation spécifique.
Exemple d'étape finale
# Save isolated object to file _ = cv2.imwrite(f"{img_name}_{label}-{ci}.png", iso_crop)
- Dans cet exemple, le
img_name
est le nom de base du fichier image source,label
est le nom de la classe détectée, etci
est l'indice du détection d'objets (en cas d'instances multiples avec le même nom de classe).
Code d'exemple complet
Ici, toutes les étapes de la section précédente sont combinées en un seul bloc de code. Pour une utilisation répétée, il serait optimal de définir une fonction pour exécuter tout ou partie des commandes contenues dans le for
-boucles, mais c'est un exercice laissé au lecteur.
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)
- La ligne de remplissage
contour
est combiné en une seule ligne ici, alors qu'il était divisé en plusieurs ci-dessus. - Ce qui se trouve ici dépend de vous !
- Consultez le mode Predict pour plus d'informations.
- Consultez la tâche Segment pour plus d'informations.
- En savoir plus sur l'utilisation des résultats
- En savoir plus sur les résultats des masques de segmentation
FAQ
Comment isoler des objets à l’aide d’Ultralytics YOLO11 pour les tâches de segmentation ?
Pour isoler des objets à l'aide d'Ultralytics YOLO11, suivez ces étapes :
-
Charger le modèle et exécuter l'inférence :
from ultralytics import YOLO model = YOLO("yolo11n-seg.pt") results = model.predict(source="path/to/your/image.jpg")
-
Générer un masque binaire et dessiner les contours :
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)
-
Isoler l'objet à l'aide du masque binaire :
mask3ch = cv2.cvtColor(b_mask, cv2.COLOR_GRAY2BGR) isolated = cv2.bitwise_and(mask3ch, img)
Consultez le guide sur le mode de prédiction et la tâche de segmentation pour plus d'informations.
Quelles options sont disponibles pour enregistrer les objets isolés après la segmentation ?
Ultralytics YOLO11 offre deux options principales pour enregistrer les objets isolés :
-
Avec un arrière-plan noir :
mask3ch = cv2.cvtColor(b_mask, cv2.COLOR_GRAY2BGR) isolated = cv2.bitwise_and(mask3ch, img)
-
Avec un arrière-plan transparent :
isolated = np.dstack([img, b_mask])
Pour plus de détails, consultez la section Mode Predict.
Comment puis-je recadrer les objets isolés sur leurs boîtes englobantes à l'aide d'Ultralytics YOLO11 ?
Pour recadrer les objets isolés sur leurs boîtes englobantes :
-
Récupérer les coordonnées des boîtes englobantes :
x1, y1, x2, y2 = results[0].boxes.xyxy[0].cpu().numpy().astype(np.int32)
-
Rogner l'image isolée :
iso_crop = isolated[y1:y2, x1:x2]
En savoir plus sur les résultats des boîtes englobantes dans la documentation du mode Prédiction.
Pourquoi devrais-je utiliser Ultralytics YOLO11 pour l'isolation d'objets dans les tâches de segmentation ?
Ultralytics YOLO11 fournit :
- Haute vitesse de détection et de segmentation d'objets en temps réel.
- Génération précise de boîtes englobantes et de masques pour un isolement précis des objets.
- Documentation complète et API facile à utiliser pour un développement efficace.
Explorez les avantages de l'utilisation de YOLO dans la documentation Segment Task.
Puis-je enregistrer des objets isolés, y compris l'arrière-plan, en utilisant Ultralytics YOLO11 ?
Oui, il s'agit d'une fonctionnalité intégrée à Ultralytics YOLO11. Utilisez l'argument save_crop
argument dans le predict()
méthode. Par exemple :
results = model.predict(source="path/to/your/image.jpg", save_crop=True)
En savoir plus sur le save_crop
argument dans le Arguments d'inférence du mode de prédiction section.