2 Nachricht, Information und Codierung

2 Nachricht, Information und Codierung 2 Nachricht, Information und Codierung

www2.fh.rosenheim.de
von www2.fh.rosenheim.de Mehr von diesem Publisher
01.11.2013 Aufrufe

88 3 Codierung ⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯ 3.4 Datenkompression . . . 3.4.5 Der LZW-Algorithmus Kompression von korrelierten Zeichengruppen Für die verlustfreie Kompression beliebiger Daten hat sich als sehr effizientes Verfahren der nach seinen Erfindern Lempel, Ziv und Welch benannte LZW-Algorithmus durchgesetzt [Ziv77]. Es handelt sich dabei um ein statistisches Verfahren, das aber anders als das Huffman-Verfahren oder die arithmetische Codierung nicht nur Einzelzeichen codiert, sondern Zeichengruppen unterschiedlicher Länge. Dadurch lassen sich nicht nur die Häufigkeiten von Einzelzeichen bei der Codierung berücksichtigen, sondern auch durch Korrelationen aufeinander folgender Zeichen bedingte Redundanzen. Der LZW-Algorithmus minimiert also auch Redundanzen, die dadurch entstehen, dass sich identische Zeichenfolgen (Strings) in den Eingabedaten mehrmals wiederholen. Dies führt zu einer umso besseren Kompressionswirkung, je häufiger solche Wiederholungen auftreten und je länger die sich wiederholenden Zeichengruppen sind. Das Ergebnis der Kompression besteht dann aus einer weit gehend unkorrelierten Zeichenfolge, die verlustfrei nicht mehr weiter komprimierbar ist. Das Prinzip des LZW-Algorithmus Der LZW-Algorithmus arbeitet mit einer Code-Tabelle in der jeder Eintrag aus einem String mit Zeichen des Quell-Alphabets und dem zugehörigen komprimierten Code besteht. Die Code-Tabelle wird am Anfang mit allen Einzelzeichen des Quell-Alphabets vorbesetzt und während der Kompression nach und nach erweitert und an die Eingabe angepasst. Wegen dieser automatischen Anpassung benötigt der LZW im Voraus keinerlei Informationen über die Statistik des Eingabetextes; er kann daher als Ein-Schritt-Verfahren realisiert werden. Auch muss die Code-Tabelle nicht zusammen mit den codierten Daten gespeichert bzw. übertragen werden, da sie im Decoder aus den codierten Daten in identischer Weise wieder neu erzeugt werden kann. Zu Beginn der Codierung muss jedes Zeichen des Eingabetextes einzeln codiert werden, weil ja die Code-Tabelle nur mit den Einzelzeichen des Quell-Alphabets vorbesetzt ist und noch keine längeren Strings enthält. Zu Beginn ist also noch kein Kompressionseffekt zu erwarten. Im Laufe der Verarbeitung sammeln sich aber in der Tabelle immer mehr und immer längere mehrfach aufgetretene Strings an, von denen angenommen werden kann, dass sie im noch zu komprimierenden Text ebenfalls noch häufig auftreten werden. Dadurch steigt die Effizienz der Kompression immer weiter an, bis die Code-Tabelle vollständig gefüllt ist. Danach geht die Anpassungseigenschaft des Algorithmus verloren. Die Kompressionsrate bleibt dann zunächst gleich, sie kann sich aber auch wieder verschlechtern, wenn sich die Charakteristika der Eingabedaten ändern. Dem kann man durch Erstellen einer neuen Code- Tabelle entgegenwirken. Der Kompressions-Algorithmus Die Codierung einer Zeichenkette Z läuft nun nach folgendem Schema ab: zunächst wird das nächste Eingabezeichen c des Eingabestrings Z eingelesen und an den als Präfix bezeichneten Anfangs-Teilstring P des Strings Z angehängt, es wird also der String Pc gebildet. Zu Beginn wird der Präfix P mit dem leeren String vorbesetzt. Ist Pc in der Code-Tabelle bereits

88 3 <strong>Codierung</strong><br />

⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯<br />

3.4 Datenkompression<br />

.<br />

.<br />

.<br />

3.4.5 Der LZW-Algorithmus<br />

Kompression von korrelierten Zeichengruppen<br />

Für die verlustfreie Kompression beliebiger Daten hat sich als sehr effizientes Verfahren der<br />

nach seinen Erfindern Lempel, Ziv <strong>und</strong> Welch benannte LZW-Algorithmus durchgesetzt<br />

[Ziv77]. Es handelt sich dabei um ein statistisches Verfahren, das aber anders als das Huffman-Verfahren<br />

oder die arithmetische <strong>Codierung</strong> nicht nur Einzelzeichen codiert, sondern<br />

Zeichengruppen unterschiedlicher Länge. Dadurch lassen sich nicht nur die Häufigkeiten von<br />

Einzelzeichen bei der <strong>Codierung</strong> berücksichtigen, sondern auch durch Korrelationen aufeinander<br />

folgender Zeichen bedingte Red<strong>und</strong>anzen. Der LZW-Algorithmus minimiert also auch<br />

Red<strong>und</strong>anzen, die dadurch entstehen, dass sich identische Zeichenfolgen (Strings) in den<br />

Eingabedaten mehrmals wiederholen. Dies führt zu einer umso besseren Kompressionswirkung,<br />

je häufiger solche Wiederholungen auftreten <strong>und</strong> je länger die sich wiederholenden<br />

Zeichengruppen sind. Das Ergebnis der Kompression besteht dann aus einer weit gehend<br />

unkorrelierten Zeichenfolge, die verlustfrei nicht mehr weiter komprimierbar ist.<br />

Das Prinzip des LZW-Algorithmus<br />

