lunedì 19 marzo 2012

2012, demosaicizzazione, ultima frontiera!

Premessa

Quando si scatta in RAW (in PEF, per chi usa Pentax), si sta scattando una foto usando una matrice di colori, per la maggior parte dei casi secondo uno schema detto "Bayer".



Lo schema Bayer consta di fotodiodi schermati in modo che possano ricevere solo fotoni nella frequenza del verde, del rosso e del blu. Da notare il numero doppio di fotodiodi "verdi" rispetto agli altri, legato alla fisiologia del nostro occhio, che dà luogo ad un rumore in crominanza nel canale del verde in genere piuttosto ridotto rispetto agli altri due canali.

Ovviamente una fotografia con la matrice di Bayer nuda e cruda è pressoché inutilizzabile. L'operazione matematica che si effettua per passare dal segnale registrato dal sensore (il cosiddetto file RAW) al file "immagine" desiderato è chiamata demosaicizzazione, e consiste sostanzialmente nel prendere sottoinsiemi di pixel e trasformarli in un colore in RGB tramite operazioni matematiche per poter ricostruire i colori "mancanti" nei vari pixel.
In base all'algoritmo utilizzato si potrà avere un maggiore o minore dettaglio, un maggiore o minore rumore, o la presenza di artefatti legati all'operazione matematica condotta dall'algoritmo di demosaicizzazione.

Tipicamente, gli artefatti sono legati all'effetto Moiré ", e tra questi molto comuni sono quelli "a labirinto".
L'effetto Moiré è un effetto ottico molto presente lì dove si opera con matrici di punti (quindi sensori fotografici, scanner, monitor o stampa tipografica, ma anche una stampante laser monocromatica può dare effetto Moiré con alcuni pattern), ed il soggetto in stampa o inquadrato possiede un livello di dettaglio tale da essere sostanzialmente dello stesso ordine di grandezza della densità di pixel del sensore o della risoluzione impostata per la stampa o per la visualizzazione (in questi casi si parla di frequenza di Nyquist). L'effetto Moiré può creare o segnali inesistenti (come certe forme geometriche che sembrano esserci in certi pattern, una sorta di "illusione ottica") o falsare i colori o entrambe le cose.



I difetti "a labirinto" sono una specie particolare di effetto Moiré, per cui nella parte più dettagliata dell'immagine appaiono dei "labirinti". La cosa è particolarmente evidente quando si hanno molti dettagli regolari (un muro di mattoni in lontananza o una maglia di lana a costine, ad esempio).


Un buon software di demosaicizzazione deve rendere il maggior dettaglio possibile senza tuttavia dare luogo all'effetto Moiré. La classica coperta troppo corta, insomma! 
Bisogna poi tener presente che i software commerciali hanno in genere l'algoritmo di demosaicizzazione di quella software house, e non permettono di elaborare l'immagine con altri motori, motivo in più per utilizzare un software open-source.


Algoritmi di demosaicizzazione

Trattare tutti gli algoritmi di demosaicizzazione in un post su un blog è davvero utopistico. Mi limiterò quindi agli algoritmi più "antichi" in ambiente open presenti in DCraw e nei software che ne implementano il codice, in Photivo, Darktable e RawTherapee, e nella comparazione degli algoritmi attualmente più promettenti. Per gli algoritmi più semplici c'è anche una piccola trattazione teorica, per capire "come funzionano" e da cosa derivano i problemi riscontrati in precedenza con le immagini demosaicizzate.

interpolazione bilineare

L'interpolazione bilineare è un'operazione per cui si ricostruisce la coppia di colori primari assenti in un pixel facendo la media aritmetica dei valori dei pixel confinanti.

Volendo ricavare il valore del verde nella posizione 8, dove c'è il pixel blu B8, si può approssimare mediando il valore dei pixel verdi intorno, ovvero:

G8 = (G3+G7+G9+G13) / 4

