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

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

Đang tải... (xem toàn văn)

Thông tin tài liệu

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; . 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. 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 150 5 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. 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 150 5 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

Ngày đăng: 29/07/2014, 04:20

Từ khóa liên quan

Tài liệu cùng người dùng

Tài liệu liên quan