Der LZW-Algorithmus arbeitet mit einer Code-Tabelle in der jeder Eintrag aus einem String<br />

mit Zeichen des Quell-Alphabets <strong>und</strong> dem zugehörigen komprimierten Code besteht. Die<br />

Code-Tabelle wird am Anfang mit allen Einzelzeichen des Quell-Alphabets vorbesetzt <strong>und</strong><br />

während der Kompression nach <strong>und</strong> nach erweitert <strong>und</strong> an die Eingabe angepasst. Wegen<br />

dieser automatischen Anpassung benötigt der LZW im Voraus keinerlei <strong>Information</strong>en über<br />

die Statistik des Eingabetextes; er kann daher als Ein-Schritt-Verfahren realisiert werden.<br />

Auch muss die Code-Tabelle nicht zusammen mit den codierten Daten gespeichert bzw.<br />

übertragen werden, da sie im Decoder aus den codierten Daten in identischer Weise wieder<br />

neu erzeugt werden kann.<br />

Zu Beginn der <strong>Codierung</strong> muss jedes Zeichen des Eingabetextes einzeln codiert werden,<br />

weil ja die Code-Tabelle nur mit den Einzelzeichen des Quell-Alphabets vorbesetzt ist <strong>und</strong><br />

noch keine längeren Strings enthält. Zu Beginn ist also noch kein Kompressionseffekt zu<br />

erwarten. Im Laufe der Verarbeitung sammeln sich aber in der Tabelle immer mehr <strong>und</strong> immer<br />

längere mehrfach aufgetretene Strings an, von denen angenommen werden kann, dass<br />

sie im noch zu komprimierenden Text ebenfalls noch häufig auftreten werden. Dadurch steigt<br />

die Effizienz der Kompression immer weiter an, bis die Code-Tabelle vollständig gefüllt ist.<br />

Danach geht die Anpassungseigenschaft des Algorithmus verloren. Die Kompressionsrate<br />

bleibt dann zunächst gleich, sie kann sich aber auch wieder verschlechtern, wenn sich die<br />

Charakteristika der Eingabedaten ändern. Dem kann man durch Erstellen einer neuen Code-<br />

Tabelle entgegenwirken.<br />

Der Kompressions-Algorithmus<br />

Die <strong>Codierung</strong> einer Zeichenkette Z läuft nun nach folgendem Schema ab: zunächst wird das<br />

nächste Eingabezeichen c des Eingabestrings Z eingelesen <strong>und</strong> an den als Präfix bezeichneten<br />

Anfangs-Teilstring P des Strings Z angehängt, es wird also der String Pc gebildet. Zu<br />

Beginn wird der Präfix P mit dem leeren String vorbesetzt. Ist Pc in der Code-Tabelle bereits


3 <strong>Codierung</strong> 89<br />

⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯<br />

vorhanden, so wird P=Pc gesetzt <strong>und</strong> das nächste Zeichen eingelesen. Andernfalls wird P<br />

ausgegeben, Pc in die Code-Tabelle eingetragen <strong>und</strong> der neue Präfix P=c gesetzt. Kommt<br />

der soeben eingetragene Teilstring Pc später im Text nochmals vor, so kann er durch ein<br />

einziges Code-Wort ersetzt werden. Darauf beruht letztlich die komprimierende Wirkung des<br />

LZW-Verfahrens.<br />

Der Kompressions-Algorithmus lautet damit in Pseudo-Code-Formulierung:<br />

LZW-Algorithmus zur Kompression eines Strings Z<br />

Initialisiere die Code-Tabelle mit den Einzelzeichen<br />

Weise dem Präfix P den Leerstring zu<br />

Wiederhole, solange Eingabezeichen vorhanden sind:<br />

Lies nächstes Eingabezeichen c aus dem Eingabestring Z<br />

Wenn Pc in der Code-Tabelle gef<strong>und</strong>en wird:<br />

setze P=Pc<br />

Sonst:<br />

Trage Pc in die nächste freie Position der Code-Tabelle ein<br />

Gib den Code für P aus<br />

setze P=c<br />

Ende der Schleife<br />

Gib den Code für das letzte Präfix P aus<br />

Beispiel: LZW-Kompression der Zeichengruppe ABABCBABAB.<br />

Als Beispiel wird die Zeichenkette Z=ABABCBABAB betrachtet. Die Code-Tabelle wird mit<br />

den Zeichen A, B, C des Quell-Alphabets <strong>und</strong> den entsprechenden Codes des Ausgabealphabets<br />

vorbesetzt. Wählt man für das Beispiel als maximale Länge der Code-Tabelle sieben<br />

Einträge, so benötigt man in der Ausgabe 3 Bit pro Code-Wort. Die Code-Tabelle wird<br />

also folgendermaßen vorbesetzt:<br />

Tabelle 3.4.6: Vorbesetzung der Code-Tabelle für die Kompression des Strings Z=ABABCBABAB mit<br />

dem LZW-Algorithmus.<br />

Präfix Ausgabe-Code<br />

A 0 = 000<br />

B 1 = 001<br />

C 2 = 010<br />

- 3 = 011<br />

- 4 = 100<br />

- 5 = 101<br />

- 6 = 110<br />

- 7 = 111<br />

Der <strong>Codierung</strong>svorgang läuft damit folgendermaßen ab:


90 3 <strong>Codierung</strong><br />

⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯<br />

Tabelle 3.4.7: <strong>Codierung</strong> des Strings Z=ABABCBABAB mit dem LZW-Algorithmus. Das aktuell verarbeitete<br />

Zeichen ist unterstrichen dargestellt. Die codierte <strong>Nachricht</strong> lautet 013247.<br />

