TNI+VO · Exercice de Programmation

EP08_12 — 🔴 Segmentation d’instances sur image réelle : objets géométriques

8.14.12 EP08_12 🔴 Segmentation d’instances sur image réelle : objets géométriques

L’exemple de segmentation classique de ce chapitre a séparé des « instances » de pièces de monnaie par déconnexion spatiale dans le masque binaire résultant du seuillage d’Otsu. Dans cet exercice, vous appliquerez la même idée — mais cette fois sur une image réelle avec des objets géométriques variés — en enchaînant le prétraitement, la binarisation, l’extraction de contours (cv2.findContours) et la validation du résultat par rapport à une référence de bounding boxes.

Contrairement à l’exercice précédent (étiquetage sur un masque déjà prêt), ici vous partez de l’image originale : la qualité de votre segmentation dépend directement des choix de prétraitement (filtrage, seuillage, opérations morphologiques) effectués avant d’étiqueter les composants.

8.14.12.1 📋 Directives d’implémentation

  1. Entrée : utiliser l’image 00000.jpg.
  2. Prétraitement et segmentation : appliquer les étapes nécessaires (filtrage, binarisation et opérations morphologiques) pour séparer automatiquement les objets du fond, sans recadrages manuels.
  3. Étiquetage et mesure : pour chaque objet segmenté, déterminer :
    • l’aire ;
    • le centre de masse (centroïde) ;
    • le type, selon l’ensemble obj2.
  4. Annotation visuelle : écrire, à l’intérieur de chaque objet, son aire et le sigle du type (obj2).
  5. Validation (IoU) : calculer l’Intersection over Union (IoU) entre la bounding box détectée (cv2.boundingRect) et la bounding box de référence du type correspondant. Un objet est considéré comme correctement segmenté uniquement s’il existe exactement une bounding box du type correct avec IoU ≥ 0,5.
  6. Sortie : imprimer, pour chaque objet détecté, son identifiant, son type et s’il a été validé avec succès (acertou=1) ou non. L’impression doit suivre l’ordre des classes de obj2 (0=Tria … 8=Cruz) ; au sein de la même classe, trier les objets par coordonnée verticale du centroïde (cy) croissante. À la fin, imprimer la précision globale.

8.14.12.2 📌 Contraintes informatiques

  • Sans recadrage manuel : toute la segmentation doit être effectuée sur l’image complète.

  • Ensemble de classes fixe :

    obj  = ['Triangulo','Quadrado','Pendagono','Hexagono','Heptagono','Circulo',
            'Elipse','Estrela','Cruz']
    obj2 = ['Tria','Quad','Pent','Hexa','Hept','Circ','Elip','Estr','Cruz']
  • Dimensions de l’image : 608×608 pixels — utilisées pour dénormaliser les coordonnées du fichier TXT.

  • Validation par centre de masse : un objet n’est considéré comme correctement segmenté que si son centroïde se trouve strictement à l’intérieur de la bounding box de référence correspondant au même type d’objet.

8.14.12.3 🧠 Fondements théoriques

Élément Rôle dans la segmentation d’instances
Prétraitement (filtrage, seuillage) Étape qui produit le masque binaire à partir de l’image d’intensité originale
cv2.findContours Extrait les contours des composants connectés dans le masque binaire
Moments géométriques (cv2.moments) Permettent de calculer le centre de masse (centroïde) de chaque contour
approxPolyDP / sommets Aide à la classification du type d’objet (nombre de côtés approximatif)
Validation via bounding box Confirme si l’instance segmentée correspond spatialement à un objet de la référence, en mesurant la précision de la méthode

8.14.12.4 📌 Exemple de sortie attendue

Objeto 1: tipo=Tria, validado=True
...
Acurácia: 88.89%

Paramètres fixes pour la reproductibilité : pour que la sortie corresponde à la référence de correction automatique, utilisez exactement : filtre d’aire minimale de 300 pixels ; cv2.approxPolyDP avec epsilon = 0.02 * périmètre ; seuil de solidité 0,92 et nombre de sommets ≥ 9 (avec ≥ 11 pour différencier Cruz de Estrela) pour les formes concaves ; rapport d’aspect 1,15 pour différencier Círculo de Elipse ; seuil IoU = 0,5 lors de la validation.

8.14.12.5 📌 Fichiers de référence (.jpg et .txt)

Pour le débogage local, deux fichiers de référence sont fournis (inclus dans cette livraison ; lors de leur intégration au dépôt du chapitre, enregistrez-les dans all/cap08/dados/EP08/) :

  • 📥 Image (00000.jpg) : image d’objets géométriques utilisée comme entrée de l’exercice. L’objectif est de segmenter automatiquement chaque objet, de déterminer son type et de calculer ses mesures.
  • 📥 Référence (00000.txt) : fichier contenant les bounding boxes normalisées des objets présents dans l’image. Chaque ligne contient l’identifiant de la classe et les coordonnées normalisées des coins supérieur gauche et inférieur droit, utilisé pour valider automatiquement la segmentation.

La Figure 8.26 présente l’image d’entrée et la même image avec les bounding boxes dessinées à partir du fichier de référence.

import os
import urllib.request
from morph import mm

def garantir_e_baixar(nome):
    pasta = "dados/EP12"
    caminho = os.path.join(pasta, nome)

    os.makedirs(pasta, exist_ok=True)

    if not os.path.exists(caminho):
        url = (
            "https://raw.githubusercontent.com/"
            "fzampirolli/pdi-vc/master/all/cap08/dados/EP12/"
            + nome
        )
        print(f"Téléchargement {nome}...")
        urllib.request.urlretrieve(url, caminho)

    return caminho

img_arq = garantir_e_baixar("00000.jpg")
txt_arq = garantir_e_baixar("00000.txt")

img = mm.read(img_arq)
img_bb = mm.showBoundBox(img, txt_arq, fmt="yolo", show=False)

mm.show(
    [img, img_bb],
    titles=[
        "Image originale",
        "Bounding boxes de la correction"
    ],
    cols=2,
    figsize=(10,5)
)
Figure 8.26: Simulateur EP08_12 : Image utilisée dans l’EP08_12. À gauche, l’image originale. À droite, l’image avec les bounding boxes du fichier de correction.
🧮 Simulateur EP08_12 : Précision de segmentation sur objets multiples 🟢 réussi si IoU ≥ seuil et type correct

Chaque forme a une boundbox de référence (rectangle en pointillés, juste autour de la forme) et une boundbox détectée (rectangle plein, décalée/bruitée). Ajustez le bruit, le biais et le seuil d'IoU pour voir la validation changer.

0
0
0.50
id type réel type détecté IoU ≥ seuil réussi
Figure 8.27: Simulateur EP08_12 : Précision de Segmentation sur Objets Multiples (IoU)
%%writefile EP08_12.py
# Code Python
Overwriting EP08_12.py
TestSuite("EP08_12.py").run()
✔️ EP08_12.cases existe déjà dans casos/
📋 1 cas chargé(s) depuis casos/EP08_12.cases

🔍 Test de Python : EP08_12.py
⚠️ EP08_12.py : fichier vide (moins de 3 lignes). Tests ignorés.