Nelle posizioni dei pixel verdi, i valori di blu e rosso possono essere mediati solo fra due pixel vicini, per esempio:

B7 = (B6+B8) / 2 ; R7 = (R2+R12) / 2

Mentre nelle altre posizioni possono anch'essi essere mediati fra quattro pixel:

R8 = (R2+R4+R12+R14) / 4 ; B12 = (B6+B8+B16+B18) / 4

Questo algoritmo ha il vantaggio di essere molto veloce, ma ha un serio problema di "color fringing" legato alla presenza, o sarebbe meglio dire assenza, di toni di uno dei colori primari quando si hanno rapidi cambiamenti di colore in orizzontale o verticale da un colore scuro ad uno chiaro. L'effetto in questi casi è il classico bordino colorato, come nel caso delle aberrazioni cromatiche legate ad una specifica ottica.


VNG (gradienti a numero variabile, variable number gradients)
In questo caso  il calcolo è un po' più complesso
Supponiamo di dover ricavare i valori del pixel verde e di quello blu nella posizione 13, ovvero G13 e B13. Si definiscono 8 gradienti nelle direzioni cardinali (Nord, Est, Sud, Ovest, NordEst, SudEst, NordOvest, SudOvest):

Gradiente N = |G8 - G18| + |R3 - R13| + |B7 - B17| / 2 + |B9 - B19| / 2 + |G2 - G12| / 2 + |G4 - G14| / 2 ;
Gradiente E = |G14 - G12| + |R15 - R13| + |B9 - B7| / 2 + |B19 - B17| / 2 + |G10 - G8| / 2 + |G20 - G18| / 2;
Gradiente S = |G18 - G8| + |R23 - R13| + |B19 - B9| / 2 + |B17 - B7| / 2 + |G24 - G14| / 2 + |G22 - G12| / 2;
Gradiente O = |G12 - G14| + |R11 - R13| + |B17 - B19| / 2 + |B7 - B9| / 2 + |G16 - G18| / 2 + |G6 - G8| / 2;
Gradiente NE = |B9 - B17| + |R5 - R13| + |G8 - G12| / 2 + |G14 - G18| / 2 + |G4 - G8| / 2 + |G10 - G14| / 2;
Gradiente SE = |B19 - B7| + |B25 - R13| + |G14 - G8| / 2 + |G18 - G12| / 2 + |G20 - G14| / 2 + |G24 - G18| / 2;
Gradiente NO = |B7 - B19| + |R1 - R13| + |G12 - G18| / 2 + |G8 - G14| / 2 + |G6 - G12| / 2 + |G2 - G8| / 2;
Gradiente SO = |B17 - B9| + |R21 - R13| + |G18 - G14| / 2 + |G12 - G8| / 2 + |G22 - G18| / 2 + |G16 - G12| / 2;

Ciascuno di questi valori è un indice di quanto brusco sia il passaggio di luminosità nelle direzioni indicate dal nome, rispetto alla posizione 13. Più alto è il valore e più secco è il passaggio di luminosità. Le direzioni con valore più alto sono da scartare, perchè introdurrebbero un errore grande se le utilizzassimo per fare una media, mentre quelle con valore più basso sono più attendibili se utilizzate per mediare i valori mancanti (in questo caso del verde e del blu). Facciamo un esempio numerico, supponiamo di avere trovato questi valori:

Gradiente
N
E
S
W
NE
SE
NW
SW
Valore
12
13
7
8
4
7
12
14

Nel passaggio successivo si fissa un valore tale per cui tutti i gradienti con valore superiore saranno scartati. Tale soglia vale:

S = k1*Min + k2 * (Max - Min)