Schritt String Z Präfix P Eintrag in die Code-Tabelle Ausgabe<br />

0 ABABCBABAB - Vorbesetzung -<br />

1 ABABCBABAB A - -<br />

2 ABABCBABAB B AB=3 0<br />

3 ABABCBABAB A BA=4 1<br />

4 ABABCBABAB AB - -<br />

5 ABABCBABAB C ABC=5 3<br />

6 ABABCBABAB B CB=6 2<br />

7 ABABCBABAB BA - -<br />

8 ABABCBABAB B BAB=7 4<br />

9 ABABCBABAB BA - -<br />

10 ABABCBABAB BAB - -<br />

11 ABABCBABAB - - 7<br />

Nach Beendigung der <strong>Codierung</strong> hat der Inhalt der Code-Tabelle die Form:<br />

Tabelle 3.4.8: Code-Tabelle nach Beendigung der Kompression des Strings Z=ABABCBABAB.<br />

Präfix Ausgabe-Code<br />

A 0 = 000<br />

B 1 = 001<br />

C 2 = 010<br />

AB 3 = 011<br />

BA 4 = 100<br />

ABC 5 = 101<br />

CB 6 = 110<br />

BAB 7 = 111<br />

Methoden zur Optimierung des Verfahrens<br />

Weil jeder neue Eintrag in der Code-Tabelle nur eine Verlängerung eines bereits in der Code-Tabelle<br />

enthaltenen Strings darstellt, ist es nicht nötig, zu jedem Code den vollständigen<br />

String zu speichern. Es empfiehlt sich statt dessen, nur das letzte Zeichen des Strings zu<br />

speichern <strong>und</strong> einen Verweis auf den String, aus dem er hervorgegangen ist. Der Code ABC<br />

aus dem obigen Beispiel wird dann als 4C abgespeichert. Dadurch erfordert jeder Tabelleneintrag<br />

bei 8 Byte Eingabezeichen <strong>und</strong> 12 bis 16 Bit Code nur drei Byte: ein Byte für das<br />

letzte Zeichen <strong>und</strong> zwei für den Verweis. Meist werden 12 Bit Codes verwendet, entsprechend<br />

4096 Tabelleneinträgen oder 13 Bit Codes, entsprechend 8192 Einträgen. Bei einer<br />

Verlängerung der Code-Tabelle können zwar mehr <strong>und</strong> längere Teilstrings abgespeichert<br />

werden; dies führt jedoch nicht unbedingt zu einer Verbesserung der Kompressionsrate, weil<br />

eine größere Tabelle auch zu längeren Code-Wörtern führt. Insbesondere zu Beginn der<br />

Kompression, wenn noch Einzelzeichen codiert werden, führt dies zunächst nicht zu einer<br />

Kompression, sondern zu einer Verlängerung des Textes.<br />

Relativ einfach zu realisieren ist, dass nicht immer die volle Länge der Codes übertragen<br />

werden muss. Solange in der Tabelle nicht mehr als 512 Einträge sind, reichen 9 Bit für die<br />

Darstellung der Code-Wörter aus, zwischen 513 <strong>und</strong> 1024 Einträgen genügen 10 Bit usw.<br />

Sowohl der Kompressor als auch der Dekompressor (siehe unten) können anhand ihrer Code-Tabelle<br />

feststellen, mit welcher Wortlänge gerade gearbeitet wird <strong>und</strong> die Wortlänge erhöhen,<br />

sobald ein längerer Code in die Tabelle eingetragen wird. Oft wird auch die Erhöhung<br />

der Wortlänge durch ein eigenes, dafür reserviertes Code-Wort signalisiert, weil dann nicht<br />

schon beim Eintragen eines längeren Code-Wortes in die Tabelle umgeschaltet werden<br />

muss, sondern erst dann, wenn tatsächlich das erste längere Code-Wort verwendet wird.<br />

Wenn die Code-Tabelle vollständig gefüllt ist, kann man entweder mit dieser Tabelle weiterarbeiten<br />

oder aber die Tabelle löschen <strong>und</strong> mit einer neu initialisierten Tabelle fortfahren. Bei


3 <strong>Codierung</strong> 91<br />

⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯<br />

der zweiten Strategie sinkt zwar die Kompressionsrate zunächst, aber die Code-Tabelle<br />

kann dafür wieder neu an die Eigenschaften der Eingabedaten angepasst werden. Dies erweist<br />

sich dann als sinnvoll, wenn damit zu rechnen ist, dass sich die Charakteristik der Daten<br />

ändern wird. Dies ist insbesondere bei der Kompression von Bilddaten der Fall. Eine<br />

Neuinitialisierung der Code-Tabelle muss in den komprimierten Daten allerdings durch Einfügen<br />

eines dafür reservierten Code-Worts kenntlich gemacht werden.<br />

Bei der Komprimierung der Daten muss bei jedem Schritt nach dem String Pc gesucht werden,<br />

also dem aktuellen Präfix plus nächstes Eingabezeichen. Eine sequentielle Suche würde<br />

sehr viel Zeit benötigen, so dass sich die Verwendung einer Hash-Tabelle (siehe Kapitel<br />

11.3) empfiehlt. Dazu wird neben der Code-Tabelle noch eine Hash-Tabelle zur Speicherung<br />

von Verweisen auf die Code-Tabelle aufgebaut.<br />

Eine weitere Verbesserung, allerdings auf Kosten der Ausführungszeit, kann erzielt werden,<br />

wenn man das Verfahren nicht einschrittig auslegt, sondern eine statistische Analyse vorschaltet.<br />

Besonders häufig auftretende Strings können so vorab ermittelt <strong>und</strong> bereits bei der<br />

