Giáo trình xử lý ảnh y tế Tập 1b P15 pptx

8 231 0
Giáo trình xử lý ảnh y tế Tập 1b P15 pptx

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

Thông tin tài liệu

92 #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); } /* Allocating memory for bit reversal LUT. */ L=(unsigned int *)malloc(N*sizeof(unsigned int)); 93 /* 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]*/ { 94 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; 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) 95 { /* 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++) { 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++) { 96 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 lưu 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à lưu 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 nhưng 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: 97 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) 98 .)()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 lưu đồ 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. 99 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; Hình 6.7 N = 4, phân chia miền tần số FFT. ip= (N>>1) ; kk=1; incr=N; for(iter=0; iter<m; iter++) 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 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 n W 8n W 4n W 2n W  . 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 nhưng lần n y ta bắt đầu từ d y ra. Chương trình n y bao gồm các. 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. Chú ý rằng trong chương trình 6.1 chúng ta giả thiết là dữ liệu được lưu 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

Ngày đăng: 10/07/2014, 22:20

Từ khóa liên quan

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

Tài liệu liên quan