fft.cpp
上传用户:dcqhjx
上传日期:2022-08-01
资源大小:2k
文件大小:6k
源码类别:

数学计算

开发平台:

C++ Builder

  1. #include "stdafx.h"
  2. #include "fft.h"
  3. #include "Complex.h"
  4. #include<math.h>
  5. #define M_PI 3.141592654 // The mathematical constant for PI
  6. void FFT1D(Complex<double> *fx, Complex<double> *Fu, int twoK, int stride) {
  7. // This function performs the 1D fast fourier transform from input data fx,
  8. // it outputs the frequency coefficients in the array Fu.
  9. // Input: fx - pointer to an array of data in complex number format
  10. // twoK - the total number of data in fx
  11. // stride - the number of data to be skipped when reading the next data in fx
  12. // e.g. fx = [0 1 2 3 4 5 6 7 8 9 10 11 12 13 14 15], twoK = 4
  13. // if stride = 1, the data to be processed is [0 1 2 3]
  14. // if stride = 2, the data to be processed is [0 2 4 8]
  15. // if stride = 4, the data to be processed is [0 4 8 12]
  16. // Output: Fu - pointer to an array buffer for transformed cofficients in complex number format
  17. // Code to be added here ...
  18. Complex<double> *F_even,*F_odd, e;
  19. int u,K;
  20. if(twoK==2)
  21. {
  22. Fu[0]=(fx[0]+fx[1*stride])*0.5;
  23. Fu[1]=(fx[0]-fx[1*stride])*0.5;
  24. return;
  25. }
  26. K=twoK/2;
  27. F_even=new Complex<double>[K];
  28. F_odd=new Complex<double>[K];
  29. FFT1D(fx,F_even,K,2*stride);
  30. FFT1D(fx+stride, F_odd, K, 2*stride);
  31. for(u=0;u<K;u++)
  32. {
  33. e.Exp(-M_PI*((double)u/(double)K));
  34. Fu[u]=(F_even[u]+e*F_odd[u])*0.5;
  35. Fu[u+K]=(F_even[u]-e*F_odd[u])*0.5;
  36. }
  37. delete []F_even;
  38. delete []F_odd;
  39. }
  40. void FFT2D(Complex<double> *f, Complex<double> *F, int width, int height) {
  41. // This function performs the 2D Fast Fourier Transform for a given image f
  42. // You can safely assume that the width = 2^m, height = 2^n for some integers m and n,
  43. // and the input image are already properly padded
  44. // Input: f - An 2D Image represented in Complex Numbers
  45. // Output: F - The transformed coefficients, also represented in Complex Numbers
  46. // Code to be added here ...
  47. int i,j;
  48. Complex<double> **s = new Complex<double>*[height];
  49. for(int j=0; j<height; j++){
  50.    s[j] =new Complex<double>[width];
  51. }
  52. for(j=0;j<height;j++)
  53. for(i=0;i<width;i++)
  54. s[j][i]=f[(j*width)+i];
  55. Complex<double> *row;
  56. row=new Complex<double>[width];
  57. for(j=0;j<height;j++)
  58. {
  59. for(i=0;i<width;i++)
  60. row[i]=s[j][i];
  61. FFT1D(row,row,width,1);
  62. for(i=0;i<width;i++)
  63. s[j][i]=row[i];
  64. }
  65. Complex<double> *col;
  66. col=new Complex<double>[height];
  67. for(i=0;i<width;i++)
  68. {
  69. for(j=0;j<height;j++)
  70. col[j]=s[j][i];
  71. FFT1D(col,col,height,1);
  72. for(j=0;j<height;j++)
  73. s[j][i]=col[j];
  74. }
  75. for(j=0;j<height;j++)
  76. for(i=0;i<width;i++)
  77. F[(j*width)+i]=s[j][i];
  78. delete []row;
  79. delete []col;
  80. delete s;
  81. }
  82. void IFFT2D(Complex<double> *F, Complex<double> *f, int width, int height) {
  83. // This function performs the Inverse 2D Fast Fourier Transform for a given image f (in one color channel R, G or B)
  84. // You can safely assume that the width = 2^m, height = 2^n for some integers m and n
  85. // Input: F - The transformed coefficients, also represented in Complex Numbers
  86. // Output: f - An 2D Image represented in Complex Numbers
  87. // Code to be added here ...
  88. int i;
  89. for(i=0;i<width*height;i++)
  90. {
  91. F[i]=Complex<double>(F[i].Real(),-F[i].Imag());
  92. }
  93. FFT2D(F,f,width,height);
  94. for(i=0;i<width*height;i++)
  95. {
  96. f[i]=Complex<double>(f[i].Real(),-f[i].Imag());
  97. f[i]=f[i]*width*height;
  98. }
  99. }
  100. void ScaleFFT(Complex<double> *F, Complex<double> *PS, int width, int height) {
  101. // This function takes a 2D coefficients in F, and compute the power spectrum of F.
  102. // This function also scales the power spectrum, such that its values lie within the range [0, 255]
  103. // for proper display.
  104. // Input: F - 2D coefficients of the FFT image
  105. // width - width of the F
  106. // height - height of the F
  107. // Output: PS - scaled power spectrum (with value normalized to the range of [0, 255])
  108. // Code to be added here ...
  109. int i;
  110. double min,max,diff;
  111. for(i=0;i<width*height;i++)
  112. {
  113. PS[i] = Complex <double>(pow((F[i].Mod()*F[i].Mod()),0.2));
  114. }
  115. min=max=PS[0].Real();
  116. for(i=1;i<width*height;i++)
  117. {
  118. if(min > PS[i].Real())
  119. min = PS[i].Real();
  120. if(max < PS[i].Real())
  121. max =PS[i].Real();
  122. }
  123. diff = max-min;
  124. for(i=0;i<width*height;i++)
  125. {
  126. PS[i] = Complex <double>(((PS[i].Real()-min)/diff)*255.0);
  127. }
  128. }
  129. void BLPF(Complex<double> *F, Complex<double> *LF, int width, int height) {
  130. // This function takes a 2D coefficients in F, and perform a second other ButterWorth
  131. // low pass filtering on the coefficents. The filtered coefficients are put back into LF
  132. // Input: F - 2D coefficients of the FFT image
  133. // width - width of the F
  134. // height - height of the F
  135. // Output: LF - ButterWorth filtered coefficients
  136. // The coded below is a low pass filter implementation, however, it cannot filter the image
  137. // properly. Modify the code below such that the filter becomes a butterworth filter of order 2.
  138. /*int i, j ;
  139. int Df ;
  140. int centerX, centerY ;
  141. centerX = width / 2 ;
  142. centerY = height / 2 ;
  143. Df = 32 ;
  144. for(j = 0; j < height; j++) {
  145. for(i = 0; i < width; i++) {
  146. if((i - centerX) * (i - centerX) + (j - centerY) * (j - centerY) > Df * Df) {
  147. LF[i + j * width] = 0.0 ;
  148. } else {
  149. LF[i + j * width] = F[i + j * width] ;
  150. }
  151. }
  152. }*/
  153. int i, j,D;
  154. double T,H;
  155. int Df ;
  156. int centerX, centerY ;
  157. centerX = width / 2 ;
  158. centerY = height / 2 ;
  159. Df = 32 ;
  160. for(j = 0; j < height; j++) {
  161. for(i = 0; i < width; i++) {
  162. D=(i - centerX) * (i - centerX) + (j - centerY) * (j - centerY);
  163. T=(D/(Df*Df))*(D/(Df*Df));
  164. H=1/(1+T);
  165. LF[i+j*width]=F[i+j*width]*H;
  166. }
  167. }
  168. }