Initialisierung der Code-Tabelle berücksichtigt werden.<br />

Der Dekompressions-Algorithmus<br />

Die Dekompression ist zunächst etwas unanschaulicher, aber auch nicht schwieriger zu implementieren<br />

als die Kompression. Zunächst wird wie bei der Kompression eine Code-Tabelle<br />

angelegt, <strong>und</strong> mit den Eingabezeichen vorbesetzt. Der Dekompressor liest nun ein Zeichen<br />

nach dem anderen ein, sucht den zugehörigen String in der Code-Tabelle auf <strong>und</strong> gibt ihn<br />

aus. Zusätzlich wird an den im vorherigen Schritt decodierten String das erste Zeichen des<br />

aktuell decodierten Strings angehängt <strong>und</strong> das Ergebnis in die nächste freie Position der<br />

Code-Tabelle eingetragen. Auf diese Weise wird schrittweise dieselbe Code-Tabelle aufgebaut,<br />

mit der auch der Kompressor gearbeitet hat. Es gibt dabei jedoch eine Komplikation:<br />

Wenn bei der Kompression ein String in die Code-Tabelle eingetragen <strong>und</strong> im nächsten<br />

Schritt bereits wieder verwendet wurde, so kann er bei der Dekompression an dieser Stelle<br />

noch nicht in der Tabelle enthalten sein. In diesem Fall ist aber klar, dass der fehlende Code<br />

einfach durch Verlängerung des Präfix um das erste Zeichen des zuvor ausgegebenen<br />

Strings entsteht. Der in die Code-Tabelle einzutragende String ist in diesem Sonderfall mit<br />

dem auszugebenden String identisch. Der Algorithmus lautet damit als Pseudo-Code:<br />

LZW-Algorithmus zur Dekompression einer <strong>Nachricht</strong><br />

Initialisiere die Code-Tabelle mit den Einzelzeichen<br />

Weise dem Präfix P den Leerstring zu<br />

Wiederhole, solange Eingabezeichen vorhanden sind:<br />

Lies nächstes Eingabezeichen c<br />

Wenn c in der Code-Tabelle enthalten ist:<br />

Gib den zu c gehörenden String aus<br />

Setze k = erstes Zeichen dieses Strings<br />

Trage Pk in die Code-Tabelle ein, falls noch nicht vorhanden<br />

Setze P auf den zu dem Code c gehörigen String<br />

Sonst (Sonderfall):<br />

setze k = erstes Zeichen von P<br />

Gib Pk aus<br />

Trage Pk in die Code-Tabelle ein<br />

Setze P=Pk<br />

Ende der Schleife<br />

Gib letztes Präfix aus


92 3 <strong>Codierung</strong><br />

⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯<br />

Beispiel: Dekompression<br />

Als Beispiel wird nun das weiter oben gewonnene Kompressions-Ergebnis 013247 des<br />

Strings ABABCBABAB wieder dekomprimiert. Zunächst wird die leere Code-Tabelle mit den<br />

Zeichen A, B <strong>und</strong> C vorbesetzt. Der Dekompressor liest dann das erste Code-Zeichen (=0)<br />

ein, sucht das zugehörige Zeichen des Quell-Alphabetes in der Code-Tabelle (=A) <strong>und</strong> gibt<br />

dieses Zeichen aus. Anschließend wird das nächste Zeichen (=1) eingelesen, decodiert (=B)<br />

<strong>und</strong> ausgegeben. Zusätzlich wird jetzt der String AB, bestehend aus dem zuvor decodierten<br />

Zeichen A <strong>und</strong> dem soeben decodierten Zeichen B auf die Nächste freie Position, hier also<br />

3, der Code-Tabelle eingetragen. Das als Nächstes eingelesene Zeichen (=3) ergibt den<br />

Ausgabestring AB, der soeben erst in die Code-Tabelle eingetragen wurde. Zusätzlich wird<br />

der String BA, bestehend aus dem Zeichen B des vorhergehenden Schritts <strong>und</strong> dem ersten<br />

Zeichen des Strings AB, in die Code-Tabelle eingetragen. Die weiteren Schritte der Decodierung<br />

ergeben sich aus der nachstehenden Tabelle.<br />

Tabelle 3.4.9: Decodierung der komprimierten <strong>Nachricht</strong> 013247 mit dem LZW-Algorithmus. Das<br />

aktuell verarbeitete Zeichen ist jeweils unterstrichen dargestellt. Es wird wieder die ursprüngliche<br />

<strong>Nachricht</strong> ABABCBABAB aufgebaut.<br />

Schritt Code-String Eintrag in Code-Tabelle Ausgabe-String=Präfix<br />

0 013247 Vorbesetzung -<br />

1 013247 - A<br />

2 013247 AB B<br />

3 013247 BA AB<br />

4 013247 ABC C<br />

5 013247 CB BA<br />

6 013247 BAB BAB<br />

Man erkennt, dass der Dekompressor tatsächlich dieselben Strings in die Code-Tabelle einträgt<br />

wie der Kompressor, allerdings immer einen Schritt später. Der Dekompressor kann<br />

beispielsweise den String AB erst dann eintragen, wenn er auch den Code für B bereits verarbeitet<br />

hat, weil erst dann bekannt ist, dass bei der Komprimierung auf das Zeichen A ein B<br />

folgte. Dieses Nachhinken kann zu dem oben bereits erwähnten Sonderfall führen, dass ein<br />

benötigter Code in der Code-Tabelle noch nicht enthalten ist. In dem betrachteten Beispiel ist<br />

dies in Schritt 6 der Fall. Dort trifft der Dekompressor auf den Code 7, den er in der Code-<br />

