5.8. Flood fill e glifi di rilevamento

Le primitive geometriche all’inizio di questa sezione pongono marcature in posizioni che l’applicazione già conosce. La composizione di immagini sovrappone un’immagine a un’altra. Un piccolo gruppo finale di metodi di disegno fa qualcosa di diverso: pone marcature la cui forma dipende da ciò che è già presente nell”immagine, o da ciò che qualche algoritmo precedente vi ha trovato.

5.8.1. Flood fill

flood_fill() parte da un singolo pixel – il seme – e cresce verso l’esterno, colorando ogni pixel che è sufficientemente simile al seme e connesso ad esso attraverso una catena di altri pixel simili. Il risultato è una regione riempita il cui confine è deciso dall’immagine stessa, non da qualcosa passato alla chiamata.

La forma più semplice accetta la coordinata del seme e un colore con cui riempire:

img.flood_fill(x=160, y=120, color=(0, 255, 0))

Due parametri di soglia controllano quanto aggressivamente cresce il riempimento. seed_threshold (una frazione normalizzata da 0.0 a 1.0) imposta quanto un pixel può differire dal valore del seme originale pur essendo ancora incluso. floating_threshold imposta quanto può differire da ciascun vicino già incluso. Le due soglie lavorano insieme: una floating_threshold generosa permette al riempimento di seguire un gradiente attraverso l’immagine, mentre una seed_threshold ristretta gli impedisce di allontanarsi troppo dal valore del seme anche lungo quel gradiente.

Alcuni flag affinano ulteriormente il risultato:

  • invert=True colora ogni pixel che non corrisponde – il complemento della regione corrispondente – anziché i pixel corrispondenti stessi.

  • clear_background=True azzera ogni pixel al di fuori della regione di riempimento. Utile per estrarre solo la regione riempita come maschera.

  • La parola chiave mask ha il suo significato consueto: i pixel disattivati nella maschera vengono lasciati intatti indipendentemente dal fatto che il riempimento li avrebbe altrimenti raggiunti.

Il flood fill è più utile per due pattern. Il primo è visualizzare ciò che qualche rilevatore di regioni ha trovato, riempiendo la regione rilevata con un colore distinto in modo che risalti rispetto al resto del frame. Il secondo è estrarre la regione stessa, combinando clear_background=True con un seme noto all’interno della regione e leggendo l’immagine risultante come maschera per operazioni successive.

5.8.2. Disegnare i risultati di rilevamento

Gli algoritmi di elaborazione delle immagini restituiscono spesso oggetti risultato che portano con sé sia una posizione sia una struttura aggiuntiva: un keypoint con un orientamento, un rilevamento di volto con un centroide distinto dal suo bounding box, un AprilTag con quattro punti d’angolo. Disegnarli bene – con un glifo che cattura la struttura, non solo un bounding box – è un pattern abbastanza ricorrente da indurre il modulo a esporre due helper per farlo.

draw_keypoints() accetta sia un descrittore di keypoint restituito da un estrattore di caratteristiche, sia un semplice elenco di triple (x, y, rotation), e disegna un piccolo glifo in ciascun punto. Il glifo porta con sé sia la posizione sia l’orientamento: un cerchio attorno al punto più una linea che esce dal centro a indicare la rotazione. Quella visualizzazione in una sola chiamata è il modo più semplice per verificare che un estrattore di keypoint stia restituendo gli orientamenti che l’applicazione si aspetta.

draw_detection() accetta una tupla a sei elementi (rx, ry, rw, rh, cx, cy) – il rettangolo di delimitazione più un centroide riportato separatamente – e disegna entrambi in una volta: un rettangolo attorno al bounding box, una croce in corrispondenza del centroide e, facoltativamente, un’etichetta di testo all’angolo del rettangolo. La forma corrisponde a ciò che tipicamente riporta un rilevamento di una rete neurale o un tracker basato su template, dove il centroide è una posizione più precisa di quella che fornirebbe il centro del bounding box.

Entrambi i metodi per i glifi sono livelli di comodità sopra le primitive geometriche all’inizio di questa sezione. Un’applicazione può sempre riprodurre la stessa visualizzazione chiamando direttamente draw_rectangle(), draw_circle(), draw_cross() e draw_string(); i metodi per i glifi si limitano a risparmiare la contabilità per i pattern che ricorrono di continuo.

Con le primitive geometriche per la geometria nota, la composizione di immagini per gli overlay, il flood fill per le regioni derivate dall’immagine e i glifi di rilevamento per i pattern di visualizzazione standard, il toolkit di disegno è completo. Qualsiasi cosa un’applicazione abbia bisogno di rendere visibile l’output di un algoritmo dispone di un metodo sulla superficie che ve la pone.