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

Biến đổi fourier rời rạc part 6 docx

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


125
wr=(float *)malloc(n2*sizeof(float));
wi=(float *)malloc(n2*sizeof(float));

/*Generating LUT for
twiddle factors. */
WTS(wr,wi,N,-1);
FFT2D(fptr,fptro,wr,wi,L,N,m,-1);
}
void FFT2D(FILE *fptr, FILE *fptro,
float *wr, float *wi, unsigned int *L,
int N, int m, int sign)
{
/* 2-D FFT Algorithm. */
/* fptr=file pointer to input file.
fptro=file pointer to output file.
Note: fptr, fptro should be opened in the main routine. They are closed
before return to @he main routine.
wr[1,wj[I input arrays for twiddle factors, calculated by calling procedure
WTS.
L[I look-up table for bit reversal. N input array size ( NxN words.) =2 to the
power m.
sign =-1 for 2-D FFT,
=1 for 2-D IFFT.
For FFT (sign= 1) the input data is assumed to be real.
The result of the FFT has its origin shifted to (N/2,N/2).*/

int N2,i,j,k,kk;
long loc,NB;
float *xr,*xi,*buff;



N2=N<<1;
NB=sizeof(float)*N2;

/* Allocating memory for FFT arrays ( real and imag.) */
xr=(float *)malloc(N*sizeof(float));
xi=(float *)malloc(N*sizeof(float));
buff=(float *)malloc(NB);

/* First stage. */

126
gotoxy(1,3);
printf(" First stage. ");
for(j=0;j<N;j++)
{
gotoxy(1,4);
printf("FFT of row %4d",j);
if(sign==(int)1)
{
fread(buff,NB,1,fptr);
for(i=0;i<N;i++)
{
k=L[i] ;
kk=i<<1 ;
xr[k]=buff[kk];
xi[k]=buff[kk+1];
}
}
else

{
for(i=0;i<N;i++)
{
k=L[i] ;
xr[k]=(float)getc(fptr);
if(((i+j)%2)!=0) xr[k]=-xr[k];
xi[k]=0.0;
}
}
FFT(xr,xi,wr,wi,m,N);
for(i=0;i<N;i++)
{
k=i<<1;
buff[k]=xr[i];
buff[k+1]=xi[1];
}
fwrite(buff,NB,1,fptro);
}
fclose(fptr);

/* Transpose. */

127
gotoxy(1,5);
printf(" Transposing of intermediate file. ");
rewind(fptro);
transpose(fptro,N,m);
rewind(fptro);

/* Second stage. */

printf("\n Second stage.");
for(j=0;j<N;j++)
{
gotoxy(1,7);
printf("FFT of row %4d",j);
loc=(long)j*NB;
fseek(fptro,loc,SEEK_SET);
fread(buff,NB,1,fptro);
for(i=0;i<N;i++)
{
k=L[i] ;
kk=i<<1 ;
xr[k]=buff[kk];
xi[k]=buff[kk+1];
}
FFT(xr,xi,wr,wi,m,N);
for(i=0;i<N;i++)
{
k=i<<1 ;
if((sign==(int)1)&&((i+j)%2)==(int)0)
{
buff[k]=-xr[i];
buff[k+1]=-xi[i];
}
else
{
buff[k]=xr[i];
buff[k+1]=xi[i];
}
}

if(fseek(fptro,loc,SEEK_SET)!=0)
{

128
perror("\n fseek failed.\n");
exit(1) ;
}
fwrite(buff,NB,1,fptro);
}
fclose(fptro);
}

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 "bit-reversal" for that purpose.
3. The twiddle factors are assumed to be stored in LUT's wr[] and wi[].
You will need to use routine LUT for calculating and storing twiddle
factors.
*/

int ip,k,kk,l,incr,iter,i,j;
float Tr,Ti;


ip=1;
kk=(N>>1);
incr=2 ;

