Tải bản đầy đủ (.pdf) (10 trang)

Biến đổi fourier rời rạc part 5 pptx

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 (337.37 KB, 10 trang )


115
Biểu thức (6.62) có thể mở rộng ra thành

22
2
./2.
1
0
22
),0(),0(
knNj
N
k
ekhnG







22
2
./2.
1
0
22
),1(),1(
knNj
N


k
ekhnG






.
.
.

v.v

Mỗi biểu thức trên biểu diễn DFT của một hàng trong ảnh.
Biểu thức (6.63) cũng có thể mở rộng ra thành:

22
1
./2.
1
0
11
)0,()0,(
knNj
N
k
ekGnH








22
1
./2.
1
0
11
)1,()1,(
knNj
N
k
ekGnH






.
.
.
v.v
Các biểu thức này dẫn ta đến giải thuật sau đây tính FFT hai chiều:

1. Tính 1-D FFT cho tất cả các hàng, và chứa kết quả vào mảng trung
gian.


2. Dịch chuyển mảng trung gian.

3. Rút ra 1-D FFT cho tất cả các hàng của mảng dịch chuyển trung gian.
Kết quả là dịch chuyển của mảng 2-D FFT.

Chúng ta có thể viết biểu thức (6.61) có dạng

116

212
2 1
121
./2.
1
0
1
0
./2.
2121
]),([),(
knNj
N
k
N
k
knNj
eekkhnnH









(6.64)

Nếu chúng ta đặt

11
1
./2.
1
0
2121
),(),(
knNj
N
k
ekkhknG





(6.65)
với k
2
= 0,1,2, , (N-1) thì



1
22
1
./2.
1
0
1121
),(),(
knNj
N
k
eknGnnH





(6.66)
với n
1
= 0,1,2, , (N-1).

Các biểu thức này dẫn chúng ta đến thuật toán tính 2-D FFT sau

1. Dịch chuyển file ảnh.

2. Tính FFT theo từng hàng một của ảnh đã đợc đọc.


3.Dịch chuyển kết quả trung gian.

4. Rút ra một hàng kề hàng FFT của dịch chuyển kết quả trung gian. Kết
quả ta sẽ đợc 2-D FFT.

Trong cả hai phơng pháp dùng để rút ra 2-D FFT, kết quả trung gian đều
đã phải dịch chuyển. Phơng pháp đầu tiên thờng hay đợc sử dụng hơn vì
nó chỉ yêu cầu một phép toán dịch chuyển. Kết quả là một dịch chuyển của
mảng 2-D FFT, có thể dùng trực tiếp dới dạng ấy mà không đòi hỏi một
phép dịch chuyển thứ hai.
Chắc bạn sẽ có một câu hỏi rằng tại sao chúng ta cần phải dịch chuyển.
Lý do của sự dịch chuyển này là hệ thống của bạn có thể không có đủ bộ
nhớ kích hoạt (RAM) để lu trữ kết quả trung gian hoặc là FFT của ảnh.
Nếu bạn có đủ bộ nhớ RAM thì việc dịch chuyển này là không cần thiết, và
bạn có thể đọc thẳng từng cột từ bộ nhớ kích hoạt. Dù sao đi chăng nữa thì
sự lựa chọn vẫn là đọc thẳng từng cột và có kết quả trung gian chứa theo
hàng. Nếu là nh vậy, chúng ta sẽ cần N N dữ liệu thêm vào từ đĩa cứng,

117
yêu cầu thời gian nhiều hơn. Nói một cách khác, dịch chuyển file dẫn đến
từng hàng một trong FFT của kết quả trung gian, đòi hỏi nhiều hơn N lần
truy nhập đĩa.
Câu hỏi bây giờ là làm thế nào chúng ta có thể dịch chuyển một file trong
trờng hợp không thể chuyển tất cả dữ liệu một lần vào bộ nhớ kích hoạt.
Trong phần tiếp theo chúng ta sẽ đề cập đến phơng pháp Eklundh để giải
quyết vấn đề này.
6.5.1 Ma trận dịch chuyển từ bộ nhớ ngoài
Thuật toán đợc giải thích rõ ràng nhất bằng một ví dụ đặc biệt. Xem xét
ma trận có kích thớc 7 7 ở hình 6.10. Các bớc của thuật toán thể hiện rõ
ràng trên hình 6.10. Bạn cần chú ý rằng chơng trình đòi hỏi ba lần lặp lại

để dịch chuyển một ma trận có kích thớc 2
3
2
3
. Trong tất cả các lần
lặp lại bạn cần phải giữ lại trong bộ nhớ kích hoạt tại hai hàng cuối cùng,
cho phép lặp, tất cả là yêu cầu yêu cầu N lần truy nhập đĩa cho xử lý một
ảnh có kích thớc N

N. Nếu N = 2
r
thì r

N số lần truy nhập đĩa để dịch
chuyển một ảnh, ít hơn nhiều so với N

N lần truy nhập trong cách xử lý
đọc một ảnh cơ bản từng khối một. Số lần truy nhập đĩa có thể giảm xuống
bởi đọc, ví dụ, bốn hàng hoặc tám hàng một lúc.
Thuật toán trong trờng hợp tổng quát có thể coi nh là sự phát triển của
giải thuật FFT. Bạn cần phát triển hai lu đồ, một để lựa chọn hàng có thể
đã đợc thêm dữ liệu vào và một để phát hiện ra phần tử đã thay đổi. Những
thuật toán này coi nh là một bài tập. Mã của chơng trình nguồn cho tất cả
các thuật toán này cho ở chơng trình 6.5.

Chơng trình 6.5 TRANSPOS.C chơng trình cho dịch chuyển
một ma trận.

/******************************
* Program developed by: *

* M.A.Sid-Ahmed. *
* ver. 1.0 1992. *
* @ 1994 *
******************************/

/*This program is for obtaining the transpose of a large binary file
stored on secondary memory. We assume that the file is large to the
point that it would not fit in active memory, and the data type in the

118
file is character.*/

#include <stdio.h>
#include <alloc.h>
#include <math.h>
#include <io.h>
#include <conio.h>
#include <stdlib.h>
void transpose(FILE *, int, int);

void main()
{
int N,n;
char file_name[11];
FILE *fptr;
float nsq;

clrscr();
printf("Enter file-name to be transposed >");
scanf("%s",file_name);

fptr=fopen(file_name,"rb+");
if(fptr==NULL)
{
printf("%s does not exist. ");
exit(1);
}
nsq=filelength(fileno(fptr));
N=sqrt((double)nsq);
n=(int)(log10((double)(N))/log10((double)(2.0)));
clrscr();
transpose(fptr,N,n);
fclose(fptr);
}

void transpose(FILE *fptr, int N, int n)

/* Algorithm */
{
int N1,inc;

119
int iter,i,k;
int k1,inc1;
int k2,j,k3,k4;
char *buff1,*buff2,tmp;
long loc;

buff1=(char *)malloc(N*sizeof(char));
buff2=(char *)malloc(N*sizeof(char));
N1=N/2;

inc=1;
inc1=2;


00 02 04 06
11 13 15 17
20 22 24 26
01 03 05 07
10 12
14
16
21 23 25 27
30 32 34 36
41 43 45 47
50 52
54 56
31 33 35 37
40 42 44 46
51 53 55 57
61 63 65 67
70
72
74 76
60 62 64 66
71 73 75 77
41
43
50
52
40

42
51
53
61
63
70
72
60
62
71
73
bíc 0 bíc 2
04
06
15
17
24
26
05
07
14
16
25
27
34
36
35
37
00
02

11
13
20
22
01
03
10
12
21
23
30
32
31
33
45
47
54
56
44
46
55
57
65
67
74
76
64
66
75
77

00
02
04
06
11
13
15
17
20
22
24
26
01
03
05
07
10
12
14
16
21
23
25
27
30
32
34
36
41
43

45
47
50
52
54
56
31
33
35
37
40
42
44
46
51
53
55
57
61
63
65
67
70
72
74
76
60
62
64
66

71
73
75
77
00
11
01
10
02
13
03
12
04
1505
14
06
17
07
16
20
21
30
31
22
23
32
33
24
25
34

35
26
27
36
37
41
50
40
51
43
52
42
53
45
5444
55
47
56
46
57
61
70
60
71
63
72
62
73
65
7464

75
67
76
66
77
bíc 1 Ma trËn chuyÓn vÞ

120
H×nh 6.10 ThuËt to¸n cña Eklundh cho dÞch chuyÓn mét ma trËn.

for(iter=0;iter<n;iter++)
{
gotoxy(1,2);
printf("iteration # %4d",iter+1);
k1=0 ;
for(k=0;k<N1;k++)
{
for(i=k1;i<(k1+inc);i++)
loc=(long)(N)*(long)(i);
if(fseek(fptr,loc,SEEK_SET)!=0)
{
perror("fseek failed");
exit(1);
}
else
{
gotoxy(1,3);
printf("Reading row # %4d",i);
for(k4=0;k4<N;k4++)
*(buff1+k4)=fgetc(fptr);

{
loc=(long)(N)*(long)(i+inc);
}
if(fseek(fptr,loc,SEEK_SET)!=0)
{
perror("fseek failed");
exit(1) ;
}
else
{
gotoxy(1,4);
printf("Reading row # %4d",i+inc);
for(k4=0;k4<N;k4++)
*(buff2+k4)=fgetc(fptr);
}
k3=0;

121
for(k2=0;k2<N1;k2++)
{
for(j=k3;j<(k3+inc);j++)
{
tmp=*(buff1+j+inc);
*(buff1+j+inc)=*(buff2+j);
*(buff2+j)=tmp;
}
k3+=inc1 ;
}
loc=(long)(N)*(long)i;


if(fseek(fptr,loc,SEEK_SET)!=0)
{
perror("fseek failed");
exit( 1 ) ;
}
else
{
gotoxy(1,3);
printf("writing row # %4d",i);
for(k4=0;k4<N;k4++)
putc((char)(*(buff1+k4)),fptr);
}
loc=(long)(N)*(long)(i+inc);
if(fseek(fptr,loc,SEEK_SET)!=0)
{
perror("fseek failed");
exit(1) ;
}
else
{
gotoxy(1,4);
printf("writing row # %4d",i+inc);
for(k4=0;k4<N;k4++)
putc((char)(*(buff2+k4)),fptr);
}
}


122
k1+=inc1 ;

}

inc*=2;
inc1*=2;
N1/=2;
}

Để kiểm tra chơng trình 6.5 chúng ta sẽ áp dụng thuật toán này lên ảnh
cho trong hình 6.11. ảnh này chứa trên đĩa đi kèm theo cuốn sách này dới
file có tên là MOHSEN.IMG.

Chơng trình 6.6 FFT2D.C 2-D FFT

/******************************
* Program developed by: *
* M.A.Sid-Ahmed. *
* ver. 1.0 1992. *
* @ 1994 *
******************************/

/* 2D-FFT - Using Decimation-in-time routine.*/

#define pi 3.141592654
#include <stdio.h>
#include <math.h>
#include <alloc.h>
#include <stdlib.h>
#include <io.h>
#include <conio.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 transpose(FILE *, int, int);
void FFT2D(FILE *, FILE *, float *, float*, unsigned int *,int,int,int);


123
H×nh 6.11 ¶nh ®· ®îc dÞch chuyÓn, "MOHSEN.IMG".
void main()
{
int N,n2,m,k,i;
unsigned int *L;
float *wr , *wi;

char file_name[14];
FILE *fptr,*fptro;
double nsq;

clrscr();
printf(" Enter name of input file-> ");
scanf("%s",file_name);
if((fptr=fopen(file_name,"rb"))==NULL)
{
printf("file %s does not exist.\n");
exit(1);
}
nsq=(double)filelength(fileno(fptr));
N=sqrt(nsq);
m=(int)(log10((double)N)/log10((double)2.0));


124
k=1 ;
for(i=0;i<m;i++)
k<<=1 ;
if (k!=N)
{
printf("Length of file has to be multiples of 2.\n ");
exit(1);
}
H×nh 6.12 ¶nh dÞch chuyÓn cña “MOHSEN.IMG”.
printf(" Enter file name for output file >");
scanf("%s",file_name);
fptro=fopen(file_name,"wb+");

/* 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 twiddle factors. */
n2=(N>>1)-1;

×