5.12. Sogliatura binaria¶
Molte pipeline di elaborazione delle immagini si riducono a una domanda su ciascun pixel: questa luminosità rientra nell’intervallo che significa «primo piano»? Questo colore è abbastanza vicino al rosso da essere il marcatore che l’applicazione sta tracciando? Questo pixel fa parte dell’insieme di candidati che la fase successiva della pipeline dovrebbe esaminare? La sogliatura è l’operazione che trasforma queste domande in una risposta binaria in ogni posizione – attivo se il pixel corrisponde, disattivo in caso contrario – e riduce l’intera immagine a una maschera su cui il resto della pipeline può lavorare.
5.12.1. Il metodo binary¶
Il metodo binary() esegue questa classificazione su ogni pixel in un’unica chiamata. Accetta un elenco di intervalli di soglia – le condizioni che un pixel può soddisfare per contare come «attivo» – e riscrive l’immagine in modo che ogni pixel che ha soddisfatto almeno uno degli intervalli venga impostato al valore massimo del formato e ogni pixel che non lo ha fatto venga impostato a zero. Il risultato è la maschera binaria che il resto della pipeline può usare direttamente.
Nella forma più semplice, l’elenco di soglie ha un solo intervallo e la chiamata restituisce una maschera dei pixel in quell’intervallo:
img.binary([(120, 255)])
La forma a elenco è ciò che rende potente binary. Una pipeline che vuole tracciare due marcatori colorati, oppure un intervallo di luminosità più un picco di saturazione isolato, passa entrambi gli intervalli nello stesso elenco e ottiene una singola maschera di output che copre tutte le corrispondenze.
La sogliatura trasforma un’immagine a valori continui in una maschera binaria: ogni pixel all’interno dell’intervallo di soglia diventa il valore massimo del formato, ogni pixel al di fuori diventa zero.¶
5.12.2. La tupla in scala di grigi¶
Per un’immagine in scala di grigi, ogni voce nell’elenco di soglie è una tupla a due elementi (lo, hi) che descrive un intervallo di luminosità inclusivo. I pixel con valori compresi tra lo e hi (inclusi) corrispondono; tutto ciò che è al di fuori di quell’intervallo no. Gli schemi naturali sono semplici:
(0, 60)corrisponde ai pixel scuri – tutto, dal nero fino al grigio profondo.(180, 255)corrisponde ai pixel luminosi – tutto, dal grigio chiaro fino al bianco.(100, 160)corrisponde ai pixel grigio medio – una banda nel mezzo dell’intervallo di luminosità.
L’ordine dei due valori all’interno di una tupla non ha importanza; il metodo li scambia internamente se lo è maggiore di hi, quindi (60, 0) funziona allo stesso modo di (0, 60).
5.12.3. La tupla LAB per il colore¶
Per un’immagine RGB565, ogni voce è una tupla a sei elementi (l_lo, l_hi, a_lo, a_hi, b_lo, b_hi) che descrive un intervallo inclusivo nello spazio colore LAB anziché direttamente in rosso, verde e blu. Le soglie sono L (luminosità), A (asse cromatico dal verde al rosso) e B (asse cromatico dal blu al giallo), ciascuna confrontata con il valore del pixel in quel canale.
Il motivo per passare attraverso LAB anziché applicare la soglia direttamente a RGB è la proprietà attorno alla quale è stato progettato lo spazio colore LAB: LAB separa la luminosità dalla croma. Due pixel che mostrano lo stesso colore ma con luminosità diverse finiscono a valori L diversi ma a valori A e B all’incirca uguali. Quella separazione consente agli intervalli di soglia di descrivere un colore tramite la sua posizione sugli assi A e B e di lasciare l’intervallo L completamente aperto per accettare quel colore a ogni livello di luminosità, dall’ombra alle alte luci. Una soglia basata su RGB non può farlo – qualsiasi cambiamento nell’illuminazione sposta contemporaneamente tutti e tre i valori R, G, B, e un tracker costruito su soglie RGB si rompe la prima volta che una nuvola passa davanti al sole.
Lo schema pratico: scegliere gli intervalli A e B che descrivono il colore che l’applicazione sta tracciando, e lasciare l’intervallo L ampio – spesso (0, 100) per accettare qualsiasi luminosità – a meno che l’applicazione non voglia specificamente applicare la soglia sia sulla luminosità sia sul colore.
Per le tuple con meno di sei valori, le componenti mancanti assumono per impostazione predefinita l’intervallo massimo (nessun vincolo su quell’asse). Una tupla a due elementi (l_lo, l_hi) in un elenco di soglie RGB565 applica quindi la soglia solo sulla luminosità e corrisponde a ogni colore.
Nota
Un intervallo L realmente completamente aperto ha un’insidia all’estremità inferiore. Man mano che la luminosità scende verso lo zero, ogni colore converge verso il nero, con i valori A e B che collassano verso lo zero e finiscono dominati dal rumore – così i pixel scuri possono finire negli intervalli A e B ed essere tracciati come colore di destinazione. Se le regioni nere della scena si illuminano come corrispondenze, aumentare l_lo finché non ne escono.
5.12.4. Flag¶
Tre argomenti keyword controllano l’output:
invert=Trueinverte il risultato. Ogni pixel che avrebbe corrisposto diventa zero, e ogni pixel che sarebbe stato zero diventa il valore massimo. Utile quando il modo naturale di descrivere il primo piano è in base a ciò che non è.zero=Truecambia la modalità di funzionamento: i pixel corrispondenti vengono azzerati e i pixel non corrispondenti mantengono i loro valori originali. Da usare quando l’obiettivo è cancellare i pixel corrispondenti dall’immagine anziché ridurre l’immagine a una loro maschera binaria.to_bitmap=Truerestituisce il risultato come immagineBINARYanziché sovrascrivere il formato esistente della sorgente. Il risultato a un bit per pixel è ciò che gli argomenti di maschera successivi accettano direttamente, e la conversione spesso risparmia la pressione di memoria derivante dal trasportare una maschera a formato completo.
La maschera e la ROI seguono la stessa convenzione del resto dell’interfaccia: un rettangolo roi limita l’operazione a una sotto-area, un’immagine mask la limita a uno schema arbitrario di posizioni.
5.12.5. In place per impostazione predefinita¶
Come le operazioni aritmetiche, binary viene eseguito in place per impostazione predefinita: i pixel dell’immagine sorgente vengono sovrascritti con l’output binario, e i valori originali scompaiono dopo la chiamata. La forma to_bitmap=True è l’alternativa quando la sorgente deve essere preservata e l’output deve essere un’immagine BINARY appena allocata. È accettata anche la forma copy=True per un risultato dello stesso formato su un nuovo buffer.