Tải bản đầy đủ (.doc) (50 trang)

Xử lý ảnh - Chương 8

Bạn đang xem bản rút gọn của tài liệu. Xem và tải ngay bản đầy đủ của tài liệu tại đây (509.87 KB, 50 trang )

Chơng
6
Biến đổi Fourier rời rạc
6.1 Chỉ dẫn
Trong chơng 2,chúng ta đ chứng minh rằng đáp ứng tần số của hệ thống của hệ thốngã
tuyến tính bất biến (LSI ) 2-D đợc cho bởi:


=

=
+
=
1 2
2211
)(
2121
),(),(
k k
kkj
ekkhH


(6.1)
Nếu h(k
1
,k
2
) chỉ có chỉ tồn tại với k
1


0, k
2


0 và tổng quát đợc xác định trong miền hữu
hạn có kích thớc N
ì
N thì


=

=
+
=
1
0
1
0
)(
2121
1 2
2211
),(),(
N
k
N
k
kkj
ekkhH



(6.2)
Công thức này chứng tỏ rằng
H( , )

1 2
là tuần hoàn, chu kỳ tuần hoàn là 2. Nếu chúng
ta lấy mẫu dới dạng
1
,
2
, và miền xác định là (0
1
2) và (0
2
2), N
ì
N mẫu,
chúng ta có thể viết:



1 1
2
=
N
n




2 2
2
=
N
n
(6.3)
vì thế
( )


=
+



=
=
1
0
2
1
0
2121
1
2211
2
),(),(
N
k

knkn
N
j
N
k
ekkhnnH

(6.4)
Biểu thức (6.4) đợc gọi là biến đổi Fourier rời rạc 2-D hay còn gọi là DFT. Công thức này đ-
ợc áp dụng vào nhiều ứng dụng nh lọc, nén ảnh, phóng đại ảnh. Trong chơng này chúng ta sẽ
nghiên cứu 2-D DFT và các kỹ thuật tính toán. Đầu tiên, chúng ta sẽ xem xét 1-D DFT, sau
đó mở rộng ra cho 2-D.
6.2 Biến đổi Fourier 1-D
Biến đổi Fourier 1-D cho tín hiệu thời gian rời rạc f(kT) tính theo công thức :
75



=

=
1
0
2
)()(
N
k
nk
N
j

ekTfnF


(6.5)
Công thức này có thể viết lại dới dạng



=

=
1
0
Ư)()(
N
n
nk
N
WkfnF
(6.6)
ở đây f(k) = f(kT) và W
N
= e
- j2 /N
.
W
N
đợc gọi là hạt nhân của phép biến đổi. Tổng quát, F(n)
có dạng


)(
)()(
nj
enAnF

=
(6.7)
Ký hiệu A(n),

(n) gọi là phổ khuyếch đại và phổ pha của F(n).
6.2.1 Biến đổi ngợc DFT
Hàm f(k) là biến đổi ngợc DFT của F(n) cho bởi theo biểu thức



=
=
1
0
2
)(
1
)(
N
n
nk
N
j
enF
N

kf


(6.8)
Chứng minh: Từ định nghĩa của DFT




=

=


=

=


=
=






=
1
0

1
0
)(
1
0
1
0
1
0
)(
1
)(
1
)(
1
N
m
N
n
mkn
N
kn
N
N
n
N
m
nm
N
N

n
nk
N
Wmf
N
WWmf
N
WnF
N
(6.9)
Đặt


=

=
1
0
)(
N
n
mkn
N
WS
Nếu (k = m) thì S = N.
Nếu (k

m), chúng ta có thể viết:
S = 1 + W
N


(k -m )
+ W
N

2(k -m )
+ ... + W
N

(N-1)(k -m )

hoặc

)(
2
))(2(
m)-(k
N
m)-N(k
N
1
1
W-1
W-1
mk
N
j
mkj
e
e

S




=
=


Khi e
j2

(k-m)

= 1 và e
j2

/N. (k-m
)
1 với (k m), vì vậy S = 0 với (k m ).
Vì vậy, biểu thức (6. 9) có thể rút gọn thành
76
f(k).N
1
)(
1
1
0
N
WnF

N
N
n
nk
N
==


=
Kết quả này giống nh biểu thức (6.8).
Khi f(k) có thể rút ra từ F(n) và ngợc lại, chúng gọi là cặp biến đổi. Cặp biến đổi này có
dạng

)()( nFkf
Chú ý từ biểu thức (6.8) ta có thể dễ dàng chứng minh:

)(
)(
1
)(
1
1
0
.
2
1
0
)(
2
kf

enF
N
enF
N
N
n
nk
N
j
N
n
Nkn
N
j
=
=
=



=

=
+


(6.10)
Mặc dù f(k) đợc xác định trên miền k

[0,N], nó vẫn là tín hiệu tuần hoàn với chu kỳ NT.

(T đợc bao hàm và rút ra từ biểu thức 6.5).
6.2.2 Một vài tính chất của DFT
Tuyến tính. Nếu ta có hai d y tuần hoàn cùng ã f
1
(n) và f
2
(n), và cả hai d y này tuần hoànã
với chu kỳ N, đợc dùng để tính
f
3
(k) = af
1
(k) + bf
2
(k) (6.11)
là kết quả của biến đổi DFT f
3
(n) cho bởi
F3(n) = aF1(n) + bF2(n) (6.12)
ở đây a, b là hằng số và
F
1
(n) = DFT của f
1
(k)
F2(n) = DFT của f2(k)
Tính đối xứng. Tính đối xứng của DFT rất hay đợc dùng.
nk
N
j

N
k
nk
N
j
N
k
N
N
j
N
k
nNk
N
eekf
eekf
WkfnNF


=


=


=





=
=
=


2
1
0
2
1
0
2
1
0
)(
)(
)(
)()(
Nếu f(k) là thực thì
77
)( Nkf +




=

=









=

)()()(
1
0
.
2
nFekfnNF
N
k
nk
N
j

(6.13)
Dấu * có nghĩa là liên hợp phức.

Tích chập tuần hoàn. Coi f
1
(k) và f
2
(k) là hai d y tuần hoàn có chu kỳ ã N, với biến đổi
Fourier rời rạc là F
1

(n) và F
2
(n). Xem xét tích F(n
1
).F(n
2
)
khi
)()(
1
0
1111
1
11


=

=
N
k
kn
N
WkfnF

)()(
1
0
2222
2

22


=

=
N
k
kn
N
WkfnF

và tại các vị trí n
1
= n
2
= n
Đặt f
3
(k) = IDFT của F
1
(n).F
2
(n)
hay
( )
nk
N
n
WnFnF

N
kf


=
=
1
0
213
)().(
1
)(
vì vậy









=









=



=
+

=

=

=

=

=
+
1
0
)(
1
0
22
1
0
11
1
0
1

0
1
0
)(
2211
21
21
1 2
21
1
)()(
)()(
1
N
n
kkkn
N
N
k
N
k
nk
N
N
n
N
k
N
k
kkn

N
3
W
N
kfkf
WWkfkf
N
(k)f
Chú ý là



=


=
+
0
1
1
1
0
)(
21
N
n
kkkn
W
N
ở đây l là số nguyên. Vì vậy mà

)()()(
12
1
01
113
lNkkfkfkf
N
k
=


=
(6.14)
78
cho k = k
1
+ k
2
+ lN
các trờng hợp còn lại.
W =
.=
2
n-
N
2
1
11
1
2

22
1
11
1
0
2211
1
0
1
0
12
1
0
111111
)()(
)()()().(
k
N
k
kn
N
N
n
N
k
kn
N
N
k
kn

N
Wkfkf
WkfWkfnFnF



=


=

=


=

ở đây k = 0 đến 2N - 1.
Biểu thức trên biểu diễn tích chập của hai tín hiệu tuần hoàn. Chú ý rằng biêủ thức này chỉ
áp dụng cho hai d y có chung một chu kỳ, và chiều dài của d y tính theo biểu thức trên là ã ã 2N -
1. Kết quả này chứng minh rằng trong DFT, tín hiệu có số mẫu lớn hơn N sẽ đợc biến đổi
thành d y tuần hoàn có chu kỳ ã N. Khi dùng DFT cho một tín hiệu không có chu kỳ, mà kết quả
thu đợc từ tích hai d y, ta sẽ phạm một sai lầm gọi là lỗi ã wraparound. Đó là lý do ta phải làm
cho cả hai d y có chu kỳ bằng nhau. Để sửa lỗi này, một số số 0 cần phải thêm vào cả hai d y đểã ã
chiều dài hai d y bằng nhau. Ví dụ, nếu một d y có chiều dài ã ã A, một d y có chiều dài ã B, kết quả
ta phải thêm các số 0 cho cả hai d y có chiều dài ít nhất là ã A + B - 1.
Bài tập 6.1
Cho hai d y sauã





=
0
1
)(
1
kf




=
0
1
)(
2
kf
1. Tính bằng tay tích chập của hai d y trên. Vẽ một lã u đồ biểu diễn thuật toán.
2. Làm lại phần 1, nhng lần này sử dụng tích chập tuần hoàn.
3. Lập một chơng trình C rút ra f
3
(k) từ biểu thức f
3
(k) = IDFT{DFT[f
1
(k)]. DFT[f
1
(k)]}. So
sánh kết quả của phần 1 và phần hai.
4. Bây giờ thêm các số không vào f

1
(k) và f
2
(k) để chu kỳ của chúng = 5 + 6 - 1. Làm lại
phần 3 và so sánh kết quả.
6.3 Thuật toán biến đổi nhanh Fourier
Tính trực tiếp giá trị của DFT bao gồm N phép nhân phức và N - 1 phép cộng phức cho mỗi
giá trị của F(n). Khi N giá trị đợc tính toán thì N
2
phép nhân và N(N - 1) phép cộng đợc tính
toán. Cũng nh vậy, cho N có giá trị rất lớn, tính trực tiếp giá trị của DFT sẽ đòi hỏi một số
phép tính lớn đến mức không thể chấp nhận đợc. Để ví dụ, cho N = 1024 = 2
10
ta sẽ phải tính
2
20
= 1,048,576 phép nhân số phức và một số gần bằng nh vậy các phép cộng.
Hoàn thiện có nghĩa là phải giảm số phép tính trong biến đổi Fourier xuống. Dới đây chúng
ta sẽ giới thiệu hai thuật toán hay dùng là thuật toán phân chia thời gian và thuật toán phân
chia tần số. DFT dùng các thuật toán trên gọi là Fast Fourier transform (FFT).
6.3.1 Thuật toán phân chia thời gian
Xem xét tính toán của DFT cho bởi (5.6) với N= 2
r
(r là một số nguyên bất kỳ). Cơ sở của
thuật toán phân chia thời gian thì rõ ràng. Tuy nhiên, việc thiết kế phần mềm cũng đòi hỏi
một số phân tích chi tiết. Để làm rõ các bớc của thuật toán này chúng ta sẽ bắt đầu phân tích
với N = 16 và sau đó mở rộng ra áp dụng cho N bất kỳ.
Cơ sở của thuật toán phân chia thời gian dựa trên cơ sở chiến lợc chia và chiếm. Các bớc
sau sẽ làm sáng tỏ thuật toán. Vì trong trờng hợp này N =16; nên,
79

0 k
1
4
các trờng hợp còn lại.
0 k
1
5
các trờng hợp còn lại.


=

=
15
0
16
)()(
k
nk
WkfnF

Chia d y ã f(k) thành hai d y, một d y đã ã ợc rút ra từ phần tử chẵn và một d y từ những phần tửã
lẻ. Đó là,


=

=

+=

15
0
16
15
0
16
)()()(
k
nk
k
nk
WkfWkfnF

k chẵn k lẻ
Chúng có thể viết thành

=
+
=

++=
7
0
)12(
16
7
0
)2(
16
)12()2()(

k
kn
k
kn
WkfWkfnF
(6.15)
Chú ý là

nk
nkjknj
kn
W
eeW



=
==
8
.
8
2
)2(.
16
2
)2(
16

vì thế


=

=

++=
7
0
816
7
0
8
)12()2()(
k
nkn
k
nk
WkfWWkfnF
đặt

f(2k)(k)f
10
=

1)f(2k(k)f
11
+=
Ta đợc

=


=

+=
7
0
81116
7
0
810
)()()(
k
nkn
k
nk
WkfWWkfnF
(6. 16)
Đặt

=

=
7
0
81010
)()(
k
nk
WkfnF
(6.17)


=

=
7
0
81111
)()(
k
nk
WkfnF
(6.18)
Viết lại biểu thức (6.16) chúng ta đợc

(n)FW (n)F F(n)
11
-n
1610
+=
(6.19)
Cũng nh vậy, phát triển cho một biểu thức
80
(n)FW -(n)F 8)F(n
11
-n
1610
=+
(6.20)
Biểu thức (6.19) và (6.20) định dạng những đơn vị tính toán gọi là bớm. Hình 6.1 là biểu đồ
của phần tử bớm. Ký hiệu W
16

-n
thờng gọi là trọng lợng hay hệ số xoay. Hai biểu thức này biểu
diễn bớc cuối cùng trong lu đồ tính toán của hình 6.2.
Bây giờ xem xét biểu thức


=

=
7
0
81010
)()(
k
nk
WkfnF
Xử lý nh trên chúng ta có


=

=

++=
7
0
4108
3
0
41010

)12()2()(
k
nkn
k
nk
WkfWWkfnF
Dễ thấy

-2n
16
-n
8
WW =
đặt

1)(2kf(k)f
(2k)f(k)f
1021
1020
+=
=

Hình 6.1 (a) Bớm; (b) Biểu diễn rút gọn.
81
F
10
(n) F(n)

F
11

(n) F(n+8)
F
10
(n) F(n)

F
11
(n) F(n+8)
1
W
16
-n
n
Hình 6.2 Bớc cuối cùng của thuật toán biến đổi FFT phân chia miền thời gian. X(k)
ký hiệu vector chứa giá trị đợc tính qua phép biến đổi FFT.
Vì vậy,

=

=

+=
3
0
421
3
0
2
1642010
)()()(

k
nk
k
nnk
WkfWWkfnF

(n)FW (n)F (n)F
21
-2n
162010
+=
(6.21)

(n)FW - (n)F 4)(nF
21
-2n
162010
=+
(6.22)
ở đây

=

=
3
0
42020
)()(
k
nk

WkfnF
(6.23)

=

=
3
0
42121
)()(
k
nk
WkfnF
(6.24)
Tơng tự

(n)FW (n)F (n)F
23
-2n
162211
+=
(6.25)
(n)FW - (n)F 4)(nF
23
-2n
162211
=+
(6.26)
82
01234567

01234567
01234567
8910111213
1415
F
10
(n)
F(n)
F
11
(n)
X(k)
X(k)
ở đây

=

=
3
0
42222
)()(
k
nk
WkfnF
(6.27)

=

=

3
0
42323
)()(
k
nk
WkfnF
(6.28)

(2k)f (k)f
1122
=

1)(2kf (k)f
1123
+=
Biểu thức (6.21), (6.22), (6.25) và (6.26) có thể biểu diễn bằng sơ đồ hình 6.3. Biểu thức
(6.23), (6.24), (6.27) và (6.28) có thể tiếp tục chia nhỏ ra nh các bớc đ làm ở trên nhã sau:

(n)FW (n)F (n)F
31
-4n
163020
+=
(6.29)
(n)FW - (n)F 2)(nF
31
-4n
163020
=+

(6.30)

(n)FW (n)F (n)F
33
-4n
163221
+=
(6.31)
(n)FW - (n)F 2)(nF
33
-4n
163221
=+
(6.32)
(n)FW (n)F (n)F
35
-4n
163422
+=
(6.33)
(n)FW - (n)F 2)(nF
35
-4n
163422
=+
(6.34)

(n)FW (n)F (n)F
37
-4n

163623
+=
(6.35)
(n)FW - (n)F 2)(nF
37
-4n
163623
=+
(6.36)
ở đây
F n f k W
nk
k
30 30 2
0
1
( ) ( )=

=

(6.37)
F n f k W
nk
k
31 31 2
0
3
( ) ( )=

=


(6.38)
..., vv.
Các biểu thức từ (6.29) đến (6.36) cho kết quả trong bớc thứ ba của thuật toán và biểu diễn
trong lu đồ hình 6.4.Mỗi phần tử từ F
30
(n) đến F
37
(n) có thể chia tiếp thành hai phần tử nữa và
bớc này tạo thành sơ đồ cuối cùng (bớc đầu tiên) trong lu đồ.
83
Hình 6.3 Bớc thứ hai sau bớc cuối cùng trong thuật toán FFT.
Hình 6.4 Bớc đầu tiên của lu đồ FFT.
84
01230123
01230123
01234567
01234567
0
F
20
(n)
2
F
21
(n)
4
6
F
22

(n)
0
F
23
(n)
4
2
6
F
10
(n)
F
11
(n)
X(k)
X(k)
W
-2n
Hệ số xoay
n=0 đến 3
0
0
0
0
0
0
00
01010101
0101010101
0

F
30
(n)
F
31
(n)
F
32
(n)
F
33
(n)
F
34
(n)
F
35
(n)
F
36
(n)
F
37
(n)
X(k)
X(k)
D yã
đầu
vào
đ ã

được
sắp
xếp
lại
Hình 6.5 giới thiệu sơ đồ thuật toán FFT cho N = 16. Chú ý rằng do yêu cầu ban đầu của
chơng trình mà d y vào đã ợc sắp xếp lại và chứa ở X(k), ví dụ

x(q) X(k) =
k = 0 đến 15
Bạn sẽ chú ý trên sơ đồ rằng q là giá trị bit của k.
Cho N = 2
4
= 16 chúng ta phải có bốn bớc trong lu đồ. Trong mỗi bớc cần phải có tám bớm.
Trong mỗi bớm chỉ có một phép nhân phức, hai phép cộng hoặc trừ phức. Tổng số phép nhân
phức là 8/2 . 4. Tổng quát cho N = 2
r
số phép nhân phức là (N/2) . r = (N/2 ) log
2
N và số phép
cộng là Nlog
2
N. Chú ý, thực tế số phép nhân sẽ giảm xuống một ít, vì trong bớc đầu tiên hệ số
xoay W
0
= 1 và trong các bớc còn lại chúng ta cũng có các bớm với hệ số xoay = 1.
Xem xét trờng hợp N = 1024 = 2
10
. Số phép nhân cần dùng cho FFT là (N/2).10 = 1024 ì 5
= 5120 so với 1 triệu phép nhân cho tính trực tiếp biến đổi DFT, đây là phơng pháp tiết kiệm
thực sự cho tính toán.

Bây giờ, chúng ta sẽ vạch ra thuật toán FFT. Đó không đơn thuần chỉ là sự phát triển một
chơng trình từ lu đồ. Tuy nhiên, chúng ta có thể nghiên cứu lu đồ và vạch ra các bớc có thể
dùng để phát triển một chơng trình. Từ lu đồ của hình 6.5 chúng ta có thể viết:
Bớc thứ nhất. Trong bớc này ta có tám bớm với trọng lợng (hệ số xoay) W
0
= 1. Chúng ta có
thể viết (xem hình 6.6)

for (j=0 đến 15 với bớc tăng 2)
{
T=X(j+1);
X(j+1)=X(j) - T;
X(j)=X(j) + T;
}
Bớc thứ hai. Chúng ta có:
1.Bốn bớm với trọng lợng bằng 1.
for (j=0 đến 15 với bớc tăng 4)
{
T=X(j);
X(j+2)=X(j) - T;
X(j)=X(j) + T;
}
2. Bốn bớm với trọng lợng W
4
= W(3). Chú ý rằng chúng ta coi rằng các hệ số xoay W, W
2
, ...
, W
7
đ đã ợc tính và đợc chứa trong W(0), W(1), ...W(6).

for (j=0 đến 15 với bớc tăng 4)
{
T=X(j)W(3);X(j+2)=X(j) - T;
X(j)=X(j) + T;
}
Bớc thứ ba. Chúng ta có :
1. Hai bớm với trọng lợng bằng 1.
for (j=0 đến 15 với bớc tăng 8)
{
T=X(j);
85
X(j+4)=X(j) - T;
X(j)=X(j) + T;
}
Hình 6.5 Lu đồ thuật toán thuật toán phân chia miền thời gian.
2. Hai bớm với trọng lợng bằng W

(1) = W
2
.
for (j=1 đến 15 với bớc tăng 8)
{
T=X(j)W(1);
X(j+4)=X(j) - T;
X(j)=X(j) + T;
}


86
0

1
2
3
4
5
6
7
0
2
4
6
0
2
4
6
0
4
0
4
0
4
0
4
0
0
0
0
0
0
0

0
0
8
4
12
2
10
6
14
1
9
5
13
3
11
7
15
0000
1000
0100
1100
0010
1010
0110
1110
0001
1001
0101
1101
0011

1011
0111
1111
0
8
4
12
2
10
6
14
1
9
5
13
3
11
7
15
0
4
8
12
2
6
12
14
1
5
9

13
3
7
11
15
0
2
4
6
8
10
12
14
1
3
5
7
9
11
13
15
0
1
2
3
4
5
6
7
8

9
10
11
12
13
14
15
0000
0001
0010
0011
0100
0101
0110
0111
1000
1001
1010
1011
1100
1101
1110
1111
n=0 n=0 đến 1 n=0 đến 3 n=0 đến 7
n
W
8

n
W

4

n
W
2

n
W

Bậc của dãy vào biểu diễn
dạng nhị phân
Bậc của dãy ra biểu diễn
dạng nhị phân
bước 0 bước 1 bước 2 bước 3
3. Hai bớm với trọng lợng bằng W(3) = W
4
.
for (j=2 đến 15 với bớc tăng 8)
{
T=X(j)W(3);
X(j+4)=X(j) - T;
X(j)=X(j) + T;
}
Hình 6.6 (a) Bớm cho thuật toán phân chia miền tần số;(b) Một bớm đơn giản.
4. Hai bớm với trọng lợng bằng W

(5) = W
6
.
for (j=3 đến 15 với bớc tăng 8)

{
T=X(j)W(5);
X(j+4)=X(j) - T;
X(j)=X(j) + T;
}
Bớc thứ t và là bớc cuối cùng.
1.Một bớm với trọng lợng bằng 1.
T = X(0)
X(8)= X(0) - T
X(0) = X(8) +T
2. Một bớm với trọng lợng bằng W

(0) = W.


T = X(1)W(0)
X(1+8)= X(1) - T
X(1) = X(1) +T
3. Một bớm với trọng lợng bằng W

(1) = W
2
.


T = X(1)W(1)
X(2+8)= X(0) - T
X(2) = X(2) +T
87
F(2n)

F(2n+1)
)(
10
kf
)(
11
kf
(a)
F(2n)
F(2n+1)
)(
10
kf
)(
11
kf
(b)
.
.
.
8. Một bớm với trọng lợng bằng W

(6) = W
7
.
T = X(7)W(6)
X(7+8)= X(7)-T
X(7) = X(7) +T
Các bớc dẫn chúng ta đến thuật toán với N = 16.
Thuật toán

ip=1
kk=8
incr=2
cho iter=0 đến 3 trong các bớc của 1
{
cho j=0 đến 15 trong các bớc của incr
{
i = j + ip
T = X(j)
X(i) = X(j) - T
X(j) = X(j) +T
nếu (iter không bằng 0) thì
{
cho k=1 đến ip-1 trong các bớc của 1
{
r = k*kk - 1
cho j=k đến 15 trong các bớc của 15
{
i=j+ip
T=X(i)*W(r)
X(i)=X(j)-1
X(j)=X(j)+T
}
}
}
kk=kk/2
ip= ip*2
inc=inc*2
}
Thuật toán trên có thể dễ dàng mở rộng cho tất cả các trờng hợp của N. Chỉ có một lĩnh vực

còn lại cần phải giải thích là sự sắp xếp lại các d y dữ liệu đầu vào. Điều này có thể tạo ra dễã
dàng nếu chúng ta tạo ra một bảng (LUT) L(i), L(i) là các giá trị đảo ngợc bit của i. Nếu dữ liệu
đợc đọc từ một file thì tất cả các việc mà chúng ta phải làm là chuyển địa chỉ vùng của chúng
trong file qua bảng LUT và lu các dữ liệu này trong địa chỉ chứa kết quả trong d y đầu vào, X.ã
Bớc này có thể chuyển sang ngôn ngữ C nh sau:
for (i=0; i<N; i++)
fscanf (fptr, %f , &X[L[i]]);

88
Kết quả của LUT đợc chuyển thẳng và đợc cung cấp với chơng trình của thuật toán tính
FFT trong Listing 6.1 dới dạng modun con dới tên bit_reversal(...).
Chơng trình 6.1 FFTDT.C FFT 1-D Thập phân trong miền thời gian.
/***********************************
* Program developed by: *
* M.A.Sid-Ahmed. *
* ver. 1.0 1992. *
* @ 1994 *
*********************************/
/* FFT - Decimation-in-time routine with examplemain
programing proper usage. */
#define pi 3.141592654
#include <stdio.h>
#include <math.h>
#include <alloc.h>
#include <stdlib.h>
void bit_reversal(unsigned int *, int , int);
void WTS(float *, float *, int, int);
void FFT(float *xr, float *xi, float *, float *,
int , int);
void main()

{
int i,k,m,N,n2,sign;
unsigned int *L;
float *wr,*wi,*xr,*xi;
char file_name[14];
FILE *fptr;
printf("\nEnter name of file containing data points-> ");
scanf("%s",file_name);
if((fptr=fopen(file_name,"rb"))==NULL)
{
printf("file %s does not exist.");
exit(1);
}
printf("Enter # of data points to be read -->");
scanf("%d",&N);
m=(int)(log10((double)N)/log10((double)2.0));
k=1;
for(i=0;i<m;i++)
k<<=1 ;
if (k!=N)
{
printf("n Length of file has to be multiples of 2. ");
exit(1);
}
89
/* Allocating memory for bit reversal LUT. */
L=(unsigned int *)malloc(N*sizeof(unsigned int));
/* Generate Look-up table for bit reversal. */
bit_reversal(L,m,N);
/* Allocating memory for FFT arrays ( real and imag.) */

xr=(float *)malloc(N*sizeof(float));
xi=(float *)malloc(N*sizeof(float));
/* Setting-up the data in real and imag. arrays.*/
for(i=0;i<N;i++)
{
k=L[i] ;
xr[k]=(float)getc(fptr);
xi[k]=0.0 ;
}
fclose(fptr);
/* Allocating memory for twiddle factors. */
n2=(N>>1)-1;
wr=(float *)malloc(n2*sizeof(float));
wi=(float *)malloc(n2*sizeof(float));
/*Generating LUT for
twiddle factors. */
WTS(wr,wi,N,-1);
/* Taking FFT. */
FFT(xr, xi, wr, wi, m, N);
printf("Enter file name for storing FFT output.--->");
scanf("%s",file_name);
fptr=fopen(file_name,"w");
for(i=0;i<N;i++)
fprintf(fptr," %e %e",xr[i], xi[i]);
fclose(fptr);
}
void bit_reversal(unsigned int *L, int m, int N)
/* Routine for generating LUT for bit reversal.
Note: N=(2 to the power of m).
LUT will reside in LI]*/

{
unsigned int MASK,C,A,j,k,i;
for(k=0;k<N;k++)
{
MASK=1;
C=0;
for(i=0,j=m-1;i<m;i++,j--)
{
A=(k&MASK)>>i;
A<<=j ;
C|=A;
90
MASK=MASK<<1;
}
L[k]=C;
}
}
void WTS(float *wr, float *wi, int N, int sign)
/* Generating LUT for twiddle factors.
Note:
sign=-1 for FFT, and
sign=1 for IFFT */
{
int n2,i ;
float theta;
n2=(N>>1)-1;
/* Generate look-up tables for twiddle factor. */
theta=2.0*pi/((float)N);
for(i=0;i<n2;i++)
{

wr[i]=(float)cos((double)((i+1)*theta));
wi[i]=(float)sin((double)((i+1)*theta));
if(sign==(int)(-1)); wi[i]=-wi[i];
}
}
/********************************************/
void FFT
(float *xr, float *xi, float *wr, float *wi, int m, int N)
{
/* FFT algorithm,
Decimation-in-time algorithm.
Note:
1. N=2 to the power of m.
2. The input arrays are assumed to be rearranged in bit-reverse
order.
You will need to use routine "bitreversal" for that purpose.
3. The twiddle factors are assumed to be stored in LUT's wr[I and
wi[j. You will
need to use routine LUT for calculating and storing twiddle factors.*/
int ip,k,kk,l,incr,iter,j,i;
float Tr,Ti;
ip=1;
kk=(N>>1);
incr=2 ;
for(iter=0; iter<m; iter++)
{
91
for(j=0; j<N; j+=incr)
{
i=j+ip;

Tr=xr[i];
Ti=xi[i];
xr[i]=xr[j]-Tr;
xi[i]=xi[j]-Ti;
xr[j]=xr[j]+Tr;
xi[j]=xi[j]+Ti;
}
if(iter!=0)
{
for(k=1; k<ip; k++)
{
l=k*kk-1 ;
for(j=k; j<N; j+=incr)
{
i=j+ip ;
Tr=xr[i]*wr[l]-xi[i]*wi[l];
Ti=xr[i]*wi[l]+xi[i]*wr[l];
xr[i]=xr[j]-Tr;
xi[i]=xi[j]-Ti;
xr[j]=xr[j]+Tr;
xi[j]=xi[j]+Ti;
}
}
}
kk>>=1;
ip<<=1;
incr<<=1;
}
}
Chú ý rằng trong chơng trình 6.1 chúng ta giả thiết là dữ liệu đợc lu nh d y của các ký tựã

không dấu. Nếu bạn muốn xử lý trên một số dấu phẩy động bạn cần thay đổi các câu lệnh mở
và đọc dữ liệu trong file dữ liệu. Chơng trình này cũng cho phép lựa chọn FFT hoặc IFFT. Cho
FFT, chơng trình con "WTS(...) " tính toán và lu các hệ số dịch xoay trong một LUT đợc gọi lên
vói tham số "sign" đợc gán giá trị -1, ví dụ, WTS(wr,wi,N,-1) và cho IFFT, WTS(wr,wi,N,1).
Với IFFT, bạn cần chia d y ra cho N trong chã ơng trình gọi hoặc là chơng trình chính.

Bài tập 6.2 Kiểm tra chơng trình FFT bằng cách làm lại chơng trình 6.1. Chú ý rằng trong
trờng hợp này bạn phải thêm các giá trị 0 để làm cho các d y có chiều dài 2ã
4
= 16 và tất nhiên
là lớn hơn chiều dài d y nhỏ nhất đòi hỏi là (6 + 5 - 1). Mối tã ơng quan của hai d y cho kết quảã
trong một tín hiệu tuần hoàn có chu kỳ bằng 16.
6.3.2 Thuật toán phân chia tần số.
Thay vì chia d y vào thành các vị trí chẵn và lẻ, chúng ta sẽ đã a ra một chơng trình giống
nh chơng trình trên nhng lần này ta bắt đầu từ d y ra. Chã ơng trình này bao gồm các bớc sau:
92

kn
N
N
k
nN
N
Nk
kn
N
N
k
kn
N

W
N
kfWkf
WkfWkfnF


=


=


=









++=
+=
12/
0
2/
1
2/
12/

0
)
2
()(
)()()(

Bây giờ, chia d y ã F(n) thành hai d y dựa trên giá trị chẵn và lẻ của ã n.


)]
2
()([)2(
2/
2/).2(
12/
0
kn
N
Nn
N
k
W
N
kfWkfnF


=
++=




)]
2
()([)12(
)12(
2/
2/).12(
12/
0
+
+

=
++=+

nk
N
Nn
N
k
W
N
kfWkfnF

Chú ý rằng
0.1
2
==
njnN
N

eW

0.1
)12(
2/).12(
==
+
+
nj
Nn
N
eW

Vì vậy

)]
2
()([)2(
2/
12/
0
kn
N
N
k
W
N
kfkfnF



=
++=

[ ]

])
2
()([)12(
2/
12/
0
kn
N
k
N
N
k
WW
N
kfkfnF


=
+=+

Đặt
f k f k f k
N
10
2

( ) ( ) ( )= + +
f k f k f k
N
W
N
k
11
2
( ) [ ( ) ( )]= +

Vì vậy


.)()2(
2/
12/
0
10
kn
N
N
k
WkfnF


=

=
(6.39)
93


.)()12(
2/
12/
0
11
kn
N
N
k
WkfnF


=

=+
(6.40)
Các biểu thức (6.39) và (6.40) có thể biểu diễn bằng dới dạng biểu đồ bớm nh trong hình 6.6.
Chúng ta có thể tiếp tục chia nhỏ các tổng cho trong các biểu thức (6.39) và (6.40), tiếp tục
làm nh vậy cho tới khi mỗi tổng giảm xuống chỉ còn lại một phần tử. Giải thuật này giống nh
giải thuật thuật toán phân chia thời gian và để lại cho bạn nh một bài tập cho bạn. Một lu đồ
cho FFT phân chia tần số với N = 4 trình bày trong hình 6.7. Bạn cần chú ý đến bậc của dữ
liệu đầu ra là bit đợc đảo. Phần mềm thực hiện thuật toán trên thì rất giống phần mềm thực
hiện FFT phân chia miền thời gian, và một chơng trình C đợc cung cấp ở Chơng trình 6.2.
Có lẽ bạn sẽ tự hỏi: nếu phân chia miền thời gian đ thực hiện đã ợc công việc thì tại sao lại
phải xem xét thêm FFT phân chia tần số. Để trả lời câu hỏi này, chúng ta sẽ cần xem xét phần
kế tiếp, FFT giảm lợc.
Chơng trình 6.2 FFTDF FFT phân chia tần số.
/****************************
* Program developed by: *

* M.A.Sid-Ahmed. *
* ver. 1.0 1992.1994 *
*****************************/
/* FFT - Decimation-in-frequency routine.*/
#define pi 3.141592654
void bit_reversal (unsigned int *, int, int);
void WTS(float *, float *, int, int) ;
void FFT(float *xr, float *xi , float, float, int, int);
void FFT
(float *xr, float *xi, float *wr, float *wi, int m, int N)
{
/* FFT algorithm.
Decimation-in-frequency algorithm.
Note :
1. N=2 to the power of m.
2. The output arrays are left in bit-reverse
order. You will need to use routine "bit-reversal" to place them in
normal ascending order.
3. The twiddle factors are assumed to be stored in LUT's wr[j and
wiEj. You will need to use routine LUT for calculating and storing
twiddle factors. */
int ip,k,kk,l,incr,iter,j,i;
float Tr,Ti,diffr,diffi;
94

Tài liệu bạn tìm kiếm đã sẵn sàng tải về

Tải bản đầy đủ ngay
×