Compressione lossy di immagini n. 2

10 Gen. '99
Leonardo Maffi

Vedi anche: CompressImmagini 0028 19981125

N.B. questa pagina contiene immagini Png visualizzabili dal Netscape4 ma non dall'Explorer 3.

    Comprimere le immagini accettando una certa perdita di qualità non è una attività rapida e facile. Se si vogliono utilizzare formati standard, cioè leggibili ad esempio da un browser, si deve utilizzare quasi soltanto Jpeg, Png, e più raramente Gif, dato che di solito il Png è più denso. Se si vuole comprimere al massimo delle immagini, ad esempio per produrre una pagina web veloce, si deve lavorare parecchio. Con le immagini pronte a disposizione, anche usando i migliori e più specifici software, come PaintShop, PhotoShop, Web Graphics Optimizer, ecc, si deve mettere in conto un tempo di quasi mezzora ad immagine, talvolta un'ora. E sono richieste conoscenze d'intuito sul funzionamento di Png, Jpeg, dithering, quantizzazione cromatica e compressione entropica (una conoscenza formale non è sufficiente!).
    Come dissi nella nota precedente le immagini sono fondamentalmente di due categorie, ciascuna adatta ad essere compressa con un metodo differente. Esistono però casi indeterminati o intermedi che fanno perdere un mucchio di tempo in tentativi.

Il Jpeg è adatto per immagini sfumate, le cosiddette immagini naturali. Possono essere prodotte da scanner e telecamere digitali o anche da pittori e disegnatori, o programmi di ray tracing. Questi ultimi spesso producono immagini pressochè prive di rumore, ben comprimibili in lossless o quasi lossless.
Il Cd di Le Scienze 1995 contriene testi completi delle riviste dell'anno e tutte le figure in Bmp. E' un formato leggibile ad alta velocità, perchè è poco compresso: hanno portato le immagini in 256 colori (o poco meno) con dithering, e poi hanno salvato con run lenght encoding (Rle). Lavorando molto di più per ottimizzare le immagini, si potevano comprimere altre dieci - venti volte, pur usando formati grafici standard, leggibili sia da Mac che da Pc.

Vediamo come ho compresso le immagini. Ho utilizzato i migliori software disponibili: Paint Shop Pro 5 (Psp), Photoshop 5 (Ps), Web Graphics Optimizer Express v. 2.05 for Win (Plenio Software Solutions) (Wgo).
Per i formati grafici non standard vedi SfidaCompressori 0022 19981121
e in particolare sul Bmf: CompressoriEntr 0055 19981218.
 

Immagini fotografiche

Per immagini fotografiche come la seguente la scelta ovvia è il Jpeg:

Predatore Astici tyratto da Le Scienze (Vedi Risonanza stocastica)

Questa immagine contiene una vasta area quasi nera. Così ho alzato il valore di gamma in modo da rendere più visibile i dettagli oscuri. Poi ho eliminato il rumore nelle aree quasi nere con un Flood Fill nero a media tolleranza cromatica.
Ho usato Wgo con un sottocampionamento cromatico normale (4:4:2). Tale programma permette di regolare finemente il fattore di quantizzazione, per trovare il miglior compromesso fra occupazione e qualità. L'originale trucolor grezzo occupa 344*248*3 = 255'936 byte, la Bmp 256 col. dith. occupa 86'400 byte circa, il Jpeg su mostrato 8788 byte (circa 1/29 della truecolor).
Ho usato il Jpeg dinamico (progressivo) a cinque strati. Il Wgo a parità di qualità comprime di più in questo formato. Di solito conviene comprimere a più strati le immagini ad alto microcontrasto. Se l'immagine finale salvata non ne ha molto, convengono solo due - tre strati. (l'immagine finale può avere poco microcontrasto sia perchè ne aveva poco all'origine, sia perchè si è compressa fortemente col Jpeg).
Questa dimensione dell'immagine è accettabile per me. Volendo comprimere l'immagine ulteriolmente si può passare a formati grafici non standard. Di solito non uso Wavelet o compressione frattale perchè non ho ancora trovato un software che solitamente comprime in maniera visibilmente migliore del Jpeg ben ottimizzato come in questo caso. Non bisogna sottovalutare la potenza del Jpeg!
Al massimo si può migliorare la compressione entropica. Ad esempio si può comprimere l'immagine jpeg su mostrata con 777, per portarla a 8701 byte.
Oppure si può usare il formato Pic del Minerva (Pegasus Imaging Corporation) che ricomprime Jpeg in maniera lossless usando al posto del compressore entropico Huffman, la Rls, una variante proprietaria della codifica aritmetica, che permette 5-10 % di compressione ulteriore.

