8.14.4 EP08_04 🟢 IoU e Soppressione Non-Massima (NMS)
La figura di questa sezione ha mostrato l’effetto della Soppressione Non-Massima su un insieme di riquadri prodotti da un rilevatore di tipo sliding window: più rilevazioni ridondanti per oggetto sono state ridotte a un singolo riquadro per oggetto. Ti è stato affidato il compito di reimplementare, byte per byte, le due funzioni che hanno prodotto quel risultato — calcola_iou e soppressione_non_massima — per confermare, con le tue mani, esattamente i numeri presentati nel capitolo.
8.14.4.1 📋 Linee Guida di Implementazione
Input: Leggi l’intero \(N\) (numero di riquadri) e il reale \(\tau\) (soglia IoU). Successivamente, leggi \(N\) righe, ciascuna con cinque reali \(x_{min}\ y_{min}\ x_{max}\ y_{max}\ \text{score}\).
Intersezione su Unione: Per due riquadri \(A\) e \(B\), \[ \mathrm{IoU}(A,B) = \frac{\text{area}(A \cap B)}{\text{area}(A \cup B)}, \] con area di intersezione nulla quando i riquadri non si sovrappongono.
Algoritmo NMS (esattamente come descritto nel capitolo):
Ordina i riquadri per
scoredecrescente (i pareggi mantengono l’ordine di lettura originale).Seleziona il riquadro con il punteggio più alto tra quelli rimanenti; aggiungilo all’output e rimuovilo dalla lista.
Scarta, dalla lista rimanente, tutti i riquadri il cui IoU con il riquadro selezionato sia maggiore o uguale a \(\tau\) — solo i riquadri con \(\mathrm{IoU} < \tau\) rimangono candidati.
Ripeti i passaggi (b)–(c) finché la lista dei rimanenti non è vuota.
Output: Per ogni riquadro mantenuto, nell’ordine in cui è stato selezionato, stampa il suo indice originale (posizione di lettura, a partire da \(0\)) e il suo
score, con 2 cifre decimali. Alla fine, stampaTotale mantenuti: X.
8.14.4.2 📌 Vincoli Computazionali
- Attenzione alla direzione della soglia: contrariamente a quanto si potrebbe supporre, un riquadro viene soppresso quando \(\mathrm{IoU} \ge \tau\) (non solo quando \(\mathrm{IoU} > \tau\)) — segui esattamente questo criterio, lo stesso del codice di riferimento del capitolo.
- Indici originali: l’output fa riferimento alla posizione di lettura di ciascun riquadro nell’input, non alla sua posizione dopo l’ordinamento per
score. - Area senza somma di 1 pixel: usa area \(= (x_{max}-x_{min}) \times (y_{max}-y_{min})\), esattamente come nel capitolo (senza l’aggiustamento “+1” talvolta usato in altre convenzioni).
8.14.4.3 🧠 Fondamenti Teorici
| Elemento | Ruolo nel post-elaborazione |
|---|---|
| IoU | Quantifica la sovrapposizione spaziale tra due riquadri delimitatore |
| Sliding window (Haar Cascade) | Produce tipicamente più rilevazioni sovrapposte per lo stesso oggetto, in posizioni e scale vicine |
| Soglia \(\tau\) | Controlla l’aggressività della soppressione: troppo bassa fonde oggetti vicini; troppo alta lascia passare ridondanze |
Ordinamento per score |
Garantisce che, tra riquadri ridondanti, quello con maggiore confidenza sopravviva sempre |
8.14.4.4 📦 Specifica di Input e Output (VPL)
Input:
- Riga 1: Intero \(N\) e reale \(\tau\).
- Prossime \(N\) righe: cinque reali \(x_{min}\ y_{min}\ x_{max}\ y_{max}\ \text{score}\).
Output:
- Una riga per riquadro mantenuto, nell’ordine di selezione:
indice score(score con 2 cifre decimali). - Ultima riga:
Totale mantenuti: X.
8.14.4.5 📌 Esempi
| Input | Output | Osservazione |
|---|---|---|
| 5 0.4 50 50 150 150 0.90 60 55 155 145 0.75 58 60 160 150 0.60 300 300 400 420 0.95 310 305 395 415 0.70 |
3 0.95 0 0.90 Totale mantenuti: 2 |
Esattamente l’esempio della figura del capitolo: 5 riquadri ridondanti (2 oggetti) diventano 2 rilevazioni finali. L’IoU tra il 1° e il 2° riquadro è \(\approx 0{,}775\), ben al di sopra di \(\tau=0{,}4\). |
%%writefile EP08_04.py
# Codice PythonOverwriting EP08_04.py
TestSuite("EP08_04.py").run()✔️ EP08_04.cases esiste già in casos/
📋 6 caso/i caricato/i da casos/EP08_04.cases
🔍 Test di Python: EP08_04.py
⚠️ EP08_04.py: file vuoto (meno di 3 righe). Test saltati.