4.3 JPEG-LS und CALIC

Werbung
4.3
JPEG-LS und CALIC
In diesem Abschnitt werden wir die Technik der vorhersagenden Codierung
an drei Beispielen aus der Bildkompression kennen lernen, dem alten JPEGLS Standard, dem neuen JPEG-LS Standard sowie CALIC. JPEG steht für
Joint Photographic Experts Group, LS steht für Lossless. Von JPEG gibt
es mehrere Standards sowohl für die verlustfreie als auch auch die verlustbehaftete Bildkompression. CALIC steht für context adaptiv lossless image
compression. Beginnen wollen wir mit dem einfachsten dieser Verfahren, dem
alten JPEG-LS Standard, der bis zum vorletzten Jahr der offizielle JPEG
Standard in der verlustfreien Bildkompression war.
Bei allen drei Verfahren zur Bildkompression, die wir kennen lernen werden, ist die wesentliche Technik dieselbe. Wir betrachten nur Graubilder,
wobei die Pixel Grauwerte annehmen können, die durch 8 Bit codiert sind.
Jeder Pixelwert liegt also im Bereich 0, . . . , 255. Zunächst einmal werden
die Pixelwerte transformiert. Hierzu wird ausgehend von bereits bekannten
und transformierten Pixelwerten für den nächsten Pixelwert eine sogenannte Vorhersage getroffen. Diese ist in aller Regel ebenfalls ein Wert zwischen
0 und 255. Der transformierte Pixelwert ist dann die Differenz zwischen
dem eigentlichen Pixelwert und dem vorhergesagten Wert. Die transformierten Werte werden dann durch geeignete Verfahren, häufig Varianten
der Huffman-Codierung oder der arithmetischen Codierung codiert. Sinn
der Transformationen ist es wie bei der Textkompression (z.B. BWT), die
Daten so aufzubereiten, dass Huffman-Codierung oder arithmetische Codierung gute Kompressionsergebnisse erzielt.
Beim Decodieren wird dann zunächst die Codierung der transformierten Pixelwerte rückgängig gemacht. Dann werden die transformierten Pixelwerte
in die ursprünglichen Werte zurück gerechnet. Der Decodierer wird in derselben Reihenfolge, die der Codierer bei der Berechnung der Transformation
benutzt hat, die ursprünglichen Pixelwerte berechnen. Hierzu berechnet der
Decodierer zunächst selber die Vorhersagen, die auch der Codierer berechnet hat. Die Differenzen zwischen Vorhersage und eigentlichem Pixelwert
ist gerade die Information des codierten Bildes. Daher kann der Decodierer
mithilfe der Differenzen, die ursprünglichen Pixelwerte berechnen. Da stets
einige Pixel, in der Regel Pixel am Rande des Bildes, nicht transformiert
werden, kann auf diese Weise des vollständige Bild rekonstruiert werden.
85
4.3.1
JPEG-LS (alt)
Der alte JPEG-LS Standard kennt acht verschiedene Arten der Vorhersage
von Pixelwerte. Die Pixel betrachten wir angeordnet in Zeilen und Spalten.
Der Wert des Pixels in Zeile i und Spalte j bezeichnen wir mit I(i, j). Die
ˆ j).
Vorhersage des Codierers für diesen Pixelwert bezeichnen wir mit I(i,
Die acht verschiedenen Vorhersagemodi sind dann in der folgenden Tabelle
zusammengefasst.
ˆ j) = 0
0. I(i,
ˆ j) = I(i − 1, j)
1. I(i,
ˆ j) = I(i, j − 1)
2. I(i,
ˆ j) = I(i − 1, j − 1)
3. I(i,
ˆ j) = I(i − 1, j) + I(i, j − 1) − I(i − 1, j − 1)
4. I(i,
ˆ j) = I(i, j − 1) + (I(i − 1, j) − I(i − 1, j − 1))/2
5. I(i,
ˆ j) = I(i − 1, j) + (I(i, j − 1) − I(i − 1, j − 1))/2
6. I(i,
ˆ j) = (I(i − 1, j) + (I(i, j − 1))/2
7. I(i,
ˆ j) =
Im ersten Modus findet keine Transformation statt, da I(i, j) − I(i,
I(i, j). Im zweiten Modus wird als Vorhersagewert der Wert unmittelbar
über dem aktuellen Pixel genommen. Im letzten Modus wird der Mittelwert
der Pixel über und neben dem aktuellen Pixel als Vorhersagewert genommen. Liegt ein Vorhersagewert nicht mehr im Bereich 0, . . . , 255 so wird er
durch 0 oder 255 ersetzt.
Innerhalb eines Bildes ist nur einer der Vorhersagemodi erlaubt. Es kann also
nicht vom Kontext des Pixels abhängig gemacht werden, welchen Vorhersagemodus der Codierer benutzt. Es ist im Standard allerdings zugelassen,
dass alle acht Modi ausprobiert werden, um dann denjenigen mit der besten
Kompression zu benutzen. Wird JPEG-LS in dieser Form benutzt, werden
in der Regel Kompressionsraten in der Nähe von 2 erreicht.
Dass im alten JPEG-LS Standard die Vorhersage eines Pixelwerts nicht vom
Kontext eines Pixels abhängig gemacht werden kann, ist einer der großen
86
Nachteile dieses Standards. Die beiden nächsten Verfahren haben diesen
Nachteil nicht.
4.3.2
CALIC-Context adaptiv lossless image compression
Bei CALIC geht der Kontext eines Pixels (also die Werte von anderen Pixeln
in der Nähe des Pixels) auf mehrfache Weise in die Berechnung des Vorhersagewertes ein. Sei X das Pixel, für das als nächstes ein Vorhersage wert
bestimmt werden soll. Wir betrachten auch die Pixel N, W, N W, N N, W W,
N E, N N E, deren Position bezüglich X sich aus Abbildung 4.1 ergibt. Eine
Abbildung 4.1: Pixel X und seine Nachbarschaft
initiale Vorhersage X̂ für X wird dann in CALIC folgendermaßen bestimmt.
Initiale Vorhersage in CALIC
Setze
dh := |W − W W | + |N − N W | + |N E − N |
dv
:= |W − N W | + |N − N N | + |N E − N N E|.
Falls dh − dv > 80
X̂ := N .
Sonst, falls dv − dh > 80
X̂ := W .
Sonst,
X̂ := (N + W )/2 + (N E − N W )/4
Falls dh − dv > 32
X̂ := (X̂ + N )/2.
Sonst, falls dv − dh > 32
X̂ := (X̂ + W )/2.
Sonst, falls dh − dv > 8
87
X̂ := (3X̂ + N )/4.
Sonst, falls dv − dh > 8
X̂ := (3X̂ + W )/4.
Die Werte dh , dv stellen fest, ob es in der Nähe von X vertikale oder horizontale Kanten gibt. Je nachdem wie stark diese Kanten ausgeprägt sind,
wird dann die Vorhersage X̂ bestimmt.
Als nächstes wird der Vorhersagekontext von Pixel X bestimmt. Dazu wird
der folgende Vektor betrachtet
(N, W, N W, N E, N N, W W, 2N − N N, 2W − W W ).
Jede Komponente dieses Vektors wird mit der initialen Vorhersage X̂ verglichen. Ist eine Komponente kleiner als X̂, so wird die Komponente durch
1 ersetzt. Sonst wird die Komponente durch 0 ersetzt. Dieses liefert den zu
X gehörigen Kontextvektor VX . Zusätzlich wird der Wert
δ(X) := dh + dv + 2|N − N̂ |
berechnet. Dabei ist N̂ der bereits bekannte endgültige Vorhersagewert für
das Pixel N . Je nachdem welchen Wert δ(X) annimmt, wird in den Vorhersagekontext von X zusätzlich zum Kontextvektor noch 0, 1, 2, 3 aufgenommen.
Für alle bislang bereits betrachteten Pixel, die denselben Kontext wie X besitzen, berechnen wir nun den durchschnittlichen Fehler zwischen den initiale
Vorhersagen der Pixelwerte und den Pixelwerten selber. Dieses nennen wir
den Bias eines Kontextes. Zur initialen Vorhersage X̂ wird nun der Bias des
Vorhersagekontextes von X addiert. Dieses liefert die endgültige Vorhersage
X̄ für X.
Nun wird die Differenz X − X̄ zwischen X und X̄ berechnet. Dieses Differenz
kann zunächst einmal zwischen −255 und 255 liegen. Diese Vergrösserung
des Alphabet von 0, . . . , 255 auf −255, . . . , 255 ist für die weitere Codierung
ungünstig. Wir beobachten nun zunächst, dass bei Vorhersagewert X̄ für die
Differenz X − X̄ nur die 255 Werte −X̄, . . . , 0, . . . 255 − X̄ auftreten können.
Diese 255 Werte werden wieder auf den Bereich 0, . . . , 255 abgebildet. Dieses
geschieht durch die folgende von X̄ abhängende Abbildung. Ist X̄ ≤ 127 so
88
gilt
0
1
−1
2
..
.
→
→
→
→
X̄
−X̄
..
.
→ 2X̄ − 1
→ 2X̄
..
.
0
1
2
3
..
.
255 − X̄ → 255
Ist X̄ ≥ 128 so gilt.
0
1
−1
2
..
.
→
→
→
→
0
1
2
3
..
.
255 − X̄ → 2(255 − X̄) − 1
X̄
→ 2(255 − X̄)
..
..
.
.
−X̄
→ 255.
Die so erhaltenen Werte werden dann zunächst mit dem rekursiven Indizieren codiert.
Rekursives Indizieren codiert natürliche Zahlen. Gegeben ist im einfachsten
Fall eine Basis B. Um eine Zahl n zu codieren, schreiben wir n = qB + r, 0 ≤
r ≤ B − 1. Die Zahl n wird dann codiert durch B, B, . . . , B , r.
|
{z
}
q-mal
Rekursive Indizierung kann aber auch mit k unterschiedlichen Basen B1 , . . . , Bk
durchgeführt werden. Diese Variante erklärt auch den Namen rekursive Indizierung. Sei wieder n ∈ N. Ist n ≥ B1 − 1, so wird in die Codierung von n
die Basis B1 aufgenommen, dann setzt man n := n − B1 . Der neue Wert von
n wird nun weiter codiert, wobei n jetzt mit der zweiten Basis B2 verglichen
wird. Dieses macht man so lange bis entweder ein i < k erreicht wird mit
n < Bi oder bis die Basis Bk erreicht wird. Gilt n < Bi , i < k, so wird als
letzter Wert der aktuelle Wert von n in die Codierung aufgenommen. Ist
man bei der Basis Bk angelangt, dann wird der aktuelle Wert von n wie
oben geschrieben als n = qBk + r, 0 ≤ r ≤ Bk − 1. Es werden dann noch q
89
Bk ’s und ein r an die Codierung angehängt. In der folgenden Tabelle sind
für n = 17 und die Basen B1 = 3, B2 = 5, B3 = 7 alle Zwischenwerte von
n, die Zwischenergebnisse der Codierung sowie die als nächstes verwendete
Basis aufgeführt.
n Codierung Basis
17
14
9
3
3, 5
3, 5, 7, 2
B1 = 3
B2 = 5
B3 = 7
Ist die rekursive Indizierung einer Zahl n gegeben durch eine Folge von
m
X
Zahlen c1 , . . . , cm so gilt n =
ci .
i=1
Bei CALIC wird die rekursive Indizierung benutzt, um die in den Bereich
0, . . . , 255 abgebildeten Differenzen X − X̄ zu codieren. Dabei ist eine Basismenge B1 , . . . , Bk , die der Grösse nach aufsteigend sortiert ist, vorgegeben.
Jedoch wird bei der rekursiven Indizierung nicht unbedingt mit der Basis B1
begonnen. Ist die Differenz X − X̄ groß, so wird die rekursive Indizierung bei
einer Basis Bi mit i > 1 beginnen. Wie genau dieses gemacht wird, werden
wir nicht erläutern. Die Ergebnisse (d.h., die Folge der Basiselement Bi und
eventueller Reste r) der rekursiven Indizierung schließlich werden in CALIC
noch mit Huffman-Codierung oder arithmetischer Codierung komprimiert.
CALIC liefert in der Praxis sehr gute Kompression. Allerdings, und dieses
sollte aus unserer Beschreibung auch hervorgehen, ist CALIC nicht sonderlich effizient. Der neue JPEG-LS Standard hat deshalb wesentliche Ideen
von CALIC übernommen. Versucht diese aber einfacher und effizienter umzusetzen.
4.4
JPEG-LS (neu)
Zwei Schritte an CALIC sind besonders ineffizient. Zunächst einmal ist die
Berechnung der initialen Vorhersage aufwendig. Weiter ist es aufwendig für
jedes Pixel die Differenz X − X̄ auf unterschiedliche Art in der Bereich
0, . . . , 255 abzubilden. Beides wird im neuen JPEG-LS Standard einfacher
gehandhabt. Betrachten wir die initiale Vorhersage in JPEG-LS. Sei X das
nächste Pixel für das eine Vorhersage berechnet werden soll. Die benachbarten Pixel sind wie in Abbildung 4.1 bezeichnet. Dann wird in JPEG-LS die
Vorhersage X̂ für X mit dem folgenden Algorithmus berechnet.
90
Initiale Vorhersage bei JPEG-LS
Falls N W ≥ max(W, N )
X̂ := max(W, N ).
Sonst,
Falls N W ≤ min(W, N )
X̂ := min(W, N ).
Sonst,
X̂ := W + N − N W .
Wie bei CALIC wird die initiale Vorhersage X̂ verfeinert, indem für jedes
Pixel ein Vorhersagekontext definiert wird. Für bereits betrachtete Pixel,
die denselben Vorhersagekontext wie X haben, wird die durchschnittliche
Abweichung zwischen der Vorhersage und dem eigentlichen Pixelwert berechnet. Dieses ist der Bias des Kontextes. Die Vorhersage X̄ enthält man
nun, indem zu X̂ der Bias des Kontextes von X addiert bzw. subtrahiert
wird.
Um den Komtext eines Pixels zu berechnen, definieren wir zunächst die drei
Werte D1 , D2 , D3 durch
D1 =
NE − N
D2 =
N − NW
D3 = N W − W.
Weiter kennt JPEG-LS drei vom Benutzer definierte Konstanten T1 , T2 , T3 .
Der Komponenten des Kontextvektors QX := (Q1 , Q2 , Q3 ) von X sind dann
91
definiert durch
Di ≤ −T3 ⇒ Qi = −4
−T3 < Di ≤ −T2 ⇒ Qi = −3
−T2 < Di ≤ −T1 ⇒ Qi = −2
−T1 < Di ≤ 0 ⇒ Qi = −1
Di = 0 ⇒ Qi = 0
0 < Di ≤ T1 ⇒ Qi = 1
T1 < Di ≤ T2 ⇒ Qi = 2
T2 < Di ≤ T3 ⇒ Qi = 3
T3 < Di ⇒ Qi = 4
Der Kontext des Pixels X besteht nun aus allen (bisher betrachteten) Pixeln,
deren Kontextvektor mit dem Kontextvektor QX von X oder mit −QX
übereinstimmt. Der Bias des Kontextes von X wird zu X̂ addiert, falls die
erste Komponente von Q positiv ist, sonst wird der Bias subtrahiert. Dieses
liefert dann die endgültige Vorhersage X̄ für das Pixel X.
Als nächstes werden dann die Differenzen X − X̄ zwischen den Pixelwerten X und ihren Vorhersagen X̄ codiert. Dazu werden wie diese Differenzen zwischen Pixelwert und Vorhersage zunächst einmal in den Bereich
−127, . . . , 128 abgebildet. Anders als bei CALIC geschieht dies bei JPEG-LS
unabhängig vom Wert X̄. Es werden die folgenden Regeln benutzt:
Ist X − X̄ < −127, so wird X − X̄ ersetzt durch X − X̄ + 255
Ist X − X̄ > 128,
so wird X − X̄ ersetzt durch X − X̄ − 255
Man überlege sich, dass der Decodierer diese Abbildung rückgängig machen
kann, obwohl sie nicht injektiv ist.
Die in den Bereich −127, . . . , 128 transformierten Werte werden dann mit
adaptiv gewählten Golomb-Code codiert. Auf diese Codes gehen wir unten
genauer ein. Der neue JPEG-LS Standard liefert in der Praxis in der Regel etwas bessere Ergebnisse als der alte JPEG-LS Standard, jedoch etwas
schlechtere Ergebnisse als CALIC.
92
4.4.1
Golomb-Codes
Golomb-Codes werden zur Codierung von natürlichen Zahlen verwendet. Betrachten wir zunächst folgendes Problem. Wir wollen die Zahlen 0, . . . , m −
1 durch einen Präfix-Code codieren. Sei l := dlog me. Dann können wir
als Präfix-Code für 0, . . . , m − 1 die l-Bit Binärdarstellungen der Zahlen
0, . . . , m − 1 nehmen. Ist m eine Zweierpotenz, ist dieses auch nicht zu verbessern. Ist m jedoch keine Zweierpotenz, sollten wir auch einige l − 1-Bit
Binärdarstellungen nehmen können, um die restlichen Zahlen dann noch
geeignet so zu codieren, dass wir einen Präfix-Code erhalten.
Betrachten wir, wie viele dieser l − 1-Bit Binärdarstellungen wir nehmen
können. Nehmen wir weiter an, wir stellen die Zahlen 0, . . . , c−1 mit l−1 Bits
dar, die restlichen Zahlen sollen dann durch jeweils l Bits codiert werden. Da
wir einen Präfix-Code erhalten wollen, schließt die l −1 Bit Binärdarstellung
von r, r ≤ c − 1 genau 2 Codeworte der Länge l aus. Es sind dies die lBit Binärdarstellungen von 2r und von 2r + 1. Damit wir für alle Zahlen
zwischen c und m − 1 noch genügend Codeworte der Länge l finden können,
muss gelten
2l − 2c ≥ m − c oder c ≤ 2l − m.
Denn für c Zahlen benutzen wir die l − 1-Bit Binärdarstellung als Codewort.
Für die restlichen m−c Zahlen wollen wir l-Bit Codeworte benutzen. Jedoch
schließen die c Binardarstellungen de Länge l − 1 genau 2c der 2l möglichen
Codeworte der Länge l aus. Genauer sind die l-Bit Binärdarstellungen der
Zahlen
0, 1, 2, . . . , 2c − 1
ausgeschlossen als Codeworte der Länge l. Wir wählen nun
c := 2l − m.
Weiter codieren wir eine Zahl r mit 2l − m ≤ r ≤ m − 1 durch die l-Bit
Binärdarstellung von 2l − m + r. Nach dem oben Gesagten liefert dieses eine
Präfix-Code.
Betrachten wir ein Beispiel. Sei m = 11. Wir wollen die Zahlen von 0, . . . , 10
codieren. Weiter ist l = 4 und 2l −m = 6 Wir werden die Zahlen 0, . . . , 5 also
durch ihre 3-Bit Binärdarstellung codieren. Alle anderen Zahlen r werden
durch die 4-Bit Binärdarstellung von r + 6 codiert. Insgesamt erhalten wir
93
folgenden Tabelle von Codeworten.
Zahl Codierung
0
000
Zahl Codierung
6
1100
1
001
7
1101
2
010
8
1110
3
011
9
1111
4
100
5
101
Nennen wir die gerade beschriebenen Codes die optimierten Binärcodes. Die
Golomb-Codes machen von den optimierten Binärcodes Gebrauch. Sei B ∈
N. Mit dem Golomb-Code zur Basis B können beliebige natürliche Zahlen
codiert werden. Golomb-Codes sind immer Präfix-Codes. Um die Zahl n im
Golomb-Code zur Basis B zu codieren, schreiben wir n als
n = qB + r, 0 ≤ r ≤ B − 1.
Die Zahl n wird dann im Golomb-Code zur Basis B codiert durch 1q , gefolgt
von 0, gefolgt vom Codewort für r im optimierten Binärcode für die Zahlen
0, . . . , B − 1.
Wählen wir als Beispiel B = 11 und betrachten die Codierung von 149. Es
gilt 149 = 13 · 11 + 6. Die optimierte Binärcodierung von 6 im Code für die
Zahlen 0, . . . , 10 ist gegeben durch 1100 (siehe Tabelle oben). Damit ist die
Codierung von 149 im Golomb-Code zur Basis 11 gegeben durch
113 01100 = 111111111111101100.
Wir sagten oben, im neuen JPEG-LS Standard werden adaptiv gewählte
Golomb-Codes gewählt. Dabei bezieht sich adaptiv auf die Wahl der Basis.
Es sollte klar sein, dass die Codierung großer Zahlen mit einem GolombCode mit kleiner Basis nicht sehr effektiv ist. Es ist auch nicht effektiv
kleine Zahlen mit einem Golomb-Code großer Basis zu codieren. Deshalb
wird bei JPEG-LS die Grösse der zu codierenden Werte überprüft und die
Basis des Golomb-Codes entsprechend angepasst. Auf die Details wollen wir
hier nicht eingehen.
94
4.5
JPEG- Der Standard für Kompression mit Verlust
Zum Abschluss wollen wir den JPEG-Standard für die Bildkompression mit
Verlust skizzieren. Wir werden sehen, dass viele Techniken, die wir bei der
verlustfreien Kompression gesehen haben, auch hier angewandt werden. Wir
beschränken uns wieder auf Graubilder mit Graustufen zwischen 0 und 255.
Allerdings werden durch JPEG diese Werte in den Bereich −128, . . . , 127
abgebildet, indem von jedem Pixelwert 128 abgezogen wird.
JPEG dann arbeitet in drei Phasen
1. einer Transformation
2. einer Quantisierung
3. einer Codierung mit Huffman-Codes oder der arithmetischen Codierung.
Den Transformations- und Codierungsschritt kennen wir schon aus der vorherigen Abschnitte. Neu ist die Quantisierung. Dies ist der einzige Schritt
der zu Qualitätsverlusten führen kann.
Wie bei der Textkompression oder den verlustfreien
Bildkompressionstechniken soll die Transformation eines Bildes für den Codierungsschritt vorbereiten. Sie soll aber auch die Quantisierung unterstützen.
Bei JPEG wird die Cosinus-Transformation benutzt. Hierzu wird zunächst
das Bild in 8 × 8 Blöcke aufgeteilt. Jeder Block wird separat transformiert.
Sei X ein solcher 8×8 Block. Dieser wird transformiert durch die Abbildung
T = T (X) := C · X · C T ,
(4.1)
wobei die Einträge Cij , 0 ≤ i, j ≤ 7 der 8 × 8-Matrix C gegeben sind durch

1

i = 0, j = 0, . . . , 7
 √8
Cij =

 1 cos( (2j+1)i ) i = 1, . . . , 7, j = 0, . . . , 7.
2
16
Der Name Cosinus-Transformation erklärt sich aus der zweiten Zeile diese
Definition der Cij . Das Bild T von X unter der Cosinus-Transformation ist
selber wieder eine 8 × 8-Matrix oder ein 8 × 8 Block, jetzt aber mit reellen
Zahlen. Wir schreiben T = (Tij )0≤i,j≤7 . Aus (4.1) und der Definition der
Cij folgt, dass jeder Wert Tij ein gewichteter Durchschnitt der Werte in X
ist. In der Regel können die Einträge von T nicht exakt dargestellt werden,
95
da es sich um reelle Zahlen handelt. Wir werden also immer Approximationen benutzten müssen. Dieses bedeutet natürlich schon einen Verlust an
Information. Dieser ist jedoch vernachlässigbar.
Betrachten wir ein Beispiel für den Effekt, den die Cosinus-Transformation
hat. Der Block X sei wie folgt gegeben
124
121
126
124
X=
127
143
150
156
125
121
124
124
127
142
148
159
122
121
123
125
128
143
152
158
120
119
122
125
129
142
152
155
122
119
121
126
130
140
152
158
119
119
121
125
128
139
152
158
117
120
120
124
127
139
150
157
118
118
120
124
125
139
151
156
Nach Anwendung der Cosinus-Transformation erhalten wir
39.88
6.56 −2.24 1.22
−0.37
−102.43 4.56
2.26
1.12
0.35
37.77
1.31
1.77
0.25
−1.50
−5.67
2.44 −1.32 −0.81
1.41
T =
−3.37 −0.74 −1.75 0.77
−0.62
5.98
−0.13 −0.45 −0.77
1.99
3.97
5.52
2.39 −0.55 −0.051
−3.43
0.51 −1.07 0.87
0.96
−1.08
−0.63
−2.21
0.22
−2.65
−0.26
−0.84
0.09
0.79
1.13
−1.05 −0.48
−0.10 0.23
−0.13 0.17
−1.30 0.76
1.46
0.00
−0.52 −0.13
0.33
0.01
In diesem Beispiel konzentrieren sich die große Werte in der linken oberen
Ecke von T . Dieses ist im Allgemeinen so. Es kann auch gezeigt werden, dass
nur Änderungen in diesem Bereich für das menschliche Auge leicht wahrnehmbar sind. Hiermit ist folgendes gemeint. Ändern wir Werte in T leicht
und berechnen dann das Inverse der Cosinus-Transformation der geänderten
Matrix, so erhalten wir nach Rundung ein Bild mit Grauwerten. Dieses unterscheidet sich vom ursprünglichen Bild nur dann deutlich wahrnehmbar,
wenn Werte in der oberen linken Ecke von T geändert wurden.
Ordnen wir die Einträge von T gemäss dem Zigzag-Muster in Abbildung 4.2
an, so sehen wir, dass die Einträge vorne in der Anordnung besonders wichtig sind. Nun kommen wir zur Quantisierung. Dieses bedeutet im wesentlichen, dass wir die Werte in T nur mit beschränkter Genauigkeit darstellen.
Wiederum, da die Werte der linken oberen Ecke von T wichtiger für die
Wahrnehmung sind, werden diese Werte genauer dargestellt als die anderen Werte. JPEG verwendet eine Quantisierungstabelle. Dieses ist ein 8 × 8
96
Abbildung 4.2: Zigzag-Ordnung bei JPEG
Block Q mit natürlichen Einträgen Qij , 0 ≤ i, j ≤ 7. Der Wert Tij in T wird
dann ersetzt durch
b
Tij
1
+ c.
Qij
2
(4.2)
D.h., Tij wird durch Qij geteilt und das Ergebnis zur nächsten ganzen Zahl
gerundet. Der JPEG Standard schreibt keine Quantisierungstabelle vor. Eine empfohlene Tabelle ist durch
16
12
14
14
Q :=
18
24
49
72
11
12
13
17
22
35
64
92
10
14
16
22
37
55
78
95
16 24 40
19 26 58
24 40 57
29 51 87
56 68 109
64 81 104
87 103 121
98 112 100
51 61
60 55
69 56
80 62
103 77
113 92
120 101
103 99
gegeben. Wenden wir diese Quantisierungstabelle auf die Matrix T von oben
97
an, erhalten wir
2
−9
3
0
0
0
0
0
1
0
0
0
0
0
0
0
0
0
0
0
0
0
0
0
0
0
0
0
0
0
0
0
0
0
0
0
0
0
0
0
0
0
0
0
0
0
0
0
0
0
0
0
0
0
0
0
0
0
0
0
0
0
0
0
Den Effekt, den wir hier beobachten können, ist typisch für JPEG. Zunächst
einmal gibt es nur wenige von Null verschiedene Einträge. Weiter konzentrieren sich die Einträge 6= 0 in der linken oberen Ecke. Eine solche Matrix
lässt sich natürlich gut mit Huffman-Codes codieren. Dieses wollen wir als
nächstes beschreiben.
Die Codierung der quantisierten Einträge erfolgt in der Reihenfolge wie
sie durch den Zigzag-Durchlauf gegeben ist. Der erste Eintrag, linke obere Ecke, heißt der DC-Koeffizient. Die restlichen Einträge werden die ACKoeffizienten genannt. Die Codierung von DC- bzw. AC-Koeffizienten erfolgt
unterschiedlich. Der DC-Koeffizient eines Blocks wird nicht selber codiert.
Vielmehr wird die Differenz zum DC-Koeffizienten des vorangegangenen 8×8
Blocks codiert. Für die Differenzen wird nun ein Huffman-Code benutzt. Da
die Differenzen aber zu viele unterschiedliche Werte annehmen können, ist es
kaum möglich eine Huffman-Tabelle für alle möglichen Werte der Differenzen
zu erstellen und zu speichern. Stattdessen werden Kategorien K0 , K1 , . . . , Kr
von Werten erstellt. Die Kategorie Ki enthält dabei 2i Werte. Dieses sind
die Werte
−2i + 1, −2i + 2, . . . , −2i−1 , 2i−1 , 2i−1 + 1, . . . , 2i − 1.
Die Anzahl der Kategorien ergibt sich aus der Anzahl der möglicher Werte der Differenzen von DC-Koeffizienten. Für die Kategorien wird nun ein
Huffman-Code erstellt. Die zugrunde gelegte Wahrscheinlichkeitsverteilung
kann dabei vorher aus den Daten aller 8 × 8 Blöcke berechnet werden. Es
kann aber auch eine fest gewählte Verteilung sein.
Innerhalb der Kategorie Ki sind die Elemente mit den Zahlen von 0, . . . 2i −1
indiziert. Jeder solcher Index kann also durch i Bits dargestellt werden.
Soll der Wert w eines DC-Koeffizienten codiert werden, so wird zunächst
die Kategorie Ki bestimmt, die w enthält. Dann wird w codiert durch die
Huffman-Codierung von Ki gefolgt vom Index von w innerhalb von Ki .
98
Die AC-Koeffizienten werden ähnlich, aber etwas komplizierter codiert. Bei
den AC-Koeffizienten werden keine Differenzen, sondern die Koeffizienten
selber codiert. Innerhalb eines Blocks werden die Koeffizient in der Reihenfolge ihres Auftretens in der Zigzag-Ordnung codiert. Da wir erwarten, dass
es unter den AC-Koeffizienten viele 0 gibt, ist es sinnvoll, die 0 gesondert zu
behandeln. Sei w 6= 0 der Wert eines AC-Koeffizienten und sei l die Anzahl
der AC-Koeffizient mit Wert 0 zwischen diesem AC-Koeffizienten und dem
letzten von Null verschiedenen AC-Koeffizienten (immer in der Reihenfolge gemäss der Zigzag-Ordnung). Wir codieren dann den Wert w zusammen
mit dem Wert l für die Anzahl der Nullen vor w. Hierzu werden wie für die
Differenzen von DC-Koeffizienten Kategorien L0 , . . . , Ls für die Werte der
AC-Koeffizienten angelegt. In jeder Kategorie sind die einzelnen Werte wiederum indiziert. Für die Menge der Paare (Lj , l) gibt es einen Huffman-Code.
Um das Paar (w, l) zu codieren, wird zunächst die Kategorie Lj bestimmt,
die w enthält. Dann wird (w, l) codiert durch die Huffman-Codierung von
(Lj , l) gefolgt vom Index von w in Lj .
Es gibt hier noch einige technische Details auf die wir nicht eingehen wollen.
Was z.B. geschieht, wenn die Folge der AC-Koeffizienten mit einer Folge von
0 endet? Stattdessen wollen wir kurz auf die Decodierung eingehen. Beim
Decodieren werden zunächst mit Hilfe der Huffman-Codes und der Kategorien die DC- und AC-Koeffizienten aller Blöcke rekonstruiert. Dann wird
jeder Koeffizient mit dem entsprechender Faktor aus der Quantisierungstabelle multipliziert. Als nächstes wird die Inverse der Cosinus-Transformation
auf jeden Block angewandt. Da die Matrix C, wie oben definiert, orthogonal
ist, gilt C −1 = C T . Also ist das Inverse der Cosinus-Transformation gegeben
durch C T · T · C. Schließlich wird dann noch auf jeden Wert der Wert 128
addiert, um die ursprüngliche Verschiebung der Grauwerte in den Bereich
−128, 127 rückgängig zu machen.
Dass bei der Decodierung nicht wieder das ursprüngliche Bild entsteht, liegt
ausschließlich am Quantisierungsschritt, denn im Allgemeinen gilt
Qij · b
Tij
1
+ c 6= Tij .
Qij
2
Durch das Runden fehlt Information, die unwiederbringlich verloren ist.
99
Herunterladen
Explore flashcards