Skip to content

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 .

Exemple de segmentation d'objets isolés

Visite guidée d'une recette

  1. Voir la sectionUltralytics Quickstart Installation pour une démonstration rapide de l'installation des bibliothèques requises.


  2. 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 :

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

    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.


  3. 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étection class-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()]
    
    1. 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.
    2. 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.


  4. 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és person est illustrée à droite.

    Image de masque binaire

    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. Pour plus d'informations sur c.masks.xy voir Section des masques du mode prédictif.

    2. Ici, les valeurs sont intégrées dans np.int32 pour la compatibilité avec drawContours() de la fonction OpenCV.

    3. 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() : : Comme masks.xy est une liste contenant un seul Ă©lĂ©ment, cet Ă©lĂ©ment est extrait Ă  l'aide de la fonction pop() mĂ©thode.

    • .astype(np.int32) : : Utilisation masks.xy sera retournĂ© avec un type de donnĂ©es de float32mais cela ne sera pas compatible avec le logiciel OpenCV drawContours() ce qui aura pour effet de changer le type de donnĂ©es en int32 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Ă©e 1et l'entrĂ©e est composĂ©e de 2 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 le drawContours() 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.


  5. 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.

    Exemple Taille réelle Image d'un objet isolé Fond noir
    Exemple de sortie 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.

    Exemple de recadrage d'une image d'objet isolé sur fond noir

    # (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. 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 fichier xyxy oĂą xmin, ymin, xmaxet ymax 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 de float32 Ă  int32ce 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 format PNG 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.

    Exemple Taille réelle Objet isolé Image sans arrière-plan
    Exemple de sortie en taille réelle + arrière-plan transparent

    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.

    Exemple de recadrage d'une image d'objet isolé sans arrière-plan

    # (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. 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 fonction xyxy le format des coordonnĂ©es de la boĂ®te, qui correspondent aux points xmin, 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 de float32 Ă  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.


  6. 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
    # 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, et ci 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)
  1. La ligne qui remplit contour est combiné en une seule ligne ici, alors qu'il était divisé en plusieurs lignes ci-dessus.
  2. C'est à vous de décider ce que vous voulez mettre ici !
  3. Voir le mode prédictif pour plus d'informations.
  4. Voir Tâche de segment pour plus d'informations.
  5. En savoir plus sur Travailler avec des résultats
  6. 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 :

  1. Charger le modèle et lancer l'inférence :

    from ultralytics import YOLO
    
    model = YOLO("yolo11n-seg.pt")
    results = model.predict(source="path/to/your/image.jpg")
    
  2. Générer un masque binaire et dessiner des 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)
    
  3. Isoler l'objet Ă  l'aide du masque binaire :

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

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 :

  1. Sur fond noir :

    mask3ch = cv2.cvtColor(b_mask, cv2.COLOR_GRAY2BGR)
    isolated = cv2.bitwise_and(mask3ch, img)
    
  2. Avec un arrière-plan transparent :

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

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 :

  1. Récupère les coordonnées de la boîte de délimitation :

    x1, y1, x2, y2 = results[0].boxes.xyxy[0].cpu().numpy().astype(np.int32)
    
  2. Recadrer l'image isolée :

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

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 :

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

En savoir plus sur la save_crop dans l'argumentaire de la Arguments d'inférence du mode prédictif section.

📅C réé il y a 1 an ✏️ Mis à jour il y a 2 mois

Commentaires