Fourier-Transformation durch Integer-Rotation
Fourier-Transformation durch Integer-Rotation
Fourier-Transformation durch Integer-Rotation
Erfolgreiche ePaper selbst erstellen
Machen Sie aus Ihren PDF Publikationen ein blätterbares Flipbook mit unserer einzigartigen Google optimierten e-Paper Software.
<strong>Fourier</strong>-<strong>Transformation</strong> <strong>durch</strong> <strong>Integer</strong>-<strong>Rotation</strong><br />
Die diskrete <strong>Fourier</strong>transformation eines Signals f(t), definiert auf t = 0 . . . n − 1, ist gegeben<br />
<strong>durch</strong><br />
F (s) =<br />
n−1 ∑<br />
t=0<br />
f(t)e −i 2π n st .<br />
Schneller berechnet kann dieses Ergebnis werden <strong>durch</strong> die Fast-<strong>Fourier</strong>-<strong>Transformation</strong> (FFT),<br />
z.B. nach dem Schema in Abbildung 1. Oben ist das Input-Signal (f(t)). Der erste Schritt ist<br />
eine Umordnung der Input-Werte. Dieser Schritt heißt auch bit reversal sorting, denn es wird<br />
z.B. der Wert an Stelle 6 (110 binär) auf die Stelle 3 (011 binär) verschoben. Danach folgt der<br />
rekursive Teil. Der dicke Punkt muss dabei so interpretiert werden: Multipliziere den Wert mit<br />
e −i 2π N m , wobei N = 2, 4, 8 und 0 ≤ m < N , und gib das Ergebnis positiv nach links und negativ<br />
2<br />
nach unten weiter. Im ersten Part wird also einfach mit e −i 2π 2 0 = 1 multipliziert, im zweiten<br />
Part mit 1 und −i, und so weiter.<br />
Die Tatsache, dass hier mit irrationalen Zahlen multipliziert wird (z.B. e −i 2π 8 3 ), zeigt, dass<br />
ganze Zahlen in f (z.B. wenn f quantisiert ist) <strong>durch</strong> die <strong>Transformation</strong> in Gleitkommazahlen<br />
verwandelt wird, was einer Datenvermehrung entspricht. Es gibt zwar <strong>Integer</strong>-FFTs, aber<br />
auch diese Erweitern den Wertebereich, etwa <strong>durch</strong> Addition und Subtraktion, wo immer ein<br />
zusätzliches Bit entsteht (wenn a und b 8 Bit benötigen (−128 . . . 127), dann braucht a + b 9<br />
Bit (−256 . . . 254)).<br />
Hier soll daher ein neuer Ansatz verfolgt werden. Es ist ja so, dass die Multiplikation mit<br />
e −i 2π N m einfach einer <strong>Rotation</strong> gegen den Uhrzeigersinn um den Winkel 2π m (in Radianten)<br />
N<br />
entspricht. Diese <strong>Rotation</strong> approximieren wir nach dem Schema in Abbildung 2. Dabei werden<br />
der Realteil einer Zahl auf der X-Koordinate und der Imaginärteil auf der Y-Koordinate aufgetragen.<br />
Dann wird der 2D-Wertebereich [−2 n , 2 n − 1] 2 in Quadrat-Ränder aufgeteilt, die alle<br />
Positionen ({−k − 1, k}, [−k − 1, k]) und ([−k − 1, k], {−k − 1, k}) enthält. Komplexe Zahlen,<br />
die sich auf einem solchen k-Ring befinden, werden dann entlang des Rings verschoben, wobei<br />
eine Verschiebung um 2k + 1 Positionen einer <strong>Rotation</strong> um π entspricht.<br />
2<br />
A B A B A B A B<br />
A A B B A A B B<br />
A A A A B B B B<br />
Abbildung 1: FFT<br />
1
2 n -1<br />
2k+1 -1,k 2k+1<br />
-2 n -1,0 0,0 k,0<br />
-k-1,-1 -1,-1 0,-1<br />
2k+1 0,-k-1 2k+1<br />
-2 n<br />
2 n -1<br />
Abbildung 2: <strong>Integer</strong>-<strong>Rotation</strong><br />
Das Addieren und Subtrahieren der (rotierten) komplexen Zahlen kann selbst wieder <strong>durch</strong><br />
eine <strong>Rotation</strong> implementiert werden. Denn für reelle a und b ist die Abbildung (a, b) ↦→ (a +<br />
b, a−b) eine 45-Grad-<strong>Rotation</strong> plus einer Multiplikation mit dem Faktor √ 2. Wir verzichten auf<br />
den Faktor und approximieren auch diese Approximation <strong>durch</strong> eine <strong>Integer</strong>-<strong>Rotation</strong>. Da es<br />
sich um komplexe Zahlen handelt, müssen die Real- und Imaginärteile getrennt rotiert werden.<br />
Wichtig ist bei all dem, dass eine <strong>Rotation</strong> von x = a + ib um 2π m das gleiche ergibt wie<br />
N<br />
eine <strong>Rotation</strong> von −x um − 2π( N − m), wobei −x als −a − 1 + i(−b − 1) definiert werden muss.<br />
N 2<br />
Das müsste für FFTs von reellen Signalen die Eigenschaft F (s) = F (N − s) erhalten, wobei<br />
auch hier a + ib := a + i(−b − 1) gesetzt werden muss. In diesem Fall kann der Ergebnisvektor<br />
auf die Hälfte gekürzt werden. Da sowohl F (0) als auch F ( N ) reell sind (sein müssten), kann<br />
2<br />
man letzteren Realteil in den Imaginärteil von F (0) kopieren, dann hat man es in weiterer Folge<br />
einfach mit N komplexen Werten zu tun.<br />
2<br />
Die inverse <strong>Transformation</strong> macht einfach alle <strong>Rotation</strong>en in umgekehrter Reihenfolge wieder<br />
rückgängig.<br />
Anwendung: Verlustfreie Codierung von Grauwert-Bildern<br />
Ein Bild ist gegeben <strong>durch</strong> ein Array A aus M×N Pixel mit n Bits im Wertebereich −2 n−1 , . . . , 2 n−1 −<br />
1, wobei der Einfachheit halber M und N Zweier-Potenzen sind. Beim Einlesen von Bildern mit<br />
positiven Grauwerten kann/muss man einfach 2 n−1 von jedem Pixel subtrahieren. Die <strong>Transformation</strong><br />
wird dann auf jede Zeile und danach auf jede Spalte angewendet. Dabei erhält man<br />
ein M × N Array von komplexen n-Bit-Zahlen.<br />
2<br />
Zur Codierung wollen wir in eine Datei Bit für Bit diese Zahlen schreiben, allerdings so,<br />
dass führende 0-Bits von ganzen Regionen zusammen als 0 codiert werden. Dazu brauchen<br />
wir zuerst folgende Funktionen, die die Bitanzahlen für komplexe, reelle und positive Zahlen<br />
berechnen:<br />
2
cbits(z = x + iy) = max(rbits(x),rbits(y)<br />
rbits(x) =pbits(max(x, −x − 1))<br />
pbits(x) =<br />
b = 0, v = 1<br />
while v ≤ x<br />
b = b + 1, v = 2v<br />
return b<br />
Der Code zum Schreiben aller notwendigen Bits (nach der <strong>Transformation</strong>) in eine Datei sieht<br />
dann so aus:<br />
code (A, b) =<br />
c = max z∈A cbits(z)<br />
Schreibe b − c 1-Bits<br />
Schreibe 0-Bit<br />
if A größer als 1 Element<br />
Teile A in Viertel A 1 , A 2 , A 3 , A 4<br />
code (A 1 , c)<br />
code (A 2 , c)<br />
code (A 3 , c)<br />
code (A 4 , c)<br />
else if A ist einzelnes Element z<br />
Schreibe c lower Bits von Realteil von z<br />
Schreibe c lower Bits von Imaginärteil von z<br />
Der Code, der die Daten einliest, sieht ziemlich ähnlich aus. Statt b−c 1-Bits zu schreiben, liest<br />
er 1-Bits, bis ein 0-Bit kommt. Die Anzahl der 1-Bits wird von b abgezogen, um c zu erhalten.<br />
Ansonsten müssen nur am Ende c Bits gelesen statt geschrieben werden und das Vorzeichenbit<br />
auf die führenden Bits aufgefüllt werden.<br />
Zur Auswertung soll das <strong>Transformation</strong>sergebnis als Bild ausgegeben und dargestellt werden,<br />
mehrere verschiedene Bilder codiert und decodiert werden, überprüft werden, ob das Bild<br />
korrekt wiederhergestellt werden konnte, und die Dateigrößen mit GIF- und/oder PNG-Dateien<br />
verglichen werden.<br />
3