Tabelle nicht findet, weil dafür noch kein String eingetragen worden ist. Wenn dieser Fall<br />

eintritt, ist aber bekannt, dass der fehlende String mit demselben Zeichen beginnen muss,<br />

wie der unmittelbar zuvor decodierte <strong>und</strong> ausgegebene String.


3 <strong>Codierung</strong> 93<br />

⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯<br />

3.4.6 Datenreduktion durch unitäre Transformationen (JPEG)<br />

Die Fourier-Transformation<br />

In vielen technischen Anwendungen werden Daten, insbesondere Messdaten <strong>und</strong> Bilder, mit<br />

Hilfe der Fourier-Transformation in eine Frequenzdarstellung transformiert. In diesem Kapitel<br />

wird gezeigt, dass auf diese Weise auch eine sehr effiziente Datenkompression erreicht werden<br />

kann. Die Fourier-Transformation wird durch Integrale vermittelt, die im Falle diskreter<br />

Daten durch Summen ersetzt werden können; man spricht dann von der diskreten Fourier-<br />

Transformation, für die es sehr effiziente Algorithmen gibt. Der bekannteste ist der DFFT-<br />

Algorithmus (von Diskrete Fast Fourier Transform). Damit kann man eine aus N Punkten bestehende<br />

Datenmenge f n in ihre Entsprechung F n im Frequenzraum transformieren:<br />

F<br />

u<br />

=<br />

1<br />

N<br />

N<br />

∑ − 1<br />

f<br />

n<br />

n=<br />

0<br />

e<br />

−2πinu/N<br />

Fourier-Transformation<br />

Die Formel für die Rücktransformation lautet:<br />

N−1<br />

2 /N<br />

f<br />

n<br />

= ∑ Fue<br />

πinu Fourier-Rücktransformation<br />

u=<br />

0<br />

Die Summen in diesen Gleichungen lassen sich durch Multiplikation einer die Exponentialterme<br />

enthaltenden Matrix mit einem Vektor darstellen, dessen Komponenten die zu transformierenden<br />

Daten sind. Die einzelnen Komponenten des transformierten Vektors ergeben<br />

sich also durch Berechnung des Skalarproduktes aus der entsprechenden Matrixzeile mit<br />

dem Datenvektor. Betrachtet man die Zeilen der Matrix als Basisvektoren, so wird durch das<br />

Skalarprodukt diejenige Komponente des Datenvektors transformiert, die in Richtung des<br />

entsprechenden Basisvektors zeigt.<br />

Unitäre <strong>und</strong> orthogonale Transformationen<br />

Dieses Prinzip soll nun verallgemeinert werden. Dazu wird bei der Fourier-Transformation<br />

die Exponentialfunktion e -i2πnu/N durch eine zunächst beliebige, als Kern der Transformation<br />

bezeichnete Matrix K der Dimension N mit den Komponenten K nu ersetzt <strong>und</strong> bei der Rücktransformation<br />

durch die zu K inverse Matrix K -1 :<br />

F<br />

f<br />

1<br />

=<br />

N<br />

N−1<br />

∑<br />

fK<br />

u n nu<br />

n=0<br />

N−1<br />

−1<br />

n<br />

= ∑ FuK nu<br />

u=0<br />

allgemeine unitäre Transformation<br />

unitäre Rück-Transformation<br />

Damit sich eine sinnvolle Transformation ergibt, müssen die Basisvektoren des Kerns, also<br />

die Zeilen der Matrix K, einen Vektorraum mit Dimension N aufspannen. Dies ist dann der<br />

Fall, wenn alle N Zeilenvektoren (Basisvektoren) linear unabhängig, also in einer geometrischen<br />

Betrachtungsweise nicht parallel zueinander sind. Besonders einfach wird die mathematische<br />

Beschreibung, wenn die Basisvektoren nicht nur linear unabhängig, sondern orthogonal<br />

sind, also - geometrisch interpretiert - aufeinander senkrecht stehen. Für komplexe<br />

Matrizen bedeutet dies, dass (bis auf den vorgezogenen Normierungsfaktor 1/N) die inverse<br />

Matrix K -1 mit der konjugiert komplexen <strong>und</strong> transponierten Matrix K *T übereinstimmt:<br />

K<br />

− 1 T<br />

= K<br />

*


94 3 <strong>Codierung</strong><br />

⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯<br />

Komplexe Matrizen mit dieser Eigenschaft werden als unitäre Matrizen bezeichnet, dementsprechend<br />

heißen auch die durch sie vermittelten Transformationen unitäre Transformationen.<br />

Insbesondere gehört auch die Fourier-Transformation zur Klasse dieser Transformationen.<br />

Im Falle reeller Matrizen stimmt die inverse Matrix mit der transponierten Matrix überein,<br />

man spricht dann von orthogonalen Matrizen <strong>und</strong> orthogonalen Transformationen. Ist die<br />

orthogonale Transformationsmatrix außerdem noch symmetrisch, so ist sie mit ihrer Inversen<br />

bzw. Transponierten identisch. Da das Rechnen mit komplexen Zahlen doch einen gewissen<br />

Aufwand bedeutet, werden in der Praxis orthogonale Transformationen mit reellen, möglichst<br />

auch noch symmetrischen Matrizen bevorzugt verwendet. Das bekannteste Beispiel für eine<br />

orthogonale Transformation ist wohl die Drehung von Koordinatensystemen, was bei der<br />

Robotersteuerung oder in CAD-Anwendungen zum täglichen Brot gehört.<br />

Im allgemeinen Fall ist die Berechnung der inversen Matrix recht aufwendig, die Bestimmung<br />

der transponierten Matrix dagegen trivial: man erhält die transponierte Matrix einfach durch<br />