for(iter=0; iter<m; iter++)
{
for(j=0; j<N; j+=incr)
{
i=j+ip;
Tr=xr[i] ;
Ti=xi[i] ;
xr[i]=xr[j]-Tr;

129
xi[i]=xi[j]-Ti;
xr[j]=xr[j]+Tr;
xi[j]=xi[j]+Ti;
}
if(iter!=0)
{
for(k=1; k<ip; k++)
{
i=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<<=l ;
incr<<=l ;
}
}

/**********************************************************
This procedure is for obtaining the transpose of a
large file of complex numbers stored on secondary memory.
We assume that the file is large to the point that it would
not fit in active memory.
***********************************************************/
struct COMPLEX
{
float REAL;
float IMAG;

130
} ;

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

{
int N1 , inc ;
int iter,i,k;
int k1,inc1;
int k2,j,k3,k4,NS;
struct COMPLEX *buff1,*buff2,tmp;
long loc,NT;

NS=sizeof(struct COMPLEX);
NT=N*NS ;
buff1=(struct COMPLEX *)malloc(NT);
buff2=(struct COMPLEX *)malloc(NT);

N1=N/2 ;
inc=1 ;
inc1=2 ;
for(iter=0;iter<n;iter++)
{
gotoxy(1,6);
printf(" Iteration number %4c.",(iter+1));
k1=0 ;
for(k=0;k<N1;k++)
{
for(i=k1;i<(k1+inc);i++)
{
loc=NT*(long)(i);
if(fseek(fptr,loc,SEEK_SET)!=0)
{
perror("fseek failed");
exit(1);

}
else
fread(buff1,NT,1,fptr);
loc=NT*(long)(j+inc);
if(fseek(fptr,loc,SEEK_SET)!=0)

131
{
perror("fseek failed");
exit(1) ;
}
else
fread(buff2,NT,1,fptr);
k3=0 ;
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=NT*(long)i;
if(fseek(fptr,loc,SEEK_SET)!=0)
{
perror("fseek failed");
exit(1);

}
else
fwrite(buff1,NT,1,fptr);
loc=NT*(long)(i+inc);
if(fseek(fptr,loc,SEEK_SET)!=0)
{
perror("fseek failed");
exit(1) ;
}
else
fwrite(buff2,NT,1,fptr);
}
k1+=inc1;
}
inc*=2 ;
inc1*=2 ;

132
N1/=2 ;
}
}


Bài tập 6.5 Cho các mảng 2-D

X











1 1 1
1 1 1
0 0 0
và Y










1 1 1
1 1 0
1 0 0

Phát triển một chơng trình C thực hiện

1. Phát triển chơng trình C tính tích chập tuần hoàn giữa hai dãy trong
miền không gian.
2. Phát triển chơng trình C mà sẽ thêm các điểm 0 để mỗi chiều của
mảng có độ dài ít nhất là 3 + 3 1 = 5 và định dạng tích chập tuần

hoàn qua DFT.
3. Dùng chơng trình 6.6 để đa ra tích chập tuần hoàn qua 2-D FFT.
6.6 Hiển thị FFT
Nếu FFT của một ảnh trong trờng hợp tổng quát là một mảng của các số
phức đầy đủ, ngời ta thờng biểu diễn biên độ và pha của tần số của ảnh.
Hai yếu tố này biểu diễn tính chất của ảnh. Thông thờng biên độ tần số
đợc biểu diễn riêng lẻ và gọi là phổ biên độ. Mặc dù vậy, nh chúng ta đã
nghiên cứu, pha đóng vai trò quan trọng trong xử lý ảnh, và hợp không hợp
lý khi chỉ biểu diễn phổ biên độ của ảnh. Để biểu diễn phổ dới dạng ảnh,
tất cả các việc chúng ta cần phải làm là chia biên độ của FFT thành các giá
trị từ 0 đến 255 (cho ảnh 8 bit). Dù thế nào đi chăng nữa thì phổ của ảnh
cũng bị suy giảm rất nhanh khi tần số tăng lên. Vì vậy mà vùng tần số cao
sẽ trở nên lu mờ khi biểu diễn phổ dới dạng ảnh. Để giải quyết vấn đề này
chúng ta cần xử lý biên độ phổ một chút bằng hàm log. Hàm logarit sẽ sửa
độ khuếch đại, và thay thế cho hiển thị phổ |H(u,v)| chúng ta hiển thị:
D(u,v) = log
10
(1+|H(u,v)|) (6.67)
Biểu thức này cho ta giá trị zero khi D(u,v) = 0 hay |H(u,v)| = 0 và nh
vậy D(u,v) luôn luôn có giá trị dơng. Một chơng trình dùng để chuyển
đổi phổ thành dạng ảnh đợc cho ở chơng trình 6.7. Hình 6.13 giới thiệu

133
phổ của ảnh "IKRAM.IMG" trong hình 3.2a sau khi đợc chuyển đổi dùng
biểu thức (6.67). Điểm tần số (0,0) nằm ở trung tâm màn hình. Chú ý phổ
ảnh giảm xuống rất nhanh chóng khi tần số tăng lên.

Chơng trình 6.7 " DISP_FFT.C" Chơng trình dùng để đa ra một
file chứa phổ tần số trong dạng ảnh có thể hiển thị đợc.


/************************
* Program developed by: *
* M.A.Sid-Ahmed. *
* ver.1.0 1992. *
*************************/
/****************************************************
Program for calculating the magnitude of the 2-D FFT
given a file containing the complex values of the FFT
of an image. The result is placed in a form suitable
for display in image form and stored in an external
file. The mapping function D(u,v)=log10(1+ |(F(u,v)|)
is used.
******************************************************/

#include <stdio.h>
#include <conio.h>
#include <math.h>
#include <alloc.h>
#include <io.h>
#include <stdlib.h>

void main()
{
int i,j,k,N,NB1,NB2;
FILE *fptri, *fptro,*fptrt;
double nsq;
float max,min,xr,xi,scale;
float *buffi,*bufft;
char *buffo;
char file_name[14];



134

H×nh 6.13 Phæ cña "IKRAM.IMG"
clrscr();
printf(""Enter name of file containing FFT data > ");
scanf("%s",file_name);

fptri=fopen(file_name,"rb");
printf("Enter name of file for storing magnitude data -> ");
scanf("%s",file_name);
fptro=fopen(file_name,wb");
fptrt=fopen("temp.img","wb+");
nsq=(double)(filelength(fileno(fptri))/(2*sizeof(float)));
N=(int)(sprt(nsq));
max=0.0; min=1.0e9;

NB1=(N<<1)*sizeof(float);
NB2=NB1>>1;

buffi=(float *)malloc(NB1);
bufft=(float *)malloc(NB2);
buffo(char *)malloc(N*sizeof(char));

×