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