Spiegelung an der Hauptdiagonalen. Damit ist auch sofort klar, dass orthogonale, symmetrische<br />

Matrizen zu sich selbst invers sind, so dass für die Hintransformation <strong>und</strong> die Rücktransformation<br />

identische Matrizen verwendet werden können.<br />

Hat man einen Datensatz durch eine unitäre bzw. orthogonale Transformation in eine andere<br />

Darstellung überführt, so ist noch stets die gleiche Datenmenge zu speichern, eine Kompression<br />

wurde dadurch also nicht bewirkt. Eine sehr effiziente Möglichkeit zur Datenreduktion<br />

liegt aber darin, dass bei geeigneter Wahl der Transformation manche Komponenten nur<br />

wenig <strong>Information</strong> tragen <strong>und</strong> daher weggelassen werden können (siehe Abbildung 3.4.4).<br />

Der Gr<strong>und</strong> dafür ist, dass man orthogonale Transformationen angeben kann, bei denen die<br />

Komponenten des Ergebnisses weitgehend unkorreliert sind, während die zu transformierenden<br />

Daten in der Regel sehr stark miteinander korreliert sind, da sie sich für gewöhnlich<br />

stetig ändern. Anders ausgedrückt: kennt man einige aufeinanderfolgende Werte der zu<br />

transformierenden Ausgangsdaten, so lässt sich der Wert des nächsten Wertes mit hoher<br />

Wahrscheinlichkeit voraussagen; für das Ergebnis einer geeigneten orthogonalen Transformation<br />

gilt das aber nicht mehr.<br />

f<br />

f 2<br />

f 1<br />

X<br />

f’<br />

f 1<br />

f 2<br />

X’<br />

Abbildung 3.4.4:<br />

Durch eine geeignete Koordinatentransformation<br />

wird erreicht, dass die X’-<br />

Komponenten für die beiden Daten f 1 <strong>und</strong> f 2<br />

zu 0 werden <strong>und</strong> daher nicht gespeichert<br />

werden müssen. Dies entspricht einer Datenkompression.<br />

Ordnet man den Zeilen des Kerns als Basisfunktionen Schwingungen mit ansteigender Frequenz<br />

zu, so wird ein Datenvektor durch Überlagerungen dieser Basisfunktionen ausgedrückt.<br />

Hohe Frequenzanteile in Daten entstehen durch scharfe Kanten <strong>und</strong> durch Rauschen.<br />

Werden nun die den hohen Frequenzanteilen entsprechenden Komponenten vernachlässigt,<br />

so führt dies zu einer Rauschunterdrückung, aber – da es sich hierbei im Gr<strong>und</strong>e<br />

um einen Tiefpass-Filter handelt – auch zu einer Kantenverschmierung.


3 <strong>Codierung</strong> 95<br />

⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯<br />

Die Hadamard-Transformation<br />

Die Effizienz des Verfahrens hängt in erster Linie von den gewählten Basisfunktionen ab. Die<br />

einfachste Möglichkeit ergibt sich, wenn man als Basisfunktionen Rechteckschwingungen<br />

wählt, die in diesem Zusammenhang auch als Walsh-Funktionen bezeichnet werden. Die<br />

zugehörige Transformation ist als Hadamard-Transformation bekannt <strong>und</strong> besonders einfach<br />

<strong>und</strong> extrem schnell ausführbar, weil die Transformationsmatrix nur die Werte 1 <strong>und</strong> -1 enthält,<br />

so dass man bei der Transformation völlig ohne Multiplikationen auskommt. Als günstiger<br />

hat sich allerdings die Wahl von Sinus- oder Kosinusfunktionen als Basis erwiesen, da<br />

dann die Resultate in noch höherem Maße unkorreliert sind als bei der Hadamard-<br />

Transformation, so dass höhere Kompressionsraten erreichbar sind.<br />

Die Kosinus-Transformation<br />

Bei der Fourier-Transformation besteht der Kern aus einer komplexen Exponentialfunktion<br />

exp(i2πnu/N), die sich in einen reellen Kosinus-Anteil <strong>und</strong> einen imaginären Sinus-Anteil zerlegen<br />

lässt:<br />

e i2πnu/N = cos(2πnu/N) + i . sin(2πnu/N)<br />

Die Kosinus- oder Sinus-Funktionen alleine bilden in diesem Fall jedoch keine Basis, da die<br />

Kosinus-Funktionen gerade Funktionen <strong>und</strong> die Sinus-Funktionen ungerade Funktionen sind.<br />

Mit den Kosinus-Funktionen alleine kann man also nur gerade Funktionen darstellen, das<br />

Ergebnis ist dann rein reell. Mit den Sinus-Funktionen alleine sind nur ungerade Funktionen<br />

darstellbar, <strong>und</strong> zwar mit rein imaginärem Ergebnis. Für Funktionen bzw. Daten ohne diese<br />

besonderen Symmetrien wird also die komplexe Kombination aus Kosinus- <strong>und</strong> Sinus-<br />

Termen benötigt.<br />

Weil ein reelles Ergebnis in den meisten Anwendungsfällen bequemer zu handhaben ist,<br />

greift man zu einem Kunstgriff: Man symmetrisiert die zu transformierenden Daten durch<br />

Spiegeln an der vertikalen Koordinatenachse. Nun wird eine Fourier-Transformation über<br />

diesen um den Faktor zwei vergrößerten Datenvektor durchgeführt, wobei sich die Summation<br />

nun über 2N Terme erstreckt. Das Ergebnis ist jetzt aber rein reell <strong>und</strong> enthält nur Kosinus-Funktionen.<br />

Wegen der künstlich erzeugten geraden Symmetrie lassen sich viele Summanden<br />

