Bildkompression Proseminar Datenkompression Daniel Koch 0
Inhalt INHALT...1 VERLUSTFREIE KOMPRESSIONSVERFAHREN...2 VERLUSTBEHAFTETE KOMPRESSIONSVERFAHREN...3 YUV-FARBREDUKTION...3 QUANTISIERUNG...3 JPEG...4 YUV-Reduktion...4 8x8-Cluster...4 DCT(Diskrete Kosinustransformation)...4 Quantisierung...5 Entropy Encoding (Zick-Zack)...6 Huffmann-Codierung...6 QUELLENANGABE...8 1
Verlustfreie Kompressionsverfahren Die verlustfreien Kompressionsverfahren werden vorwiegend in der professionellen Bildbearbeitung eingesetzt. Da bei verlustbehafteten Verfahren grundsätzlich selbst bei der höchsten Qualität Verluste bezüglich der Detailtreue und Farbe entstehen, sind diese nicht oder nur sehr eingeschränkt einsetzbar. Es ist also erforderlich einen Weg zu finden diese Bilddaten zu komprimieren und bei Bedarf deren Originalzustand wieder herzustellen. Natürlich wäre für diesen Zweck jedes verlustfreie Verfahren möglich, jedoch haben gerade Fotos häufig leichte Farbvarianzen (von Pixel zu Pixel). Deshalb haben es Kompressoren wie LZ77 oder auch Huffman große Schwierigkeiten, dieses Material vernünftig zu bearbeiten, da sie ja auf der Gleichheit von Datenströmen bzw. der Häufigkeit bestimmter Zeichen aufsetzten. Um dennoch diese Verfahren zu nutzen bemüht man einen Präprozessor (predictive coder). Dieser setzt genau auf der Tatsache auf das in Bildern häufig fliesende Farbübergänge bestehen. Dazu wird das Bild zunächst in seine drei Farbwerte (RGB) zerlegt. Es werden also nur Graustufenbilder bearbeitet. Im folgenden ist ein Auszug aus einer Bilddatei gegeben. Es soll das Pixel in der Mitte codiert werden. Nehmen wir nun den kompletten Block unter die Lupe: Egal ob Huffman oder LZ77, so wie er vor uns liegt wäre keine sinnvolle Kompression möglich. Codiert man jedoch alle Werte nach dem obigen Muster ergibt sich folgendes Bild: <16>, <+2>, <+1>, <-4>, <+2>, <+3>, <-7>, <+3>, <+2>; Man erkennt nun eine viel besser komprimierbare Zeichenfolge. Huffmann erscheint hier geradezu prädestiniert: 3x<+2>, 2x<+3> etc. Bedenkt man das unser Beispiel nur 3x3 Pixel groß ist, kann man sich leicht vorstellen, das gerade technische Zeichnungen wenn sie denn im Pixelformat vorliegen sollten durchaus hohe Kompressionsraten erwarten lassen (da ja das meiste weiß ist). Aber auch Fotos können mit dieser Methode noch gut komprimiert werden. Des weiteren erzielt man auch mit BWT oder LZ77 mit Huffmann-Postprozessor sehr gute Ergebnisse. Es gibt natürlich noch weitere Verfahren, welche sich an dieses Anlehnen. Zum Beispiel könnte man das obere und linke Pixel in die Vorhersage einbeziehen. Allerdings gibt es dabei eine Besonderheit: 16 18 19 15 17 (15+18)/2=16.5 16 18 19 15 17 20 13 16 18 Wir nehmen zunächst den einfachsten Fall. Das Pixel (17) soll aus dem Wert links daneben vorhergesagt werden. Es weicht genau um +2 ab. 16.5 ist kein ganzzahliger Wert. Jedoch lässt sich dieses Problem recht einfach dadurch lösen, dass man im Encoder wie auch im Decoder die Nachkommastellen weglässt und das selbe Rundungsverfahren verwendet. Man würde demnach <+1> codieren. Eine weitere Steigerung währe das Einbeziehen aller Randpixel. Man käme dann auf den Wert (16+18+19+15)/4=17. Damit würde die 0 codiert werden. 2
Verlustbehaftete Kompressionsverfahren YUV-Farbreduktion Wie bereits erwähnt, werden alle Bilddaten vor der Bearbeitung in Graustufen-Bilder zerlegt. Dabei wird zwischen Drei und Vier-Kanal Bildern unterschieden. Das bedeutet allerdings auch den drei bzw. vierfachen Speicherplatzbedarf. Allerdings hat das menschliche Auge bei weitem nicht die erforderliche Auflösung um alle gespeicherten Informationen wahrzunehmen. Genau an diesem Punkt setzt YUV an. Die Farbinformationen werden leicht komprimiert. Y wird in der vollen Auflösung gespeichert, da es die Helligkeitsinformationen beinhaltet. U und V (die Farbinformationen) werden auf die halbe Auflösung heruntergerechnet So hat man schon einmal die Hälfte eingespart. Der Betrachter sprich das menschliche Auge - erkennt jedoch keinen Unterschied, da Farbinformationen sehr viel schlechter aufgelöst werden können als Helligkeitsinformationen. Die Umrechnungsformeln lauten für: Y=0,299R+0,587G+0,114B (R rot, G grün, B blau) U und V sind die Differenzen der Farbinformationen von der Helligkeit Y, also: U=R-Y V=B-Y G ist ja schon zum Großteil in Y enthalten Nach folgender Matrix lässt sich die Berechnung auch auf einfachere Art und Weise durchführen: Y 0,229 0,587 0,144 R U = 0,701-0,587-0,114 * G V -0,299-0,587 0,886 B und zurück: R 1 1 0 Y G = 1-0,509-0,194 * U B 1 0 1 V 3 Es fällt auf, das bis jetzt abgesehen von der Reduktion der Farbkanäle nicht komprimiert wurde. Die Daten wurden lediglich mathematisch umgeformt. Der Nachteil dieser Methode ist, dass an harten Farbkanten speziell von Rot zu Grün blockartige Strukturen auftreten können. Da dieses Verfahren aber nie für Schemazeichnungen oder ähnliches entwickelt wurde, und Fotos nahezu perfekt reproduziert werden, ist dies unerheblich. Es bilden außerdem die Grundlage für Jpeg, Mpeg und DV. Quantisierung Es gibt zwei Arten der Quantisierung, einmal die Scalar Quantization (Skalarquant i- sierung) oder kurz SQ und die Vector Quantization (Vektorquantisierung) VQ. Beide arbeiten völlig verschieden. Die SQ ist die einfachste. Sie rundet Werte auf bestimmte (skalare) Größen. Zum Be i- spiel kann man 8Bit Farbwerte auch in 5Bit speichern. Der Unterschied fällt kaum auf. Nur bei feinen Farbverläufen sieht man die Einbuße doch recht drastisch. Beim Anzeigen werden die 5Bit wieder auf 8Bit hochgerechnet. Das macht eine Ersparnis von 1Byte pro Pixel aus. 3x8Bit=24Bit ; 3x5Bit=15Bit 16Bit Die VQ ist eigentlich ein sehr weit gefächertes Gebiet. Deshalb will ich an dieser Stelle auch nur die einfachste Methode darstellen. Die VQ geht einen völlig and e- ren Weg. Sie reduziert selektiv die Bildauflösung nach folgendem Muster: Haben rechteckig (oder auch quadratisch) beieinanderliegende Pixel in einem vordefiniertem Toleranzbereich die selben Farbwerte, werden sie als ein Pixel gespeichert. Man erkennt jedoch schnell, das dieses Verfahren um zufriedenstellende Kompressionsraten zu erreichen, die Bildqualität sehr drastisch angreift. Der Vorteil liegt aber in der gerade bei der Dekompression eno r- men Geschwindigkeit. Diese Art der Quantisierung wird deshalb nur selten zur Bild-
Bildkompression eingesetzt. Jedoch war sie Bestandteil der ersten Videokompressoren. Jpeg Da Jpeg das wohl bekannteste Kompressionsverfahren ist, soll es an dieser Stelle auch ausführlich behandelt werden. Die Baseline-Jpeg: Ausgangsbild YUV-Reduktion Unterteilung 8x8-Cluster DCT Quantisierung Zig-Zag-Coding Huffmann-Codierung Komprimierter Datenstrom YUV-Reduktion In der Regel werden die U und V Kanäle auf ein Viertel der Auflösung heruntergerechnet (also horizontal und vertikal ha l- biert). Die so erhaltenen Kanäle werden wie drei Graustufenbilder codiert. 8x8-Cluster Die so entstandenen Bilder werden in 8x8 große Blöcke unterteilt. Jpeg arbeitet somit weder auf Pixel noch auf Gesamtbildbasis. Die folgenden Methoden werden immer auf diese 8x8-Cluster angewandt. DCT(Diskrete Kosinustransformation) Die DCT führt eine Frequenzanalyse über die direkten Helligkeitswerte des Clusters durch. Dabei stellt eine hohe Frequenz einen schnellen Helligkeitswechsel von link nach recht oder von oben nach unten dar, eine tiefe einen allmählichen. Speichert man nun die hohen Frequenzen weniger genau erhält man ein etwas ve r- schwommeneres Bild. Jedoch hat man durch diesen Effekt den Vorteil, dass man die Bildschärfe genau regulieren kann. Mathematisch bedeutet das folgendes: Sei f(x, y) ein 8x8 Feld mit den originalen Helligkeitswerten konvertiert von vorze i- chenlosen Ganzzahlen zu vorzeichenbeha f- teten (damit bleiben die Ergebnisse möglichst klein). F(u, v) ist ein weiteres Feld selber Größe welches die transformierten Werte beinhaltet. Natürlich könnte man nun die DCT in einem Zug durchrechnen, d.h. zweidimens i- onal, allerdings wäre dies neben der Undurchschaubarkeit um ein vielfaches langsamer, als die Berechnung ausschließlich mit eindimensionalen DCTs durchzuführen F 8 (y,u) = C u F 8 (v,u) = 7 2 x=0 C v 7 2 y=0 mit C_n=1/Wurzel(2) für n=0; C_n=1 für n! = 0 f (y,x) cos (2x+1)π u 16 f(y,u) cos (2y+1)π v 16 Zunächst werden alle Zeilen transformiert danach alle Spalten, wobei die Reihenfolge eigentlich keine Rolle spielt. Es fällt auf, dass dies einen immensen Rechenaufwand darstellt. Allein für ein 8x8-Feld müssen 128 Kosinus-Berechnungen durchgeführt werden. Die Komponente F(0,0) spielt eine wesentliche Rolle. Sie ist horizontal wie auch vertikal frequenzlos und stellt die Gesamtbzw. Durchschnittshelligkeit des Blocks dar. Sie wird folgend gesondert behandelt und DC-Koeffizient genannt. 4
Diese Tabelle stellt ein 8-Bit Graustufenbild dar. 139 144 149 153 155 155 155 155 144 151 153 156 159 156 156 155 150 155 160 163 158 156 156 156 159 161 162 160 160 159 159 159 159 160 161 161 160 155 155 155 161 161 161 161 160 157 157 157 162 162 161 163 162 157 157 157 162 162 161 161 163 158 158 158 Und hier die transformierte Tabelle (auf eine Nachkommastelle gerundet): 235,6-1,0-12,1-5,2 2,1-1,7-2,7 1,3-22,6-17,5-6,2-3,2-2,9-0,1 0,4-1,2-10,9-9,3-1,6 1,5 0,2-0,9-0,6-0,1-7,1-1,9 0,2 1,5 0,9-0,1 0,0 0,3-0,6-0,8 1,5 1,6-0,1-0,7 0,6 1,3 1,8-0,2 1,6-0,3-0,8 1,5 1,0-1,0-1,3-0,4-0,3-1,5-0,5 1,7 1,1-0,8-2,6 1,6-3,8-1,8 1,9 1,2-0,6-0,4 Dabei fällt auf, dass die meisten Werte um 0 liegen und die größeren Werte in der linken oberen Ecke erscheinen. Quantisierung Nun werden diese ungünstigen Fließkommazahlen quantisert. Dies ist der entsche i- dendste weil eingreifendste Schritt. Die Wahl der Quantisierungskoeffizienten beeinflusst immens die Qualität des komprimierten Bildes. Jeder DCT-Wert wird durch den entsprechenden Wert aus der Quantisierungstabelle dividiert und das Ergebnis wird auf ganze Zahlen gerundet. Der Decoder geht den entsprechend umgekehrten Weg. Die folgende Tabelle stellt ein Beispiel für Quantisierungskoeffizienten dar. Die Werte kann man zwar beliebig wählen jedoch hat sich diese als recht erfolgreich herausgestellt (entnommen den White Papers), was die Resultate angeht. Man nimmt im einfachsten Fall an, dass diese Werte 50% Qualität entsprechen und skaliert die Werte linear. So erreicht man bei den meisten Bilddaten gute Ergebnisse. 16 11 10 16 24 40 51 61 12 12 14 19 26 58 60 55 14 13 16 24 40 57 69 56 14 17 22 29 51 87 80 62 18 22 37 56 68 109 103 77 24 35 55 64 81 104 113 92 49 64 78 87 103 121 120 101 72 92 95 98 112 100 103 99 Die optimale Bildqualität erreicht man, wenn alle Koeffizienten 1 sind. Allerdings ließe sich das Bild dann kaum komprimieren, da nur wenige Redundanzen vorhanden sind. Größere Werte ermöglichen gute Kompressionsraten, da ja mehr Werte auf 0 abgerundet werden. Allerdings wird dies erkauft durch eine drastische Qualitätseinbuße. Aus obigen Beispiel ergibt sich folgende quantisierte Matrix: 15 0-1 0 0 0 0 0-2 -1 0 0 0 0 0 0-1 -1 0 0 0 0 0 0 Nun haben wir den Ausgangspunkt zu eigentlichen Kompression erreicht. 5
Entropy Encoding (Zick-Zack) Um eine noch bessere Kompression zu erreichen es sind ja schon sehr viele Stellen Null bedient man sich der Tatsache das die einzigen von Null verschiedenen Werte in der linken oberen Ecke anzufinden sind. Der Encoder formt die Matrix in eine lineare Sequenz um und zwar nach folgendem Schema: (x, y) x-koordinate; y-koordinate (1;0); (0;1); (0;2); (1;1); (2;0); (3;0) usw. bis (7;7). Dabei ergibt sich in unserem Beispiel die Sequenz: 15, 0, -2, -1, -1, -1, 0, 0, -1 und 55x0 Dabei wird die DC-Komponente (15) gesondert gehandelt. Sie wird als Differenz zum vorhergehenden DC-Wert gespeichert. Nehmen wir an er wäre 13: dann würde also +2 codiert werden. Um Verschwendung zu vermeiden wird ein Huffmann codierter Wert das Symbol A und ein codierter Wert für DC, das Symbol B gespeichert. Das Symbol A für DC speichert die Größe des folgenden Symbols als Huffmanncode. Diesen Code nennt man VLC (variable length Code). Das Symbol B ist eine VLI (variable length integer). Dadurch werden immer nur so viele Bits benutzt, wie auch wirklich nötig sind. Die VLC bestimmt seine Länge selbst, weil der Decoder immer solange Bits einließt, bis er am Endknoten des Baumes angekommen ist. Des weiteren bestimmt diese VLC die Länge der folgenden VLI. Die VLI s selbst werden auch noch einmal kompakter dargestellt. Um zum Beispiel den Wert -80 zu codieren, sind im Normalfall 8Bit (signed char) nötig. Für den Wert 40 7Bit. Da man jedoch die 40 auch in 8, 9 oder mehr Bit speichern kann, stellt dies eine Verschwendung dar. Man entfernt also den Wertebereich von 7 Bits (-63 bis 64) aus dem Bereich von 8 Bits und erreicht damit Platz für neue Zahlen. Beginnt man mit dieser Methode bei 0 ergibt sich folgendes Bild: Länge Bereich 0 0 1-1 und 1 2-3..-2 und 2..3 3-7..-4 und 4..7...... 10-1023..-512 und 512..1023 11-2047..-1024 und 1024..2047 Praktischerweise werden die Zahlen in Zweierkomplementschreibweise dargestellt. Die 5 also als (101) entsprechend die -5 als (010) Die AC Koeffizienten werden auch als VLI s gespeichert. Allerdings kommt hier hinzu, dass außer der Größe des folgenden VLI auch die Anzahl der Nullen vor dem zu codierenden Wert mitgespeichert wird. Das Symbol A hat somit die Form (Nullenanzahl, Größe), wobei der Wert Nullenanzahl stets vier-bittig ist. Damit werden die Nullen nicht extra als Symbol B gespeichert, sondern immer im Symbol A mitgeführt. Somit können pro Symbol A 0 bis 15 Nullen gespeichert werden. Da der Wert 0 als Größe unmöglich ist bedeutet (15, 0) 16 Nullen gefolgt von einem weiteren Symbol A. Maximal vier solcher Symbole sind zulässig, bevor ein Symbol B folgen muss. Spätestens nach dem 63. Zeichen folgt ein spezielles Symbol A (0, 0), welches als Escape-Zeichen fungiert. Es kann jedoch auch schon früher auftreten, wenn im Block nur noch Nullen folgen. Das gesamte Symbol A wird als Huffmann-VLC gespeichert. Huffmann-Codierung Unser Beispiel sieht jetzt folgendermaßen aus: DC hat das Delta 2 und die Größe 2 A=2, B=2 6
Der erste von 0 verschiedene AC-Wert hat eine Größe von 2 Bit und den Wert 2. Da vor ihm eine 0 steht ergibt sich: A=(1,2), B=-2 Nun folgen drei AC Werte mit 1: A=(0,1), B=-1 A=(0,1), B=-1 A=(0,1), B=-1 Jetzt folgen zwei Nullen vor dem letzten Wert 1: A=(2,1), B=-1 Der Block ist abgeschlossen: A(0,0) Nun werden die VLC s und VLI s Huffmanncodiert. VLC s: (2) DC = 011, (0,0) = 1010, (0,1) = 00, (1,2) = 11011, (2,1) = 11100 und VLI s: (2) = 10, (-2) = 01, (-1) = 0 Das ergibt den Datenstrom: 0111011011010000000001110001010 Aus den ehemals 64Bytes Originalgröße sind 31Bit komprimierter Datenstrom geworden. Eine Kompressionsrate von 16,5:1. Auch wenn es sich hier nur um ein einziges Cluster handelt, kann man auf das ganze Bild in etwa den gleichen Faktor erwarten. Des weiteren werden Farbbilder zunächst YUV-transformiert, wobei die U und V Komponente schon auf die Hälfte der Auflösung heruntergerechnet werden. Auch wenn Jpeg ein sehr ausgereiftes Verfahren ist, gibt es jedoch entscheidende Nachteile. Gerade bei sehr stark komprimierten Bildern entstehen blockartige Strukturen, die auf den fehlenden Abgleich zwischen den Blöcken zurückzuführen sind. Außerdem kann man die Kompressionsrate nur über den abstrakten Parameter der Quantisierungstabelle einstellen und nicht zum Beispiel über die gewünschte Dateigröße. 7
Quellenangabe Martin J. Fiedler Projektarbeit Kapitel 3 bis 3.4.1 http://x500.tu-chemnitz.de/~mfie/compproj/3picture.htm The Implementation of the 2D-DCT http://rnvs.informatik.tu-chemnitz.de/~jan/mpeg/html/idct.html#picture 8