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'accomplir ceci en utilisant lemode Predictde Ultralytics .
Visite guidée d'une recette
-
Voir la sectionUltralytics Quickstart Installation pour une démonstration rapide de l'installation des bibliothèques requises.
-
Charger un modèle et l'exécuter
predict()
sur une source.from ultralytics import YOLO # Load a model model = YOLO("yolo11n-seg.pt") # Run inference results = model.predict()
Pas d'arguments de prédiction ?
Si aucune source n'est spécifiée, les images d'exemple de la bibliothèque seront utilisées :
Cela permet d'effectuer des tests rapides avec l'outil
predict()
méthode.Pour plus d'informations sur les modèles de segmentation, consultez le site web de la Commission européenne. Segment Tâche page. Pour en savoir plus sur
predict()
Voir la méthode Mode prédictif de la documentation.
-
Itérer maintenant 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és 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 la détection, reportez-vous à la section Encadrés pour le mode prédictif.
- Pour en savoir plus
predict()
résultats voir Travailler avec les résultats du mode Predict
For-Loop
Une image unique n'itère la première boucle qu'une seule fois. Une image unique ne comportant qu'une seule détection n'effectuera qu'une seule itération de chaque boucle.
-
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 produits détectésperson
est illustrée à 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 prédictif. -
Ici, les valeurs sont intégrées dans
np.int32
pour la compatibilité avecdrawContours()
de la fonction OpenCV. -
Le logiciel OpenCV
drawContours()
La fonction s'attend Ă ce que les contours aient une forme de[N, 1, 2]
pour plus de détails.
Étendre pour comprendre ce qui se passe lors de la définition de la
contour
variable.-
c.masks.xy
: : Fournit les coordonnées des points du contour du masque au format(x, y)
. Pour plus de détails, voir le Section des masques du mode prédictif. -
.pop()
: : Commemasks.xy
est une liste contenant un seul élément, cet élément est extrait à l'aide de la fonctionpop()
méthode. -
.astype(np.int32)
: : Utilisationmasks.xy
sera retourné avec un type de données defloat32
mais cela ne sera pas compatible avec le logiciel OpenCVdrawContours()
ce qui aura pour effet de changer 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. Les valeurs-1
indique que le nombre de valeurs sur cette dimension est flexible.
DĂ©velopper pour une explication de la
drawContours()
configuration.-
Encapsuler le
contour
entre crochets,[contour]
s'est avéré efficace pour générer le masque de contour souhaité lors des essais. -
La valeur
-1
spécifiée pour ledrawContours()
indique à la fonction de dessiner tous les contours présents dans l'image. -
Le
tuple
(255, 255, 255)
représente la couleur blanche, qui est la couleur souhaitée pour dessiner le contour dans ce masque binaire. -
L'ajout de
cv2.FILLED
colorera de la même manière tous les pixels entourés par la limite du contour, dans ce cas, tous les pixels entourés seront blancs. -
Voir Documentation OpenCV sur
drawContours()
pour plus d'informations.
-
-
Ensuite, il y a deux options pour faire avancer l'image à partir de ce point et une option ultérieure pour chacune d'entre elles.
Options d'isolation des 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 converti d'une image à un canal 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 mélange.
-
L'image originale et le masque binaire à trois canaux sont fusionnés à l'aide de la fonction OpenCV
bitwise_and()
. Cette opération permet de conserver seulement les valeurs des pixels qui sont supérieures à zéro(> 0)
des deux images. Étant donné que 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 se superposent au contour.
Isoler avec des pixels noirs : Sous-options
Image en taille réelle
Aucune étape supplémentaire n'est nécessaire pour conserver l'image en taille réelle.
Image de l'objet recadré
Des étapes supplémentaires sont nécessaires pour recadrer l'image afin de n'inclure que 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 de la boîte englobante, voir la section Boîtes du mode Prévision.
Que fait ce code ?
-
Le
c.boxes.xyxy.cpu().numpy()
récupère les boîtes de délimitation sous la forme d'un tableau NumPy dans le fichierxyxy
oĂąxmin
,ymin
,xmax
etymax
représentent les coordonnées du rectangle de la boîte englobante. Voir Section des boîtes du mode prédictif pour plus de détails. -
Le
squeeze()
supprime toutes les dimensions inutiles du tableau NumPy, en s'assurant 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, qui passe defloat32
Ăint32
ce qui les rend compatibles avec le recadrage d'images Ă l'aide de tranches d'index. -
Enfin, la région de la boîte englobante est découpée dans l'image à l'aide d'un découpage par index. Les limites sont définies par la fonction
[ymin:ymax, xmin:xmax]
coordonnées de la boîte de délimitation de la détection.
# Isolate object with transparent background (when saved as PNG) isolated = np.dstack([img, b_mask])
Comment cela fonctionne-t-il ?
- Utilisation du logiciel NumPy
dstack()
(empilement de tableaux le long de l'axe de profondeur) en conjonction avec le masque binaire généré, créera une image à quatre canaux. Cela permet à tous les pixels situés en dehors du contour de l'objet d'être transparents lors de l'enregistrement au formatPNG
fichier.
Isoler avec des pixels transparents : Sous-options
Image en taille réelle
Aucune étape supplémentaire n'est nécessaire pour conserver l'image en taille réelle.
Image de l'objet recadré
Des étapes supplémentaires sont nécessaires pour recadrer l'image afin de n'inclure que 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 de la boîte englobante, voir la section Boîtes du mode Prévision.
Que fait ce code ?
-
Lors de l'utilisation de
c.boxes.xyxy.cpu().numpy()
les boîtes englobantes sont renvoyées sous la forme d'un tableau NumPy, à l'aide de la fonctionxyxy
le format des coordonnées de la boîte, qui correspondent aux pointsxmin, ymin, xmax, ymax
pour la boîte de délimitation (rectangle), voir Section des boîtes du mode prédictif pour plus d'informations. -
Ajout
squeeze()
permet de s'assurer 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, qui passe defloat32
Ăint32
qui sera compatible avec le recadrage de l'image Ă l'aide de tranches d'index. -
Enfin, la région de l'image pour la boîte de délimitation est découpée à l'aide d'un découpage par index, où les limites sont définies à l'aide de la fonction
[ymin:ymax, xmin:xmax]
coordonnées de la boîte de délimitation de la détection.
Que se passe-t-il si je veux que l'objet recadré comprenne l' arrière-plan ?
Il s'agit d'une fonctionnalité intégrée à la bibliothèque Ultralytics . Voir la page
save_crop
argument pour Arguments d'inférence du mode prédictif pour plus de détails.
-
-
La suite est entièrement laissée à l'appréciation du développeur. Un exemple basique d'une étape possible (enregistrement de l'image dans un fichier pour une utilisation ultérieure) est présenté.
- REMARQUE : cette étape est facultative et peut être ignorée si elle n'est pas nécessaire pour votre cas d'utilisation spécifique.
Exemple Étape finale
- 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 de la détection d'objets (en cas d'instances multiples portant le même nom de classe).
Exemple de code 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 certaines ou toutes les commandes contenues dans la section for
-Mais il s'agit là d'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 qui remplit
contour
est combiné en une seule ligne ici, alors qu'il était divisé en plusieurs lignes ci-dessus. - C'est à vous de décider ce que vous voulez mettre ici !
- Voir le mode prédictif pour plus d'informations.
- Voir Tâche de segment pour plus d'informations.
- En savoir plus sur Travailler avec des résultats
- En savoir plus sur les résultats du masque de segmentation
FAQ
Comment isoler les objets en utilisant Ultralytics YOLO11 pour les tâches de segmentation ?
Pour isoler des objets à l'aide de Ultralytics YOLO11 , procédez comme suit :
-
Charger le modèle et lancer l'inférence :
-
Générer un masque binaire et dessiner des contours :
-
Isoler l'objet Ă l'aide du masque binaire :
Pour plus d'informations, reportez-vous au guide sur le mode prédictif et à la tâche de segmentation.
Quelles sont les options disponibles pour enregistrer les objets isolés après la segmentation ?
Ultralytics YOLO11 offre deux options principales pour l'enregistrement d'objets isolés :
-
Sur fond noir :
-
Avec un arrière-plan transparent :
Pour plus de détails, consultez la section Mode prédictif.
Comment puis-je recadrer des objets isolés dans leur boîte de délimitation à l'aide de Ultralytics YOLO11 ?
Pour recadrer des objets isolés dans leur boîte de délimitation :
-
Récupère les coordonnées de la boîte de délimitation :
-
Recadrer l'image isolée :
Pour en savoir plus sur les résultats de la boîte englobante, consultez la documentation sur le mode prédictif.
Pourquoi utiliser Ultralytics YOLO11 pour isoler les objets dans les tâches de segmentation ?
Ultralytics YOLO11 fournit :
- Détection et segmentation d'objets en temps réel et à grande vitesse.
- Génération précise de boîtes de délimitation et de masques pour une isolation précise des objets.
- Une documentation complète et une API facile à utiliser pour un développement efficace.
Explorez les avantages de l'utilisation de YOLO dans la documentation sur les tâches de segmentation.
Puis-je enregistrer des objets isolés, y compris l'arrière-plan, en utilisant Ultralytics YOLO11 ?
Oui, il s'agit d'une fonction intégrée dans Ultralytics YOLO11 . Utilisez la fonction save_crop
dans l'argumentaire de la predict()
méthode. Par exemple :
En savoir plus sur la save_crop
dans l'argumentaire de la Arguments d'inférence du mode prédictif section.