zusammenfassen, so dass sich schließlich wieder nur genau so viele Terme ergeben,<br />

wie man bei Summation über die ursprünglichen Daten erhalten hätte, wobei sich aber<br />

die Wellenlängen der Kosinus-Funktionen verglichen mit der Fourier-Transformation verdoppelt<br />

haben. Das Ergebnis ist die rein reelle Kosinus-Transformation [Str02], die in der<br />

Praxis größte Bedeutung erlangt hat. Die Transformations-Formeln lauten:<br />

N−1<br />

u<br />

=<br />

u n [ + ]<br />

F c 2/N∑ fcos(2n 1) π u/2N)<br />

Kosinus-Transformation<br />

n=<br />

0<br />

N−1<br />

∑ [ π ]<br />

f = 2/ N c F cos (2n+<br />

1) u/2N)<br />

n u u<br />

u=<br />

0<br />

mit: u,n = 0,1,...N-1, c u = 1/√2 für u=0, c u = 1 für u>0.<br />

Kosinus-Rücktransformation<br />

Der Transformationskern enthält nun nicht mehr nur die Werte 1 <strong>und</strong> -1 wie bei der Hadamard-Transformation.<br />

Die Berechnung ist daher wegen der jetzt nötigen Multiplikationen entsprechend<br />

aufwendiger. Der Aufwand lohnt jedoch, da wie schon erwähnt, die Ergebnisse<br />

der Kosinus-Transformation noch weniger korreliert sind als bei der Hadamard-<br />

Transformation <strong>und</strong> somit eine noch effizientere Datenreduktion ermöglichen. Wegen der<br />

Verfügbarkeit von Signalprozessoren, die in der Lage sind, die nötigen Berechnungen sehr<br />

schnell durchzuführen, hat sich die Kosinus-Transformation als Standard durchgesetzt. Häufig<br />

verwendet man Kerne mit N=8:


96 3 <strong>Codierung</strong><br />

⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯<br />

C<br />

un<br />

= 0.5 ⋅ c cos[(2n + 1) πu /16]<br />

=<br />

u<br />

⎛1.0000 1.0000 1.0000 1.0000 1.0000 1.0000 1.0000 1.0000 ⎞<br />

1.3870 1.1759 0.7857 0.2759 -0.2759 -0.7857 -1.1759 -1.3870<br />

1.3066 0.5412 -0.5412 -1.3066 -1.3066 -0.5412 0.5412 1.3066<br />

1.1759 -0.2759 -1.3870 -0.7857 0.7857 1.3870 0.2759 -1.1759<br />

= 1.0000 -1.0000 -1.0000 1.0000 1.0000 -1.0000 -1.0000 1.0000<br />

0.7857 -1.3870 0.2759 1.1759 -1.1759 -0.2759 1.3870 -0.7857<br />

0.5412 -1.3066 1.3066 -0.5412 -0.5412 1.3066 -1.3066 0.5412<br />

⎝0.2759 -0.7857 1.1759 -1.3870 1.3870 -1.1759 0.7857 -0.2759⎠<br />

Die Transformation entspricht dann einer Multiplikation der Matrix C mit dem Vektor der Bilddaten<br />

(Zeile bzw. Spalte) f:<br />

u<br />

N<br />

=∑ −1<br />

F f C<br />

Fourier-Transformation<br />

n<br />

n=0<br />

N<br />

∑ − 1<br />

c<br />

u<br />

u=<br />

0<br />

nu<br />

f = F C Fourier-Rücktransformation<br />

n<br />

u<br />

−1<br />

nu<br />

Bei der Ausführung der Transformation, geht man am besten durch Erweiterung der Koeffizienten<br />

mit einer Potenz von 2, beispielsweise 4096, zu einer Integer-Darstellung über, so<br />

dass für alle Berechnungen Integer-Arithmetik genügt.<br />

JPEG-Kompression durch Quantisierung der Koeffizienten<br />

Die Kosinustransformation liefert als Ausgabe quadratische Matrizen mit einer zuvor festgelegten<br />

Komponentenzahl, üblicherweise 8×8. Es wird nun angestrebt, diese Einträge möglichst<br />

Platz sparend abzuspeichern, wozu ein Teil der <strong>Information</strong> so zu entfernen ist, dass<br />

es in den rekonstruierten Daten nur zu geringen, nicht relevanten Änderungen kommt. Bei<br />

der Entscheidung, welche Matrixkomponenten übertragen werden <strong>und</strong> mit wie vielen Bits sie<br />

dargestellt werden sollen, gibt es prinzipiell zwei verschiedene Möglichkeiten:<br />

Ein Ansatz besteht darin, die Entscheidung von der Position der Komponenten in der Matrix<br />

abhängig zu machen. Man geht dabei von der Überlegung aus, dass die niederfrequenten<br />

Anteile mehr zur <strong>Information</strong> beitragen als die zu höheren Frequenzen gehörenden Komponenten.<br />

Die Ergebnismatrix wird dementsprechend in verschiedene Zonen aufgeteilt, für die<br />

in einer Bit-Zuordnungstabelle oder Quantisierungstabelle festgelegt wird, wie viele Bits für<br />

die <strong>Codierung</strong> der Matrixkomponenten in den jeweiligen Zonen zu verwenden sind. Dabei<br />

werden für die niederfrequenten Matrixkomponenten mehr Bits reserviert als für die höherfrequenten<br />

<strong>und</strong> die höchsten Frequenzen werden oft ganz unterdrückt, was durch den Eintrag<br />

Null gekennzeichnet wird. Die folgende Tabelle zeigt eine mögliche Bit-Zuordnung für<br />