dove k1 e k2 sono costanti il cui valore empirico è rispettivamente 1.5 e 0.5, Min e Max sono i valori minimo e massimo dei gradienti (nell'esempio valgono rispettivamente 4 e 14).
S dunque risulta uguale a 11 e il sottoinsieme di gradienti che non ho scartato sarà:
Gradient subset = {S, W, NE, SE}

Considerando solo le direzioni dei gradienti individuati, e definendo i valori medi in tali direzioni nel modo seguente:


G
B
R
S
G18
( B17 + B19 ) / 2
( R13 + R23 ) / 2
W
G12
( B7 + B17 ) / 2
( R11 + R13 ) / 2
NE
( G4 + G8 + G10 + G14 ) / 4
B9
( R13 + R5 ) / 2
SE
( G14 + G18 + G20 + G24 ) / 4
B19
( R13 + R25 ) / 2

si possono definire e calcolare le somme Gsum, Bsum e Rsu, che si ottengono sommando i valori incolonnati nella tabella:

Gsum = G18 + G12 + ( G4 + G8 + G10 + G14 ) / 4 + ( G14 + G18 + G20 G24 ) / 4;
Bsum = ( B17 + B19 ) / 2 + ( B7 + B17 ) / 2 + B9 + B19;
Rsum = ( R13 + R23 ) / 2 + (R11 + R13 ) / 2 + ( R13 + R5 ) / 2 + ( R13 + R25 ) / 2;
E finalmente si ricavano i valori cercati:

G13 = R13 + ( Gsum - Rsum ) / 4;
B13 = R13 + ( Bsum - Rsum ) / 4; 

dove 4 è il numero di gradienti considerati.
Per calcolare il valore del pixel verde vengono utilizzati i valori del pixel rosso. Questo perchè i tre valori RGB, nella realtà, risultano molto correlati.

Per ricavare il valori dei pixel rossi e blu nelle posizioni dei verdi si fa lo stesso ragionamento, cambiano solo le definizioni dei gradienti iniziali, ovvero:



Gradiente N = |G3 - G13| + |B8 - B18| + |G7 - G17| / 2 + |G9 - G19| / 2 + |R2 - R12| / 2 + |R4 - R14| / 2 ;
Gradiente E = |R14 - R12| + |G15 - G13| + |G9 - G7| / 2 + |G19 - G17| / 2 + |B10 - B8| / 2 + |B20 - B18| / 2;
Gradiente S = |B18 - B8| + |G23 - G13| + |G19 - G9| / 2 + |G17 - G7| / 2 + |R24 - R14| / 2 + |R22 - R12| / 2;
Gradiente W = |R12 - R14| + |G11 - G13| + |G17 - G19| / 2 + |G7 - G9| / 2 + |B16 - B18| / 2 + |B6 - B8| / 2;
Gradiente NE = |G9 - G17| + |G5 - G13| + |R4 - R12| + |B10 - B18|;
Gradiente SE = |G19 - G7| + |G25 - G13| + |B20 - B8| + |R24 - R12|;
Gradiente NW = |G7 - G19| + |G1 - G13| + |B6 - B18| + |R2 - R14|;
Gradiente SW = |G17 - G9| + |G21 - G13| +|R22 - R14| + |B16 - B8|;
 Il VNG è molto più complicato dell'interpolazione bilineare perché prevede un numero di operazioni elevato, anche con la migliore ottimizzazione dell'algoritmo. Tuttavia, l'effetto ottenuto è decisamente migliore, per cui se è plausibile pensare ad una previsualizzazione con il metodo bilineare, sicuramente in fase di esportazione dell'immagine è consigliabile un algoritmo più ricercato.

Adaptive Homogeneity-Directed interpolation (AHD)
E' un metodo piuttosto complesso basato su un lavoro di Keigo Hirakawa e Thomas Parks. In un'immagine registrata da un sensore, lungo le linee di discontinuità orizzontali o verticali, nascono degli artefatti di colore molto evidenti e fastidiosi. Anche gli algoritmi "adattativi", cioè quelli che variano la direzione di interpolazione in modo intelligente (come quello dei gradienti) non riescono ad eliminare questo inconveniente che prende il nome di zippering (effetto cerniera lampo). Ciò avviene perchè in queste zone, critiche per la struttura stessa della matrice di bayer, la direzione di interpolazione commuta continuamente, dando luogo al un pattern di questo tipo:


 In una transizione da un colore scuro ad uno chiaro, in una situazione reale, il passaggio di colore è graduale, cioè due pixel vicini, nella direzione della transizione, avranno colori "visivamente" simili. Se utilizzassimo le coordinate Lab, vedremmo che lungo la transizione, i pixel adiacenti, a due a due, avrebbero un dE definito come:
dE = RadiceQuadrata ( (LR-LR')2 + (aR-aR')2 + (bR-bR')2 )
che sarà piccolo e che diventerebbe ancora più piccolo se riducessimo le dimensioni dei pixel. Quindi, nell'operazione di demosaicizzazione, se dovessimo scegliere tra una direzione di interpolazione che determina un deltaE grande e una direzione che ne determina uno piccolo, sceglieremmo quest'ultima perchè molto più probabile.
Applicando questo concetto nella realtà, si può verificare facilmente che se il canale verde varia rapidamente, anche i canali rosso e blu in quei punti variano rapidamente, in modo da rendere graduale (sempre in senso visivo) la transizione (in altre parole i tre canali RGB risultano fortemente correlati).
L'algoritmo AHD si basa sul concetto di "omogeneità": un pixel avrà un grado di omogeneità alto se rispetto ai pixel circostanti il deltaE è piccolo, mentre avrà un valore di omogeneità basso nel caso contrario. Per una data immagine è possibile costruire una mappa di omogeneità, assegnando ad ogni pixel il suo grado di omogeneità. Lo spazio Lab risulta particolarmente adatto a questo scopo per la sua proprietà di uniformità, in quanto il concetto di omogeneità risulta strettamente legato al concetto di dE, parametro facilmente calcolabile e indice della differenza visiva fra due colori.
Il metodo di interpolazione AHD consiste in questi tre passi:
  1. Interpolare prima secondo la direzione fissa orizzontale e poi quella verticale
  2. Convertire in Lab le due immagini ricavate e creare le mappe di omogeneità
  3. Combinare le due immagini interpolate utilizzando le mappe di omogeneità
Il terzo punto significa:
  • considero il primo pixel
  • guardo nelle mappe in quale delle due immagini interpolate il pixel ha il grado più alto di omogeneità
  • scelgo questo pixel e lo metto nell'immagine finale.
Poi si passa al secondo pixel e così via.
In generale l'operazione di interpolazione soffre di due tipi di artefatti: uno dovuto alla scelta della direzione di interpolazione (che questo sofisticato metodo risolve nel modo migliore) e uno dovuto alla limitazione nell'interpolazione stessa. Per esempio, supponendo di aver scelto la direzione di interpolazione perfetta, per ricavare il valore di un pixel mancante potrei, per esempio, mediare tra i due pixel adiacenti, oppure potrei considerare anche quelli più lontani, oppure potrei usare tecniche ancora più sofisticate. Ovviamente il risultato finale cambierebbe molto.
 L'algoritmo AHD (almeno nelle sue forme più semplici), rispetto al VNG ed al bilineare soffre parecchio in termini di artefatti "a labirinto":

L'algoritmo AHD è stato nel tempo ottimizzato e potenziato, con sottoinsiemi di pixel considerati nel calcolo maggiori o con condizioni al contorno differenti. In Photivo è possibile operare sia con l'AHD "classico" che con la sua versione "modificata".


Altri algoritmi di demosaicizzazione

In campo open, oltre ai classici VNG (o VNG 4 colori, che guadagna in termini di effetto Moiré ma perde in definizione dei dettagli) e AHD (EAHD, AHD modificato ecc.), sono stati proposti anche il PPG, il DCB, il VCD (Variance of Color Differences di K.H Chung and Y.H Chan) l' LMMSE (basato su un algoritmo di tipo Hamilton-Adams illustrato brevemente qui).
Gli stessi algoritmi "classici" sono stati spesso rivisti ed ottimizzati, mentre in alcuni casi c'è chi ha fuso il risultato di più algoritmi nella speranza di ottenere risultati migliori.
Cercando sulla Rete si trovano numerosi esempi di algoritmi in fase sperimentale. In generale, non è un'impresa "facile", perché sono richieste conoscenze matematiche e di programmazione tali per cui di fatto i nomi nel campo sono quasi sempre gli stessi. Qui e qui sono riportati due esempi (in inglese) significativi di cosa vuol dire studiare un algoritmo di demosaicizzazione e cosa si va a cercare. Da notare che un ambiente "open" permette a più persone di intervenire sul codice, per cui lo stesso algoritmo può essere ottimizzato nel tempo o si possono applicare modifiche che migliorano la qualità del risultato finale. Una cosa del genere su un sistema "chiuso" è molto difficile (gli sviluppatori sono comunque un numero limitato). Chi pensa che un software commerciale come quello di DxO debba avere per forza un algoritmo migliore può ricredersi quardando l'immagine seguente


Ogni algoritmo ha le sue caratteristiche ed è difficile "premiare" un vincitore.  Tuttavia è relativamente facile affermare che, al netto dell'effetto Moiré, gli algoritmi migliori sono AMaZE, DCB e LMMSE, con i primi due che danno foto generalmente più "nitide" dell'ultimo. Nel caso di DCB è possibile impostare un numero di iterazioni il cui effetto finale è limitare fortemente l'insorgere di "labirinti" senza perdita di dettaglio. In genere il numero di iterazioni massimo possibile è elevato, ma nella maggior parte dei casi conviene non spingersi oltre 4, perché oltre questa soglia non si hanno risultati apprezzabilmente differenti.

crop al 200%, demosaicizzazione bilineare
crop al 200%, demosaicizzazione VNG
crop al 200%, demosaicizzazione VNG a 4 colori
crop al 200%, demosaicizzazione PPG
crop al 200%, demosaicizzazione AHD
crop al 200%, demosaicizzazione AMaZE
crop al 200%, demosaicizzazione DCB
crop al 200%, demosaicizzazione VCD
crop al 200%, demosaicizzazione LMMSE

In generale, è importante che il flusso di lavoro nel programma utilizzato effettui le eventuali correzioni di aberrazioni cromatiche prima del processo di demosaicizzazione (http://www.imatest.com/docs/sfr_chromatic/). Riflettendo sul principio di funzionamento degli algoritmi visti in precedenza, e considerando che le zone in cui il colore cambia rapidamente sono spesso anche quelle in cui si ha aberrazione cromatica, si capisce immediatamente che la correzione del fenomeno ottico produce un file da processare sicuramente migliore, per cui l'immagine "demosaicizzata" ne godrà sicuramente. Rawtherapee compie le operazioni nel giusto ordine, mentre ignoro cosa facciano gli altri software.
Altro aspetto da tenere in considerazione è il rumore digitale presente nelle foto, perché in questi casi AMaZE non è la scelta "primaria", mentre DCB fornisce risultati migliori.
L'estremo dettaglio reso da DCB può essere eccessivo in alcuni casi, come ad esempio con i ritratti, per i quali un LMMSE "funziona" meglio.
La regola principale è che non ci sono regole, se non quella del buonsenso di mettersi a cercare i difetti (che si conosce essere in determinate zone dell'immagine) ed eventualmente cambiare algoritmo oppure salvare le immagini con due algoritmi differenti e poi fonderle in postproduzione.
Nell'esempio seguente i dettagli sulla finestra e l'aliasing sono resi meglio dall'algoritmo creato ad hoc dal programmatore rispetto agli altri (-q 0 è l'opzione che il programmatore ha indicato per il suo algoritmo in DCRaw, uno dei software più utilizzati dagli "smanettoni" amanti della riga di comando)!



Confronto tra differenti software di demosaicizzazione

Sulla Rete si trovano varie pagine con confronti costruiti più o meno ad arte per i differenti motori di demosaicizzazione.
A questo indirizzo è possibile osservare come si comportano molti algoritmi con un'immagine particolarmente ostica da trattare.
Sulle pagine web del creatore dell'algoritmo DCB si trova un confronto in cui sono presenti anche alcuni algoritmi commerciali. Su quelle stesse pagine, si può capire anche come funzionano i vari algoritmi per aspetti differenti dalla sola nitidezza.
Sui forum dei vari software (rawtherapee, Photivo, darktable ecc.) si possono trovare vari esempi caricati da utenti che fanno il confronto tra i vari algoritmi per scatti "problematici".
Al di là dei classici esempi "preconfezionati", credo che il primo metro di giudizio debbano essere le proprie immagini. Sotto questo aspetto è utile la funzione di Darktable di fornire un confronto diretto tra diverse versioni della stessa immagine lavorata con parametri differenti.


Algoritmi "secondari"

Tra gli algoritmi presenti nel flusso di lavoro che porta dalla matrice di Bayern all'immagine come siamo abituati a vedere ci sono alcuni che lavorano prima o dopo rispetto al motore di demosaicizzazione e che possono migliorare alcuni aspetti della resa finale.
EECI: è un algoritmo basato sui gradienti che si può accoppiare facilmente all' LMMSE in quanto va a migliorare alcuni pixel favorendo il lavoro successivo del motore di demosaicizzazione. Da quello che ho capito, dovrebbe essere alla base dell' "edge threshold" - "soglia bordi" nella traduzione italiana del programma- nel plugin di demosaicizzazione presente in darktable.
FDBB: è sostanzialmente un riduttore di rumore che agisce a monte dell'operazione di demosaicizzazione. L'autore dell'algoritmo è lo stesso del DCB. L'algoritmo ha due livelli di funzionamento, uno blando ed un altro più "vigoroso", ma ha effetti abbastanza "evidenti" soprattutto sul canale del rosso, come si vede nell'immagine di esempio (da notare i comignoli ed i binari "desaturati"). Come tutti gli algoritmi di riduzione del rumore, anche l' FDBB tende a rendere meno risolta l'immagine.

immagine "originale" (sinistra) ed immagine trattata con FDBB (destra)





Conclusioni

Parlare di fotografia oggi implica parlare di tecnologia e di matematica. La "fotografia" per come la vediamo è ormai un insieme di dati numerici, per cui dobbiamo sempre considerare "postprodotta" qualsiasi immagine che vediamo e che proviene da una camera digitale. Le stesse immagini in jpg che escono dalla macchina fotografica non sono altro che file elaborati dal software interno alla macchina!
La demosaicizzazione è la prima operazione che si fa sulla matrice di punti colorati che viene registrata inizialmente, e sapere che tipo di algoritmo usare può essere essenziale per migliorare la qualità dei nostri scatti.
Il mondo open, nonostante i brevetti software, offre ottimi algoritmi di demosaicizzazione, e soprattutto permette (a chi vuole) di modificare i codici per creare il proprio algoritmo.
Il resto sta a noi e alla nostra capacità.




fonti:
http://www.cambridgeincolour.com/tutorials/camera-sensors.htm
http://www.pentaxiani.it/forum/viewtopic.php?f=27&t=52435
http://www.linuxphoto.org
http://www.photoactivity.com
http://www.stampolampo.it/dblog/articolo.asp?articolo=585

Nessun commento:

Posta un commento

Puoi commentare quello che vuoi, ed io sono libero di pubblicarlo o meno.