Aggiornamento del 4/3/18: Aggiunta la tabella sulle LUT non ottimizzate, cambiata l'ultima immagine e modificata la conclusione; ora l'articolo è nella sua forma definitiva dopo oltre 1 anno dalla gestazione!
Aggiornamento del 26/2/18: Effettuate ulteriori piccole modifiche e correzioni.
Aggiornamento del 28/1/18: Corretta la tabella dei formati "microfloat" (le dinamiche erano sbagliate) ed effettuate ulteriori piccole modifiche sugli ultimi due paragrafi.
Aggiornamento del 21/1/2018: oltre alle conclusioni, è stato aggiunto un nuovo paragrafo sulle "LUT ottimizzate".
Aggiornamento del 27/3/2023: inserite ulteriori considerazioni sul set ideale di "LUT ottimizzate" da adottare.
Introduzione: cos'è l'HDR?
Si sente parlare sempre più spesso delle immagini High Dinamic Range (HDR), sia nella fotografia che (ultimamente) per i televisori. Di cosa si tratta?
Bisogna partire dalla fisiologia. I fotoricettori presenti nell'occhio umano (coni e bastoncelli della retina) producono uno stimolo sensoriale che è approssimativamente proporzionale al logaritmo dell'intensità luminosa; questo ci permette di apprezzare, in una scena davanti a noi, un grande intervallo di luminosità, distinguendo sia dettagli in ombra che oggetti illuminati direttamente; in pratica, stime empiriche mostrano che l'occhio umano è in grado di apprezzare simultaneamente differenze di illuminazione pari a un fattore 10000:1 e anche qualcosa in più! Tradotto in deciBel, questo significa che l'occhio ha una dinamica di oltre 40 dB mentre, in termini informatico-fotografici, si traduce in una dinamica di circa 14 bit o 14 stop (i numeri coincidono poichè entrambe le scale si basano sul logaritmo in base 2)1.
Fino ad alcuni anni fa, le immagini e i video venivano registrati, memorizzati e riprodotti con sistemi che non erano affatto in grado di abbracciare tutta questa dinamica; le prime fotocamere/videocamere digitali non si spingevano oltre una dinamica di circa 20 dB e quindi gli 8 bit presenti in 1 byte erano sufficienti a codificare in maniera lineare l'intensità di ogni pixel, fornendo una dinamica teorica di 255:1 ovvero 24 dB. In realtà, alcuni sistemi analogici di "compressione della dinamica", derivati dalle tecnologie audio, erano stati già implementati nella televisione analogica; in pratica, per ridurre gli effetti negativi del rumore durante il trasferimento dell'informazione, in fase di registrazione il segnale veniva "appiattito" per poi venire "riespanso" in fase di riproduzione, utilizzando una particolare "funzione di trasferimento" detta "Gamma correction" che, in parte, ricalca lo schema fisiologico dei logaritmi ed è analogo al "sistema Dolby" usato nelle audiocassette (per i lettori più attempati).
D'altro canto, già da alcuni anni le fotocamere reflex/mirrorless e anche alcune "prosumer" utilizzano il formato "raw" che memorizza i dati nativi del sensore usando più di 8 bit per esprimere la luninosità di ciascun colore e ciascun pixel (si arriva a 14 o addirittura 16 bit nei sistemi professionali); anche sui dispositivi portatili si sta diffondendo la modalità di ripresa HDR; quest'ultima, tuttavia, è spesso ottenuta sommando più immagini riprese con diversi tempi di esposizione, codificando però il risultato a 8 bit con una particolare mappatura o funzione di trasferimento simil-logaritmica. Infine, i televisori di ultima generazione (quelli con la sigla UHD, per intenderci) utilizzano una modalità HDR con codifica di 10 bit per ciascun colore; questa tendenza sarà ancora più marcata con il diffondersi della tecnologia OLED, intrinsecamente capace di restituire una elevata dinamica poichè i pixel emettono luce propria invece di filtrare la retroilluminazione LED.
Con tutti i rapidi progressi tecnologici sia nel campo della registrazione (sensori di immagini) che in quello della restituzione (display) è inevitabile che si abbandonino definitivamente i vecchi standard foto/video a 8 bit e si passi a un sistema di codifica più moderno, ma quale standard bisogna adottare? Qui provo a dare una risposta personale e originale, riassunta nelle conclusioni.
Uno standard tutto digitale
Attualmente, gli standard per contenuti video ad alta dinamica (HDR) fanno uso di sistemi a 10 bit “ibridi”, in cui l'input (codifica) avviene secondo parole digitali lunghe 10 bit (1024 combinazioni) e l'output (che corrisponde all'intensità del segnale in uscita sul display e anche del segnale in ingresso prima della codifica) è dato da una funzione “analogica” di trasferimento, in particolare la PQ (Perceptual Quantizer o SMPTE ST2084) di Dolby.
In questa sede, invece, intendo occuparmi di funzioni di trasferimento o codifica digitale-digitale, che trasformano cioè un contenuto digitale ad alta dinamica in un altro più compatto, che può essere poi riespanso numericamente, restituendo la dinamica originale anche se con un lieve degrado in termini di precisione fotometrica, non percepibile ad occhio. Si tratta in altre parole di un sistema di compressione “lossy” della dinamica, fisologicamente efficiente e completamente digitale.
Un sistema sarà “fisiologicamente efficente” se rispetta due condizioni fondamentali: da un lato, la dinamica deve essere nettamente superiore a quella fornita dalla grafica tradizionale, cioè almeno 14 bit invece di 8; l'altra è una buona precisione fotometrica, con errore nettamente inferiore al cosiddetto limite di Schreiber, pari a circa il 2% (soglia sopra la quale la variazione di luminosità tra due livelli diviene percepibile); esiste in realtà un limite più stringente, il cosiddetto limite di Barten, che vale solo in condizioni di illuminazione ottimale ed ammonta circa a 0,4%; qui adotteremo questo limite, al di sopra del quale l'occhio di uno spettatore attento è in grado di apprezzare le differenze (come bande di diversa luminosità o “effetto banding”) tra livelli contigui nelle regioni dell'immagine con luminosità media e alta, soprattutto se abbastanza spaziate tra loro; in pratica, questa situazione si verifica quando nella scena è presente un gradiente di luminosità che varia in modo molto regolare e graduale, come mostrato nell'esempio sottostante.
Esempio di immagine affetta da "banding effect" (a sinistra); a destra l'immagine originale prima della quantizzazione. Credits: Justin Hemsley - fonte
Il rispetto dei due criteri appena citati, se applicato a una codifica lineare della luminosità, richiederebbe parole di almeno 21 bit che è una lunghezza davvero eccessiva per lo spreco di banda e memoria che comporta; infatti, dal momento che lo stesso sistema visivo ha una risposta logaritmica e non lineare allo stimolo luminoso, non sarebbe comunque in grado di apprezzare le piccole differenze di luminosità nelle regioni bene illuminate della scena. Un discorso analogo, in realtà, si potrebbe fare anche senza ricorrere ai limiti della fisiologia; ad esempio, anche in termini di semplice rumore statistico, non ha senso riportare l'esatto valore per regioni con luminosità elevata (ma comunque lontane dalla zona di saturazione del sensore) poichè l'incertezza di quel valore aumenta in ragione della radice quadrata del numero di fotoelettroni4.
E' necessario dunque un sistema con una risposta non lineare per codificare il segnale. L'idea più immediata per realizzare un sistema fisiologico è quello di ricorrere al logaritmo dell'intensità, dato che imiterebbe la risposta della retina allo stimolo luminoso; per la decodifica si userebbe l'esponenziale, che è l'operazione inversa. Ebbene, questo è quello che, in parte, fanno i sistemi HDR in uso (PQ e curve Gamma-Log) ma, come dicevo prima, si tratta di soluzioni miste analogico-digitali.
Volendo invece ricorrere a una codifica completamente digitale, si parte da un segnale in ingresso e in uscita descritto da m bit lineari e da una codifica con n bit (dove n<m); il passaggio tra il segnale originale a quello codificato e viceversa è definito da una opportuna funzione di trasferimento. Qui mi concentrerò su due tipi diversi di funzioni di trasferimento completamente digitali: quella del formato in virgola mobile (qui ridotto a un numero molto contenuto di bit) e quella delle tabelle di trasferimento (LUT); vediamoli nell'ordine.
Unsigned Micro-Floating (UMF)
L'idea, imparentata con la funzione logaritmo dell'intensità, spinge l'uso del sistema “Floating Point” su parole di lunghezza limitata (non oltre 16 bit) con due varianti importanti rispetto ai formati FP tradizionali: il bit dedicato al segno della mantissa non ha senso poichè le intensità sono sempre positive, perciò invece di lasciarlo inutilizzato può venire fruttuosamente usato per aumentare la precisione. Inoltre, sia i valori ±∞ che i codici “NaN” non servono e quindi il valore massimo dell'esponente viene utilizzato effettivamente. Resta inteso che si sfrutta sempre il trucco del ”bit nascosto” (hidden bit) tranne il caso in cui l'esponente ha valore minimo; in quel frangente, il numero codificato è “subnormale” il che vuol dire che non c'è “hidden bit” e il valore più basso vale zero; in quella regione, inevitabilmente, l'errore di precisione (ovvero la variazione relativa di intensità tra due livelli consecutivi) sale a valori altissimi, che comunque non possono essere apprezzati ad occhio poichè stiamo parlando di zone estremamente buie nell'immagine. Ecco quelle che reputo le configurazioni ottimali da usare:
Come si vede, questi “unsigned micro-Floating” si prestano molto bene allo scopo. Se il primo rispetta solo il limite di Schreiber in termini di precisione e anche la dinamica risulta un pò limitata, quello a 10 bit soddisfa in pieno i requisiti di dinamica, scendendo ben sotto l'1% di precisione; lo standard a 12 bit, poi, riesce a coprire una dinamica eccellente di 23 bit (attualmente irraggiungibile in un normale sistema di acquisizione foto/video) stando addirittura sotto lo stringente limite di Barten sulla precisione fotometrica! Personalmente, ritengo che nella maggior parte degli utilizzi non abbia molto senso andare oltre quest'ultimo livello3. Un altro aspetto interessante di tutti i sistemi "microfloat" sopra riportati (tranne il primo) è che sono "retrocompatibili" con il formato a 8 bit, nel senso che fino al livello 255 (valore massimo del formato a 8 bit lineare) i valori in ingresso e in uscita coincidono, come evidente dal seguente grafico sul sistema a 10 bit (in verde la funzione di trasferimento, in rosso l'incremento da essa utilizzato al variare dell'esponente).
Nel grafico qui sopra, nel riquadro, c'è l'ingrandimento relativo ai livelli di bassa luminosità mentre, di seguito, la curva Drel (con scala sulla destra) mostra la variazione relativa di intensità in output passando da un livello codificato al successivo; naturalmente, nella prima zona a sinistra con numeri “sub-normali” (primi 128 livelli codificati), il limite massimo sulla precisione viene violato e di fatto diventa infinito passando dal livello 0 al livello 1, ma questa è una caratteristica inevitabile, comune a tutti i sistemi di codifica. Nelle rimanenti 7 regioni a maggiore luminosità, la Drel oscilla tra 0,39 e 0,79% e alla fine la dinamica è 16 volte più ampia rispetto a una codifica lineare a 10 bit2.
L'unico scotto da pagare è che gli incrementi, passando da un esponente a quello successivo, raddoppiano e quindi sono tutte potenze di due; in questo modo, non si sfruttano tutti i valori intermedi che renderebbero la curva del Drel meno discontinua, con salti sempre più piccoli mano a mano che n aumenta. E questa è proprio la prerogativa del prossimo sistema.
Look-Up Tables (LUT)
Il secondo metodo di compressione è quello più efficiente ma, apparentemente, meno intuitivo e più “pesante” dal punto di vista dell'implementazione, se non altro in termini di memoria occupata; si tratta delle cosiddette “Look-Up Tables", un sistema ben noto nel campo della elaborazione digitale delle immagini che fa ricorso a una tabella di riferimento per passare dai valori originali a quelli codificati e viceversa. In pratica, si tratta di due matrici di corrispondenza, ciascuna contenente due “array” o sequenze di numeri pre-calcolati: la prima tabella serve per codificare i 2m livelli in ingresso in 2n possibili livelli della funzione di trasferimento (con inevitabili approssimazioni per cui la funzione non è biunivoca e valori vicini nel primo array corrispondono allo stesso valore nel secondo array); la seconda tavola definisce l'operazione inversa di decodifica e stavolta si torna a un range che va da 0 a 2m-1 ma saltando molti valori nella parte alta a causa della precedente "quantizzazione" o approssimazione.
Nelle LUT qui presentate, la maggiore richiesta di memoria è solo apparente poichè le tabelle si costruiscono con un algoritmo piuttosto semplice e non c'è reale bisogno di memorizzarle, a meno che questo non comporti una maggiore velocità di esecuzione. In pratica, se chiamiamo Di l'i-esimo incremento e outi l'i-esimo elemento nella tabella di decodifica (Di = outi - outi-1), basta fissare il numero di bit di codifica n e il livello di precisione Dmax; la tabella viene generata imponendo che:
Drel = Di/outi < Dmax [ con outi>1/Dmax ]
Qui sotto gli andamenti relativi alla curva con codifica a 10 bit (n=10) e Dmax=0,784% che è la stessa precisione della codifica "micro-Float" a 10 bit discussa al pararafo precedente:
Come si vede, a parità di precisione fotometrica la dinamica è nettamente migliore, quasi 16.3 bit o "stop", dunque 4,8 volte più ampia del sistema floating. Naturalmente, volendo invece limitare la dinamica a 14 bit, questo si tradurrà in una precisione migliore, con un Dmax=0,604%. Perciò le tabelle di riferimento, con la loro ottimizzazione degli incrementi, si dimostrano nettamente superiori alla codifica "microfloat", come mostrato nella tabella seguente che mostra le prestazioni, in termini di precisione (incremento massimo) con codifiche a 9,10,11,12 bit e decodifiche intere che vanno da 10 a 24 bit (le combinazioni "estreme" con precisione troppo grande o troppo piccola non hanno molto senso e non sono visualizzate):
Il grafico qui sotto riassume le prestazioni che possono essere raggiunte con codifiche LUT a 9,10,11 e 12 bit, sia in termini di gamma dinamica risultante in bit (ascisse) che di precisione fotometrica (ordinate); dato che gli andamenti sono grossomodo rettilinei, sono indicate anche le rette che li approssimano con le corrispondenti equazioni.
La linea viola orizzontale indica la soglia di Barten mentre quella verticale il requisito dei 14 bit di dinamica; come si vede, l'uso di parole a 9 bit non riesce a soddisfare nessuno dei due requisiti mentre è necessario ricorrere a una codifica di almeno 11 bit per raggiungerli entrambi. Nella figura ho cerchiato in azzurro quelle che ritengo le codifiche ottimali per ciascuna lunghezza utilizzata; esse sono le codifiche 9→12 bit, 10→14 bit, 11→16 bit e 12→20 bit, che giacciono approssimativamente su una curva simile ad una iperbole (in azzurro). Da notare che la penultima di queste codifiche ottimali ha prestazioni molto simili al "microfloat" 12 bit ma con un risparmio di 1 bit.
LUT ottimizzate
Esiste un margine fisiologico per migliorare ulteriormente le prestazioni di una tabella di riferimento, rilassando un pò il limite di precisione nella regione iniziale di codifica. Questo è lecito poichè, in questa zona di luminosità più bassa, l'occhio è meno sensibile a differenze fotometriche (e cromatiche) rispetto a condizioni ottimali di illuminazione; l'affermazione è tanto più vera quanto maggiore è la dinamica complessiva, cioè per decodifiche con molti bit. Per sfruttare questa "debolezza", la soluzione più semplice è quella di trasformare il valore di precisione in un valore medio, piuttosto che in un limite superiore. L'algoritmo per generare questa nuova LUT è quindi modificato come segue:
Di = int ( Dmax · outi +0,5 ) [ con outi>1/Dmax ]
L'andamento dell'incremento relativo che si ottiene è illustrato qui sotto (nel caso di codifica a 10 bit con Dmax = 0,6 %). Come si vede, il primo salto avviene tra ( Di = 2/3 Dmax ) e ( Di+1 = 4/3 Dmax ) e poi l'incremento relativo tende a Dmax con oscillazioni sempre più contenute.
Qui sotto, a sinistra le tabelle con le performances di queste LUT ottimizzate per valori prefissati di n, m e di precisione fotometrica, includendo anche codifiche estremamente grossolane a 8 bit; stavolta il grafico riporta la precisione in scala logaritmica. Rispetto alle codifiche non ottimizzate illustrate in precedenza, quelle riportate nella prima tabella presentano un miglioramento sul livello medio di precisione che va dal 5% al 15% (i miglioramenti più forti si ottengono per valori piccoli di m e n):
Adesso gli schemi di codifica 10→13 e 10→14 bit si abbassano decisamente, rendendo "quasi accettabili" entrambe queste codifiche dal punto di vista fisiologico senza ricorrere a parole di 11 bit; personalmente, ritengo soluzioni "ottimali" dal punto di vista della precisione fotometrica le seguenti codifiche "allineate": 8→10 bit, 9→12 bit, 10→14 bit, 11→16 bit, 12→18 bit (contorno blu nel grafico e nella tabella); in aggiunta, se si vuole massimizzare la dinamica mantenendo una precisione soddisfacente, si può ricorrere alle due soluzioni 11→18 bit, 12→24 bit. Come illustrato nella seconda tabella, in alternativa alla scelta di un numero intero di m bit in output, possiamo imporre una precisione media arbitraria, ad esempio pari allo 0,59%, che il più valore più alto atto a garantire il suddetto vantaggio di "retrocompatibilità" con la codifica lineare 8 bit classica; esso offre una dinamica ottima, quasi 23800:1 o 43,8 dB (freccia e contorno verde nella tabella/grafico). Abbassando invece il limite di precisione sulla soglia di Barten (0,4%), otteniamo una LUT con dinamica complessiva di circa 5080:1 (37.05 dB), un compromesso comunque interessante evidenziato con grassetto e bordo rosso nella tabella; peraltro, sempre adottando questa precisione, la codifica a 12 bit permette di raggiungere una dinamica spettacolare di 1 miliardo a 1 (30 bit o 90 decibel).
Nota del marzo 2023: riesaminando il grafico qui sopra e dando maggiore peso all'efficienza di compressione e ai limiti fisiologici, probabilmente il set ideale di formati è il seguente: 8→11, 9→12, 10→14, 11→18, 12→24.
In ultimo, si potrebbe pensare di generalizzare il discorso sull'ottimizzazione introducendo un parametro α che varia in maniera continua da 0 a 1, in modo tale che:
Di = int ( Dmax · outi + α ) [ con outi>1/Dmax ]
Per α=1 abbiamo la codifica non ottimizzata con un limite superiore sull'incremento relativo, mentre per α=0,5 abbiamo quella ottimizzata discussa in questo paragrafo.
Conclusione e ulteriori sviluppi
Questo breve excursus mostra che, per avere un formato digitale HDR che soddisfi pienamente i requisiti fisiologici di precisione e dinamica del nostro sistema visivo, non è affatto necessario ricorrere a parole di 16 bit o a una antiquata decodifica ibrida (tramite una curva di trasferimento analogica); è infatti sufficiente utilizzare 12 bit con un formato a virgola mobile dedicato ("microfloat") oppure solo 11 bit con una più efficiente tabella di trasferimento (LUT). Al limite, sacrificando leggermente i requisiti imposti dalla fisiologia e utilizzando LUT ottimizzate, è possibile utilizzare codifiche a soli 10 bit, come già si fa per la TV HDR, ma in modalità "full-digital".
Infine, anche se in questo articolo il problema non è stato affrontato, bisogna accennare al fatto che è sicuramente possibile ottimizzare ulteriormente il formato di una immagine HDR a colori, unendo le informazioni sui tre canali e realizzando, ad esempio, un sistema a 32 bit/pixel, con un ulteriore risparmio di bit a parità di qualità/prestazioni. L'implementazione dovrebbe basarsi sulle considerazioni fatte nell'articolo per quanto riguarda la componente di luminanza (ovvero alla somma dei tre canali primari, eventualmente pesati) che dovrebbe quindi utilizzare una codifica "microfloat" o LUT a 12÷14 bit; i rimanenti 18÷20 bit bit esprimeranno le componenti cromatiche (ad esempio "tonalità" e "saturazione") e, in questo caso, è meglio utilizzare scale lineari oppure specifiche tabelle di riferimento che garantiscano un'accuratezza cromatica adeguata senza spreco di informazione.5
Note:
1) Dati due livelli estremi di luminosità Imax e Imin, la gamma dinamica in deciBel si calcola nel modo seguente:
DR (dB) = 10·Log10(Imax/Imin)
Mentre in termini di bit o di stop il calcolo è:
DR (bit) = Log2(Imax/Imin)
Di conseguenza, dato che per le leggi sui logaritmi Log2(x)=Log10(x)/Log10(2), per convertire i valori nelle due scale basta fare:
DR (dB) ≈ 3,01·DR (bit) ; DR (bit) ≈ DR (dB) / 3,01
Purtroppo, per motivi storici e di marketing, il range dinamico in dB viene spesso calcolato in maniera errata, moltiplicando il numero di bit per 6 invece che per 3; questa scellerata convenzione deriva da una trasposizione acritica di quanto si fa in campo audio, dove l'intensità sonora non è direttamente proporzionale al segnale elettrico ma al suo quadrato. Qui naturalmente non farò questo errore e userò il modo giusto (ma meno diffuso) per calcolare la dinamica.
2) Un altro aspetto interessante a favore della codifica float 10 bit è che il massimo incremento Delta, relativo all'ultima zona con 895<i<1023, vale 64 lsb (less significant bit); questo può sembrare un valore alto ma, considerando che codifica valori originali compresi tra 8192 e 16383, dovrebbe essere confrontabile o al di sotto dell'incertezza (rumore) statistica associato a un segnale molto alto (si veda la penultima nota qui sotto). In effetti, assumendo ragionevolmente che 1 lsb corrisponda a 0,5÷1 fotoelettroni nel sensore, il rumore statistico in quella regione è maggiore di √(0,5·8192)=64 lsb. Quindi si tratta di una codifica ottimale non solo dal punto di vista fisiologico ma anche statistico-metrologico!
3) In effetti, anche ammesso che il sistema di acquisizione/riproduzione dell'immagine abbia una dinamica ampissima, l'uso di parole più lunghe sarebbe di fatto inutile. Infatti, per ogni zona (sequenza) di una immagine (filmato), l'occhio non è in grado di apprezzare una dinamica maggiore di 14 bit; perciò, basterebbero pochi bit per rimodulare, all'interno di ciascuna zona (sequenza), la luminosità complessiva; con questo sotterfugio, si aumenta in modo irrisorio la banda occupata!
4) In base alle leggi della statistica, se una misura implica l'osservazione di un numero medio di N eventi, tale conteggio rispetta una distrbuzione approssimativamente "gaussiana" con deviazione standard pari a √N. Perciò, nella misura di N fotoelettroni, il "rapporto segnale/rumore" puramente statistico vale √N (quello effettivo potrebbe essere anche maggiore per la presenza di altre sorgenti di rumore).
5) Il ricorso (da me precedentemente proposto) ad un sistema HDR a colori con un esponente comune di 5 bit ed i rimanenti 27 bit equamente distribuiti sulle mantisse di ciascuno dei tre colori primari, pur essendo una soluzione più semplice e con prestazioni apparentemente eccellenti (dinamica di 120 dB per canale e precisione fotometrica migliore dello 0,20%), ad una più attenta analisi si è rivelato inadeguato perchè non è in grado di restituire colori sufficientemente saturi in regime "non-subnormale" (con luminosità non troppo basse).
Riferimenti:
- http://www.digitaltveurope.net- https://books.google.it/