EDI+VA · Esercizio di Programmazione

EP08_12 — 🔴 Segmentazione di Istanza in Immagine Reale: Oggetti Geometrici

8.14.12 EP08_12 🔴 Segmentazione di Istanza in Immagine Reale: Oggetti Geometrici

L’esempio classico di segmentazione di questo capitolo ha separato le “istanze” delle monete tramite disconnessione spaziale nella maschera binaria risultante dalla sogliatura di Otsu. In questo esercizio applicherai la stessa idea — ma ora su un’immagine reale con oggetti geometrici vari — concatenando pre-elaborazione, binarizzazione, estrazione dei contorni (cv2.findContours) e validazione del risultato rispetto a un ground truth di bounding box.

A differenza dell’esercizio precedente (etichettatura su maschera già pronta), qui parti dall’immagine originale: la qualità della tua segmentazione dipende direttamente dalle scelte di pre-elaborazione (filtraggio, sogliatura, operazioni morfologiche) effettuate prima di etichettare i componenti.

8.14.12.1 📋 Linee Guida di Implementazione

  1. Input: utilizzare l’immagine 00000.jpg.
  2. Pre-elaborazione e segmentazione: applicare le fasi necessarie (filtraggio, binarizzazione e operazioni morfologiche) per separare automaticamente gli oggetti dallo sfondo, senza ritagli manuali.
  3. Etichettatura e misurazione: per ogni oggetto segmentato, determinare:
    • area;
    • centro di massa (centroide);
    • tipo, secondo il set obj2.
  4. Annotazione visiva: scrivere, all’interno di ciascun oggetto, la sua area e la sigla del tipo (obj2).
  5. Validazione (IoU): calcolare l’Intersection over Union (IoU) tra la bounding box rilevata (cv2.boundingRect) e la bounding box di ground truth del tipo corrispondente. Un oggetto è considerato correttamente segmentato solo se esiste esattamente una bounding box del tipo corretto con IoU ≥ 0,5.
  6. Output: stampare, per ogni oggetto rilevato, il suo identificatore, il tipo e se è stato validato con successo (acertou=1) o meno. La stampa deve seguire l’ordine delle classi di obj2 (0=Tria … 8=Cruz); all’interno della stessa classe, ordinare gli oggetti per coordinata verticale del centroide (cy) crescente. Alla fine, stampare l’accuratezza complessiva.

8.14.12.2 📌 Vincoli Computazionali

  • Niente ritaglio manuale: tutta la segmentazione deve essere eseguita sull’immagine completa.

  • Set di classi fisso:

    obj  = ['Triangulo','Quadrado','Pendagono','Hexagono','Heptagono','Circulo',
            'Elipse','Estrela','Cruz']
    obj2 = ['Tria','Quad','Pent','Hexa','Hept','Circ','Elip','Estr','Cruz']
  • Dimensione dell’immagine: 608×608 pixel — utilizzata per denormalizzare le coordinate del file TXT.

  • Validazione tramite centro di massa: un oggetto è considerato correttamente segmentato solo se il suo centroide si trova strettamente all’interno della bounding box di ground truth corrispondente allo stesso tipo di oggetto.

8.14.12.3 🧠 Fondamenti Teorici

Elemento Ruolo nella segmentazione di istanza
Pre-elaborazione (filtraggio, sogliatura) Fase che produce la maschera binaria a partire dall’immagine di intensità originale
cv2.findContours Estrae i contorni dei componenti connessi nella maschera binaria
Momenti geometrici (cv2.moments) Consentono di calcolare il centro di massa (centroide) di ogni contorno
approxPolyDP / vertici Aiuta nella classificazione del tipo di oggetto (numero approssimativo di lati)
Validazione tramite bounding box Conferma se l’istanza segmentata corrisponde spazialmente a un oggetto del ground truth, misurando l’accuratezza del metodo

8.14.12.4 📌 Esempio di Output Atteso

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

Parametri fissi per la riproducibilità: affinché l’output corrisponda al ground truth di correzione automatica, utilizza esattamente: filtro di area minima di 300 pixel; cv2.approxPolyDP con epsilon = 0.02 * perimetro; soglia di solidità 0.92 e conteggio dei vertici ≥ 9 (con ≥ 11 per distinguere Cruz da Estrela) per forme concave; rapporto d’aspetto 1.15 per distinguere Circulo da Elipse; soglia IoU = 0.5 nella validazione.

8.14.12.5 📌 File di Riferimento (.jpg e .txt)

Per il debug locale, sono resi disponibili due file di riferimento (inclusi in questa consegna; quando li integri nel repository del capitolo, salvali in all/cap08/dados/EP08/):

  • 📥 Immagine (00000.jpg): immagine di oggetti geometrici utilizzata come input dell’esercizio. L’obiettivo è segmentare automaticamente ogni oggetto, determinarne il tipo e calcolarne le misure.
  • 📥 Ground Truth (00000.txt): file contenente le bounding box normalizzate degli oggetti presenti nell’immagine. Ogni riga contiene l’identificatore della classe e le coordinate normalizzate degli angoli superiore sinistro e inferiore destro, utilizzato per validare automaticamente la segmentazione.

La Figura 8.26 presenta l’immagine di input e la stessa immagine con le bounding box disegnate a partire dal file di ground truth.

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"Scaricamento {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=[
        "Immagine originale",
        "Bounding boxes del riferimento"
    ],
    cols=2,
    figsize=(10,5)
)
Figura 8.26: Simulatore EP08_12: Immagine utilizzata nell’EP08_12. A sinistra, l’immagine originale. A destra, l’immagine con le bounding boxes del file di riferimento.
🧮 Simulatore EP08_12: Accuratezza della Segmentazione su Oggetti Multipli 🟢 indovinato se IoU ≥ soglia e tipo corretto

Ogni forma ha un boundbox di riferimento (rettangolo tratteggiato, aderente alla forma) e un boundbox rilevato (rettangolo pieno, spostato/rumoroso). Regola rumore, bias e soglia IoU per vedere cambiare la validazione.

0
0
0.50
id tipo reale tipo rilevato IoU ≥ soglia indovinato
Figura 8.27: Simulatore EP08_12: Accuratezza della Segmentazione su Multipli Oggetti (IoU)
%%writefile EP08_12.py
# Codice Python
Overwriting EP08_12.py
TestSuite("EP08_12.py").run()
✔️ EP08_12.cases esiste già in casos/
📋 1 caso/i caricato/i da casos/EP08_12.cases

🔍 Test di Python: EP08_12.py
⚠️ EP08_12.py: file vuoto (meno di 3 righe). Test saltati.