eine 8×8 Matrix, entsprechend einer Datenreduktion um etwa den Faktor 3.<br />

Tabelle 3.4.10: Eine datenkomprimierende Bitzuordnungstabelle (Quantisierungstabelle) für die 8×8<br />

Kosinus-Transformation. Der Kompressionsfaktor beträgt für dieses Beispiel ca. 3.<br />

8 8 7 7 6 5 4 4<br />

8 7 6 5 4 3 2 2<br />

7 6 5 3 2 2 1 1<br />

7 5 3 2 1 1 0 0<br />

6 4 2 1 1 0 0 0<br />

5 3 2 1 0 0 0 0<br />

4 2 1 0 0 0 0 0<br />

4 2 1 0 0 0 0 0


3 <strong>Codierung</strong> 97<br />

⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯<br />

Der zweite Ansatz zur Datenkompression besteht darin, die Quantisierung nicht nach der<br />

Lage der Matrixelemente zu entscheiden, sondern nach deren Größe. Man geht hier von der<br />

Annahme aus, dass Matrixeinträge mit großen Beträgen auch viel <strong>Information</strong> tragen. Dies<br />

trägt der Tatsache Rechnung, dass scharfe Kanten in Messdaten oder Bildern im Verlauf der<br />

Daten auch zu signifikanten hochfrequenten Komponenten führen, deren Unterdrückung zu<br />

einer Kantenverschmierung führen würde. Alle Matrixelemente werden daher mit einem voreinstellbaren<br />

Schwellwert verglichen <strong>und</strong> nur übertragen, wenn sie größer sind als dieser<br />

Schwellwert. Allerdings muss dann auch die Position der Matrixelemente mit codiert werden.<br />

Fehlende Einträge werden bei der Rücktransformation wie beim ersten Verfahren durch Null<br />

ergänzt.<br />

Beide Methoden können zu Problemen führen. Das erste Verfahren berücksichtigt nicht,<br />

dass auch hochfrequente Matrixelemente wichtige <strong>Information</strong> tragen können. Das zweite<br />

Verfahren vermeidet zwar diesen Fehler, codiert aber statt dessen niederfrequente Anteile<br />

nur dann, wenn sie über dem Schwellwert liegen. Erinnert man sich daran, dass die erste<br />

Matrixkomponente den Mittelwert der codierten Daten repräsentiert, so wird deutlich, dass<br />

diese Komponente auch dann nicht ohne Qualitätsverlust weggelassen werden darf, wenn<br />

sie klein ist. Eine optimale Lösung muss demnach beide Methoden kombinieren <strong>und</strong> die Anzahl<br />

der Bits für die <strong>Codierung</strong> der einzelnen Matrix-Komponenten in Abhängigkeit von deren<br />

Position <strong>und</strong> Größe entscheiden.<br />

Die Kosinus-Transformation mit 8×8-Matritzen ist wesentlicher Bestandteil des genormten<br />

JPEG-Standards für die datenreduzierende <strong>Codierung</strong> von Bilddaten, bei der nach den oben<br />

beschriebenen Strategien kleine <strong>und</strong>/oder hochfrequente Komponenten auf 0 gesetzt werden.<br />

Dadurch ergeben sich häufig längere Sequenzen von Nullen, die durch eine Lauflängen-<strong>Codierung</strong><br />

komprimiert werden. Zusätzlich werden die Koeffizienten aufeinander folgender<br />

8×8-Bereiche mittels Differenz-<strong>Codierung</strong> weiter komprimiert. Im letzten Schritt steht<br />

dann eine Huffman-<strong>Codierung</strong> oder eine arithmetische <strong>Codierung</strong>, mit der die verbleibende<br />

Einzelzeichen-Red<strong>und</strong>anz eliminiert wird. Für Bilder ergeben sich dann bei Kompressionsraten<br />

um ca. den Faktor 10 gute visuelle Eindrücke, obwohl der <strong>Information</strong>sgehalt wesentlich<br />

reduziert wurde. Besonders für Internet-Anwendungen hat dieses Verfahren der Bildkompression<br />

weite Verbreitung gef<strong>und</strong>en.<br />

Weitere Kompressionsverfahren<br />

Von großer praktischer Bedeutung ist die Kompression bewegter Bilder nach dem MPEG-<br />

Standard (siehe [Wat01] <strong>und</strong> [Sym98]) Die Kompression von Einzelbildern erfolgt dabei wie<br />

beim JPEG-Verfahren durch Kosinustransformation [Str02]. Es werden jedoch nicht alle Bilder,<br />

sondern nur Stützbilder (beispielsweise jedes vierte) vollständig komprimiert, Zwischenbilder<br />

aber nur aus den Stützbildern interpoliert. Zusätzlich wird durch die Übernahme örtlich<br />

verschobener, aber sonst unveränderter Bildbereiche von einem Bild zum nächsten ein weiterer<br />

Kompressionseffekt erzielt. Insgesamt sind Kompressionsraten bis ca. um den Faktor<br />

100 möglich.<br />

Weitere Methoden der Bilddatenkompression sind die Kompression mit Hilfe der Wavelet-<br />

Transformation [Str02], bei der die zur Bildbeschreibung benötigte Funktionsbasis aus den<br />

Bildern selbst gewonnen wird sowie die fraktale Bildkompression [Fis96], bei der Bilder durch<br />

typische, kleine Bildausschnitte <strong>und</strong> deren Kombination zu fraktalen Mustern durch Überlagerung<br />

sowie unter Verwendung affiner Abbildungen approximiert werden.

Hurra! Ihre Datei wurde hochgeladen und ist bereit für die Veröffentlichung.

Erfolgreich gespeichert!

Leider ist etwas schief gelaufen!