Un'ultima nota sul Jpeg. Un formato grafico come questo non finisce il suo sviluppo quando viene formalizzato lo standard. Infatti sono stati introdotti software con una buona interfaccia, che permette di scegliere interattivamente il fattore di compressione per una data immagine (Wgo e JpegOptimizer). Tali migliorie non sono da sottovalutare, perchè fanno la differenza fra un prodotto comodo e veloce da usare da uno inutilizzabile o quasi.
Una delle migliorie che non è stata utilizzata è la compressione aritmetica finale, perchè ancora protetta da brevetti, di solito Ibm. Per cui si usa la compressione di Huffman.
Una miglioria che non fa parte dello standard, ma che gradirei veder diffusa è una migliore ricostruzione dei valori assenti della Dct (trasformata Discreta Coseno), quando si usa il Jpeg a forte compressione. Si potrebbe operare una estrapolazione di spettro.
Una operazione simile, forse un poco più semplice, è eseguita dal Minerva Pegasus. Nelle tre figure sotto, a sinistra vediamo l'immagine Bird originale, al centro la vediamo fortemente compressa. Si nota che i blocchi 8x8 con pochi dettagli sono stati appiattiti del tutto, col risulatato di mostrare una sgradevole blocchettatura. Caricando la seconda immagine in Pegasus Minerva vediamo invece la terza immagine (quasi, quì è stata risalvata in jpeg a bassa compressione). Le blocchettature sono state sostituite da uno sfondo ben più gradevole (permettendo di fatto di usare tali fattori di compressione nella pratica, nella quale l'aspetto del risultato è importante). (forse esistono plug-in per browser che decomprimono jpeg con tale metodo).
 
 
Immagine originale di pappagallino in B/N
Immagine Bird originale
256 * 256, 1 byte/pixel B/N
35361 byte Png
Immagine fortemente compressa
Ottenuta col Web Graphics Optimizer
1956 byte Jpeg
La precedente ricostruita col Minerva e risalvata in Jpeg a bassa compressione

    Per vedere meglio l'effetto del Minerva ho ingrandito un particolare dell'immagine tre volte (con interpolazione di ordine 0 eseguita dal browser). Nella prima immagine vediamo la jpeg a forte compressione ricostruita normalmente, ingrandita e intensificata. (L'intensificazione è ottenuta coi comandi Sharpen seguito da Edge - Enhance eseguiti sul Paint Shop Pro 5). La seconda vediamo lo stesso dettaglio intensificato della ricostruita col Minerva. Nella terza immagine vediamo in dettaglio la differenza fra la Jpeg ricostruita normalmente e quella ricostruita col Minerva. (Da notare che non è la differenza fra le intensificate). L'istogramma del risultato è stato stirato (Histogram functions - Stretch).
L'intensificazione è stata fatta per simulare ciò che fa normalmente il nostro sistema visivo (prima una intensificazione dei contrasti locali eseguita dalla retina, poi una intensificazione dei bordi eseguita dal primo stadio della corteccia visiva, la V1).
 
Dettaglio intensificato della seconda immagine (Jpeg da 1956 byte) Dettaglio intensificato della terza immagine (Jpeg ricostruita) Differenza fra la Jpeg da 1956 byte e la ricostruita col minerva. Istogramma stirato.
Vediamo chiaramente l'effetto del minerva sui blocchi contenenti solo la componente DC della trasformata DCT (nel Jpeg si trasforma ogni blocco 8x8 dell'immagine con la Trasformata Coseno Discreta, DCT in inglese, ciò produce una scomposizione in frequenza simile alla trasforma di Fourier. La DC è componente continua del segnale, che nel Jpeg viene trattata separatamente a causa della sua importanza e a causa della sua spesso grande ampiezza). E' evidente la interpolazione della DC fra blocchi adiacenti che  contengono solo essa.
Ad  un esame più attento si nota che l'effetto del Minerva non si limita a questo. Se fosse nell'immagine differenza si dovrebbe notare segnale solo nei blocchi con solo DC, ma ciò non è vero. Non è facile accorgersene, ed è forse impossibile farlo ad occhio nudo, per cui tale effetto è di poca importanza nel risultato finale.
Ecco un altro esempio di decompressione col minerva di una immagine a colori. Quella che segue è una immagine di una volpe fulva a primavera, compressa in Jpeg col Wgo, in near-lossless percettivo (cioè appare quasi indistinguibile dall'originale Bmp):
 

Volpe a primavera 512x512x24M in near-lossless percettivo
Volpe Primavera
512x512x24M, 35849 byte Jpeg Web G. Opt.
Il minerva agisce anche sui piani cromatici:
 
Volpe ad eccessiva compressione col Wgo Volpe compressa, e poi ricostruita col Minerva (e poi ricompressa col Wgo)
Volpe compressa col Wgo a 7647 byte
Stessa immagine ricostruita col Minerva
(poi risalvata col Wgo in near lossless percettivo rispetto alla ricostruita)
Le differenze sono visibili sia nelle zone uniformi, che nelle blocchettature cromatiche, ad esempio sulle cosce, sul dorso, sul muso, dulla gamba anteriore sinistra, sul tronco di legno. La differenza è evidente, Minerva fa un lavoro eccellente!
(Forse si possono avere dei peggioramenti, nell'usare il minerva su immagini originalmente non sfumate. Comunque esse non erano adatte alla compressione Jpeg fin dall'inizio.)


Esistano vari software che permettono una buona compressione tramite il formato Jpeg standard.
Uno dei migliori è Jpeg Optimizer v. 3.01, la sua principale qualità è la possibilità di definire zone con compressione differente nella stessa immagine. Ciò permette di rendere dettagli importanti come occhi, o bordi netti, in maniera accettabile, pur comprimendo molto aree di immagine quasi uniformi. Quì vediamo un esempio dell'immagine Lenna compressa in maniera eccessiva per rendere evidente l'effetto. La prima immagine è l'originale in Png lossless, la seconda è ottenuta dal Web Graphics Optimizer, e mostra la grande potenza di questo software nel formato Jpeg dinamico, col quale si risparmia un 5% circa rispetto al Jpeg normale, senza ulteriori perdite di qualità, apparentemente.
La terza immagine è ottenuta col Jpeg Optimizer, assegnando una compressione minore alla faccia.
 
Lenna Originale 256*256 B/N
65536 byte Pgm
45558 Byte in Png
Web Graphics V. 2.05
http://WebOpt.com
2447 byte Jpeg progressivo (3.73%)
Jpeg Optimizer V. 3.01
www.xat.com
2412 byte Jpeg (3.67%)

    Jpeg Opt. ha anche una opzione per la classificazione automatica del livello di compressione da applicare a ciascun blocco, in base alla quantità di dettagli che contiene. (Da notare che anche lo standard Jpeg prevede una classificazione dei blocchi in maniera simile, ma evidentemente in questo software l'operazione è più accurata). Qui vediamo il risultato dell'operazione di classificazione; tono di rosso più intenso indica maggiore compressione (l'immagine ottenuta, non mostrata, è stata una Jpeg di circa 8500 byte, quasi indistinguibile dall'originale). Jpeg optimizer è il più veloce a mostare l'aggiornamento, quando si muove lo slider del livello di compressione, molto più veloce di Web Graphics Optimizer.
    Ultima nota sul Jpeg Optimizer: gli autori sono probabilmente appassionati di compressione, e quindi hanno cercato di distribuire il loro software in maniera efficiente. Ci sono due versioni del pacchetto, la versione con installazione normale automatica, il cui file occupa 1006KB, e la versione "bare bones" che consiste in un semplice file zip con istruzioni. Per installarlo basta decomprimere il file nella directory desiderata, ed occupa 346KB! Penso che gli algoritmi di compressione e i metodi di installazione andrebbero rivisti sotto il profilo dell'efficienza! (e si vede che gli autori di questo software sono appassionati di compressione, non amano gli sprecgi, come me).
 

Immagini artificili con aree uniformi

Originale
26976 byte Png
in otto colori Png col Photoshop 5
5986 byte Png Photoshop
In otto colori con Dl3ycc, Web Graphics optimizer e Paint Shop Pro 5.
2706 byte Png ottimale

    La prima immagine, occupante 26'976 byte in Png truecolor (167958 in raw truecolor), apparentemente contiene solo pochi colori, bianco, rosso e nero. In realtà a causa dell'antialiasing contiene 5'867 colori. (l'originale Bmp a 1 byte/pixel è stato rifilato e poi ridotto in dimensione al 70%)
Per immagini di questo tipo conviene ridurre il numero di colori e poi salvare con un formato lossless, di solito in Png, se si vuol usare un formato standard. Altrimenti in Bmf se l'immagine ha molti colori o Pic Minerva se ne ha pochi (<=16).
    Usando Photoshop l'ho convertita in 8 colori senza dithering e con la massima qualità (Color Matching: Best), e poi l'ho salvata in Png a 4 bit/pixel con compressione adattativa. Il risultato è la seconda immagine. Occupa 5986 byte e si nota una pessima viratura al beige del colore di fondo.
    E' chiaro che per fare questa quantizzazione cromatica occorre software più specializzato del Photoshop5. Il migliore che ho trovato è Dl3ycc di Dennis Lee (lo stesso autore del miglior compressore audio lossless! <denlee@ecf.toronto.edu> http://www.ecf.utoronto.ca/~denlee/dlquant.htm). Si tratta di un eseguibile a linea di comando di circa 47 KB. E' incredibilmente efficace, e talvolta piuttosto lento. Accetta in I/O solo il formato Ppm (Portable Pixel Map, uno dei formati grafici più semplici, Psp lo carica e salva, Ps no.) e volendo produce anche una quantizzazione con dithering. (Internamente usa tabelle di quantizzazione a 15 bit di precisione e un metodo iterativo. L'autore si era prefisso lo scopo di ottenere il miglior quantizzatore cromatico, e pare che ci sia quasi riuscito, è al livello, e talvolta superiore di quello del Photoshop5.)
Così ho convertito l'immagine in Ppm col Psp. Col comando
Dl3ycc 8 0 imageIn.ppm ImageOut8.ppm
l'ho quantizzata senza dithering in 8 colori.
(per quantizzare con dithering il secondo parametro deve essere 1 così:
Dl3ycc 8 1 imageIn.ppm ImageOut8D.ppm )
Per salvarla in Png occorre portarla da ppm truecolor a 4 bit/pixel. E' un compito banale, ma solo Ps5 ne è capace. (e non Wgo e Ps che producono solo approssimazioni!!). Così converto l'immagine Ppm in Bmp truecolor col Psp, poi col Ps5 la converto in Bmp a 4 bit/pixel con palette Esatta.
A questo punto per la compressione finale uso il Png del Wgo, che è il più ottimizzato. Il risultato è la terza immagine, di solo 2706 byte. Il risultato è ben vicino all'originale.
Per i maniaci della compressione faccio notare che quest'ultima immagine può essere compressa in lossless col Pic del Minerva, Minerva8 0066 19981226.pic, invece che in Png, in 1999 byte (circa 1/84 della Raw truecolor). Anche tale formato Imstar usa la codifica aritmetica Els.

Nota: per visualizzare una immagine in Ps5, anche con dithering, caricando una palette da disco contenete n<256 colori, bisogna assegnare a tutti gli elementi >n della palette (assegnati a nero per default) un colore scelto fra gli n della vera palette, altrimenti l'immagine convertita se conterrà n+1 colori (a meno che il nero non facesse già parte degli n).

Le immagini prodotte dal ray tracing sono spesso pressochè prive di rumore, per cui sono facilmente comprimibili in lossless. Se poi le aree hanno colori uniformi, allora la situazione è ideale. A sinistra c'è l'originale in Png truecolor ottenuto col Wgo, 17'731 byte (354'294 byte in Bmp, 13'728 in Bmf).
(immagine generata da una applet Java tratta da Interactive Ray Tracer v1.0 di Alyosha Efros, Computer Science Division, University of California, Berkeley)
A destra la versione in Jpeg ottenuta col Wgo (Jpeg progressivo a 5 strati, quantizzazione cromatica 4:4:4, 16006 byte (la quantizzazione ad alta risoluzione cromatica è necessaria a causa dei bordi netti colorati)):

Come si vede il Jpeg non è male (benchè richieda solo 1000 byte meno della lossless Png...), ma data la presenza di vaste aree uniformi e l'assenza di rumore (e antialiasing) un formato lossless è più adatto. Col Dl3ycc l'ho quantizzato a 256 colori senza dithering, e col Wgo l'ho salvata in Png a 1 byte/pixel in 10'807 byte:

Tale immagine può essere salvata in 7888 byte col Bmf.
 

Casi indeterminati

Sono quelli più difficili, nei quali sia il Png che il Jpeg sembrano inadatti.
Un caso era quello della compressione di spettrogrammi. Vedi VqfMp3Ra5 0020 19981119 .
Almeno per una immagine il problema di compressione non è stato risolto, e ho accetttato un forte degrado Jpeg e un file piuttosto grande (33'600 byte circa):

In un caso ho dovuto evidenziare con varie elaborazioni le strutture significative, poi portare l'immagine a toni di grigio e salvarla in Jpeg monocromatico:

Il problema con queste immagini è che hanno molte sfumature, e il segnale, cioè le strutture visibili, sono affogate nel rumore. Comprimendo col Jpeg si perdono molti dettagli ad alta frequenza spaziale.

    Un altro esempio rognoso è dato dalla seguente immagine scansionata (tratta da Le Scienze 1995). A sinistra c'è l'originale in Png 1 byte/pixel di 47'743 byte (l'originale Bmp a 1 byte/pixel con dithering occupava 161'478 byte, in Bmf 36'792 byte):
 
47743 byte Png
8966 byte Png (6736 Pic Minerva)
Tale immagine non conviene comprimerla col jpeg a causa dei bordi netti e delle scritte che contengono frequenze spaziali alte.
Per cui occorre diminuire il numero di colori e poi usare un formato lossless.
Nella figuara, in alto a destra c'è un riquadro azzurro originariamente uniforme, che lo scanner ha riempito con rumore, rinforzato poi dal dithering a 256 colori. Per codificare tale riquadro sono necessarie varie sfumature di azzurro, e il rumore di cui è pieno risulta poco comprimibile. Per cui ho fatto la seguente sequnza di operazioni:

1) caricata l'immagine originale in Ps, convertita in truecolor, corretta la curva di gamma (schiarita) e filtrata con Smart Blur, con elevato raggio e treshold sensibile. Tale operazione lascia inalterate le righe e i dettagli e elimina il rumore nel riquadro azzurro e dentro le colonne dell'istogramma.
2) Le aree non sono diventate perfettamente uniformi, ma sfumate a frequenza spaziale molto bassa. Per cui bisogna appiattirle del tutto. Per farlo ho copiato col contagocce il colore azzurro del riquadro ed ho fatto un floodfill con una tolleranza appena sufficiente a riempire tutte le sfumature di azzurro.
3) ho salvato l'immagine in Bmp, l'ho caricata in Psp e risalvata in Ppm
4) col Dl3ycc l'ho convertita a 16 colori
5) caricata dal Psp e risalvata in Bmp (tutto ciò a causa del fatto che Dl3ycc carica solo Ppm e il Photoshop non accetta tale formato, se non come raw, ma diventa inutilmente complicato escludere l'header della Ppm)
6) caricata in Ps, convertita in Indexed Exact, e salvata come Bmp a 4 bit/pixel
7) caricata col Wgo e salvata in Png a 4 bit/pixel in 8966 byte (circa 1/54 della truecolor raw)

Il risultato di tanto lavoro è visibile nella figura di destra, che per certi versi è quasi migliore dell'originale.
Come al solito se si ha necessità di massima compressione si può portare questa immagine a 7'292 byte col Bmf o 6736 byte col Pic Minerva, entrambi lossless.

Data 19981226 Pag. 66

Vedi seguito CompressioneImmagini3