fft.cs
上传用户:c6x6r6
上传日期:2022-07-31
资源大小:515k
文件大小:11k
源码类别:

波变换

开发平台:

Visual Basic

  1. using System;
  2. using System.Drawing;
  3. namespace WindowsFormsApplication2
  4. {
  5. /// <summary>
  6. /// Summary description for Class1.
  7. /// </summary>
  8. /// 
  9. public class complexd
  10. {
  11. public double real;
  12. public double im;
  13. public complexd(double x,double y)
  14. {
  15. real=x;
  16. im=y;
  17. }
  18. }
  19. public class MyFFT
  20. {
  21. private int myHeight;
  22. private int myWidth;
  23. private double[][] BitIll;
  24. public MyFFT()
  25. {
  26. InitialBitIll();
  27. }
  28. private void InitialBitIll()
  29. {
  30. BitIll=new double[5][];
  31. BitIll[0]=new double[5];
  32. BitIll[0][0]=0;
  33. BitIll[0][1]=1;
  34. BitIll[0][2]=2;
  35. BitIll[0][3]=1;
  36. BitIll[0][4]=0;
  37. BitIll[1]=new double[5];
  38. BitIll[1][0]=1;
  39. BitIll[1][1]=4;
  40. BitIll[1][2]=8;
  41. BitIll[1][3]=4;
  42. BitIll[1][4]=1;
  43. BitIll[2]=new double[5];
  44. BitIll[2][0]=2;
  45. BitIll[2][1]=8;
  46. BitIll[2][2]=16;
  47. BitIll[2][3]=8;
  48. BitIll[2][4]=2;
  49. BitIll[3]=new double[5];
  50. BitIll[3][0]=1;
  51. BitIll[3][1]=4;
  52. BitIll[3][2]=8;
  53. BitIll[3][3]=4;
  54. BitIll[3][4]=1;
  55. BitIll[4]=new double[5];
  56. BitIll[4][0]=0;
  57. BitIll[4][1]=1;
  58. BitIll[4][2]=2;
  59. BitIll[4][3]=1;
  60. BitIll[4][4]=0;
  61. for(int i=0;i<5;i++)
  62. for(int j=0;j<5;j++)
  63. BitIll[i][j]=BitIll[i][j]/80;
  64. }
  65. private complexd[][] GetBits(Bitmap myBitmap)
  66. {
  67. int height=myBitmap.Height;
  68. int width=myBitmap.Width;
  69. int nHeight=(int) Math.Pow(2,Math.Ceiling(Math.Log(height,2)));
  70. int nWidth=(int) Math.Pow(2,Math.Ceiling(Math.Log(width,2)));
  71. myHeight=height;
  72. myWidth=width;
  73. complexd[][] array=new complexd[nHeight][];
  74. int i,j;
  75. for(i=0;i<=nHeight-1;i++)
  76. {
  77. array[i]=new complexd[nWidth];
  78. for(j=0;j<=nWidth-1;j++)
  79. {
  80. if(i<height&&j<width)
  81. array[i][j]=new complexd(myBitmap.GetPixel(j,i).R,0);
  82. else array[i][j]=new complexd(0,0);
  83. }
  84. }
  85. return array;
  86. }
  87. private double[][] GetArray(Bitmap myBitmap)
  88. {
  89. int height=myBitmap.Height;
  90. int width=myBitmap.Width;
  91. double[][] array=new double[height][];
  92. int i,j;
  93. for(i=0;i<=height-1;i++)
  94. {
  95. array[i]=new double[width];
  96. for(j=0;j<=width-1;j++)
  97. {
  98. array[i][j]=myBitmap.GetPixel(j,i).R;
  99. }
  100. }
  101. return array;
  102. }
  103. private complexd Mux(complexd x1,complexd x2)
  104. {
  105. double real=x1.real*x2.real-x1.im*x2.im;
  106. double im=x1.real*x2.im+x1.im*x2.real;
  107. complexd x=new complexd(real,im);
  108. return x;
  109. }
  110. private complexd Add(complexd x1,complexd x2)
  111. {
  112. complexd x=new complexd(0,0);
  113. x.real=x1.real+x2.real;
  114. x.im=x1.im+x2.im;
  115. return x;
  116. }
  117. private complexd Del(complexd x1,complexd x2)
  118. {
  119. complexd x=new complexd(0,0);
  120. x.real=x1.real-x2.real;
  121. x.im=x1.im-x2.im;
  122. return x;
  123. }
  124. private void BitReverse(int[] br, int m,int N)
  125. {
  126. for(int i=0;i<N;i++)
  127. {
  128. br[i]=i;
  129. }
  130. int lh=N/2;
  131. int j=lh;
  132. int n1=N-2;
  133. for(int i=1;i<=n1;i++)
  134. {
  135. if(i<j)
  136. {
  137. int t=br[i];
  138. br[i]=br[j];
  139. br[j]=t;
  140. }
  141. int k=lh;
  142. while(j>=k)
  143. {
  144. j=j-k;
  145. k/=2;
  146. }
  147. j=j+k;
  148. }
  149. }
  150. private complexd WNR(int N,int r)
  151. {
  152. double x=Math.Cos(((-2)*r*Math.PI)/N);
  153. double y=Math.Sin(((-2)*r*Math.PI)/N);
  154. complexd c=new complexd(x,y);
  155. return c;
  156. }
  157. private complexd IWNR(int N,int r)
  158. {
  159. double x=Math.Cos(((-2)*r*Math.PI)/N);
  160. double y=Math.Sin(((-2)*r*Math.PI)/N);
  161. complexd c=new complexd(x,y);
  162. return c;
  163. }
  164. private complexd[][] Rotate(complexd[][] array)
  165. {
  166. int n=array[0].Length;
  167. complexd[][] ar=new complexd[n][];
  168. for(int i=0;i<n;i++)
  169. {
  170. ar[i]=new complexd[array.Length];
  171. for(int j=0;j<array.Length;j++)
  172. ar[i][j]=array[j][i];
  173. }
  174. return ar;
  175. }
  176. private void Operate(complexd[] array,int i,int j,complexd W)
  177. {
  178. complexd ii=array[i];
  179. complexd jj=array[j];
  180. array[i]=Add(ii,Mux(W,jj));
  181. array[j]=Del(ii,Mux(W,jj));
  182. }
  183. private void FFT1(complexd[] array,int sig)
  184. {
  185. int Width=array.Length;
  186. int bit=(int)Math.Ceiling(Math.Log(Width,2))+1;
  187. int[] br=new int[Width];
  188. BitReverse(br,bit,Width);
  189. complexd[] ar=(complexd[])array.Clone();
  190. for(int i=0;i<Width;i++)
  191. array[i]=ar[br[i]];
  192. int m=(int) Math.Log(Width,2);
  193. for(int l=1;l<=m;l++)
  194. {
  195. int b=(int)Math.Pow(2,l-1);
  196. for(int j=0;j<=b-1;j++)
  197. {
  198. int r=(int)Math.Pow(2,m-l)*j;
  199. for (int k=j;k<=Width-1;k+=(int)Math.Pow(2,l))
  200. {
  201. complexd w;
  202. if(sig==0)
  203. w=WNR(Width,r);
  204. else w=IWNR(Width,r);
  205. Operate(array,k,k+b,w);
  206. }
  207. }
  208. }
  209. if(sig==1)
  210. {
  211. for(int i=0;i<Width;i++)
  212. {
  213. array[i].real=array[i].real/Width;
  214. array[i].im=array[i].im/Width;
  215. }
  216. }
  217. }
  218. private complexd[][] FFT2(complexd[][] PicData,int sig)
  219. {
  220. int height=PicData.Length;
  221. int width=PicData[0].Length;
  222. for(int i=0;i<height;i++)
  223. FFT1(PicData[i],sig);
  224. PicData=Rotate(PicData);
  225. for(int i=0;i<width;i++)
  226. FFT1(PicData[i],sig);
  227. PicData=Rotate(PicData);
  228. return PicData;
  229. }
  230. private complexd[][] FFT2(Bitmap myBitmap)
  231. {
  232. complexd[][] PicData=GetBits(myBitmap);
  233. PicData=FFT2(PicData,0);
  234. PicData=Array2Array(PicData);
  235. return PicData;
  236. }
  237. public Bitmap Butterworth(Bitmap myBitmap,double pass)
  238. {
  239. complexd[][] PicData=FFT2(myBitmap);
  240. Bitmap m=new Bitmap(PicData.Length,PicData[0].Length);
  241. //Bitmap m=new Bitmap(myHeight,myWidth);
  242. double tp=TotalPower(PicData);
  243. int D0=0;
  244. int M=m.Height;
  245. int N=m.Width;
  246. while(true)
  247. {
  248. if(PartPower(PicData,D0)/tp>=pass)
  249. break;
  250. else D0++;
  251. }
  252. complexd[][] f=new complexd[M][];
  253. for(int i=0;i<M;i++)
  254. {
  255. f[i]=new complexd[N];
  256. for(int j=0;j<N;j++)
  257. {
  258. double bt=Math.Sqrt(Math.Pow(Math.Abs(i-M/2),2)+Math.Pow(Math.Abs(j-N/2),2))/D0;
  259. bt=1/(1+Math.Pow(bt,2));
  260. f[i][j]=new complexd(PicData[i][j].real*bt,PicData[i][j].im*bt);
  261. }
  262. }
  263. f=Array2Array(f);
  264. f=FFT2(f,1);
  265. for(int i=0;i<M;i++)
  266. for(int j=0;j<N;j++)
  267. {
  268. int c=(int)r2(f[i][j]);
  269. if(c>255) c=255;
  270. if(c<0) c=0;
  271. m.SetPixel(j,i,Color.FromArgb(c,c,c));
  272. }
  273. m.RotateFlip(RotateFlipType.Rotate180FlipNone);
  274. Rectangle rect=new Rectangle(0,0,myWidth,myHeight);
  275. m=m.Clone(rect,m.PixelFormat);
  276. return m;
  277. }
  278. public Bitmap IdealLowPass(Bitmap myBitmap,double pass)
  279. {
  280. complexd[][] PicData=FFT2(myBitmap);
  281. Bitmap m=new Bitmap(PicData.Length,PicData[0].Length);
  282. double tp=TotalPower(PicData);
  283. int D0=0;
  284. int M=PicData.Length;
  285. int N=PicData[0].Length;
  286. while(true)
  287. {
  288. if(PartPower(PicData,D0)/tp>=pass)
  289. break;
  290. else D0++;
  291. }
  292. complexd[][] f=new complexd[M][];
  293. for(int i=0;i<M;i++)
  294. {
  295. f[i]=new complexd[N];
  296. for(int j=0;j<N;j++)
  297. {
  298. f[i][j]=new complexd(0,0);
  299. if((Math.Pow(Math.Abs(i-M/2),2)+Math.Pow(Math.Abs(j-N/2),2))<=D0*D0)
  300. {
  301. f[i][j]=PicData[i][j];
  302. }
  303. }
  304. }
  305. f=Array2Array(f);
  306. f=FFT2(f,1);
  307. for(int i=0;i<m.Height;i++)
  308. for(int j=0;j<m.Width;j++)
  309. {
  310. int c=(int)r2(f[i][j]);
  311. if(c>255) c=255;
  312. if(c<0) c=0;
  313. m.SetPixel(j,i,Color.FromArgb(c,c,c));
  314. }
  315. m.RotateFlip(RotateFlipType.Rotate180FlipNone);
  316. Rectangle rect=new Rectangle(0,0,myWidth,myHeight);
  317. m=m.Clone(rect,m.PixelFormat);
  318. return m;
  319. }
  320. private double TotalPower(complexd[][] array)
  321. {
  322. double re=0;
  323. for(int i=0;i<array.Length;i++)
  324. for(int j=0;j<array[0].Length;j++)
  325. {
  326. double f=r2(array[i][j]);
  327. re+=f*f;
  328. }
  329. return re;
  330. }
  331. private double PartPower(complexd[][] array,int D0)
  332. {
  333. double re=0;
  334. int M=array.Length;
  335. int N=array[0].Length;
  336. for(int i=0;i<array.Length;i++)
  337. for(int j=0;j<array[0].Length;j++)
  338. {
  339. if((Math.Pow(Math.Abs(i-M/2),2)+Math.Pow(Math.Abs(j-N/2),2))<=D0*D0)
  340. {
  341. double f=r2(array[i][j]);
  342. re+=f*f;
  343. }
  344. }
  345. return re;
  346. }
  347. public complexd[][] Array2Array(complexd[][] array)
  348. {
  349. int M=array[0].Length;
  350. int N=array.Length;
  351. complexd[][] re=new complexd[N][];
  352. for(int i=0;i<N/2;i++)
  353. {
  354. re[i]=new complexd[M];
  355. for(int j=0;j<M/2;j++)//1
  356. {
  357. re[i][j]=array[i+N/2][j+M/2];
  358. }
  359. for(int j=M/2;j<M;j++)//2
  360. {
  361. re[i][j]=array[i+N/2][j-M/2];
  362. }
  363. }
  364. for(int i=N/2;i<N;i++)//4
  365. {
  366. re[i]=new complexd[M];
  367. for(int j=0;j<M/2;j++)
  368. {
  369. re[i][j]=array[i-N/2][j+M/2];
  370. }
  371. for(int j=M/2;j<M;j++)
  372. {
  373. re[i][j]=array[i-N/2][j-M/2];
  374. }
  375. }
  376. return re;
  377. }
  378. private double r2(complexd c)
  379. {
  380. return Math.Sqrt(c.real*c.real+c.im*c.im);
  381. }
  382. public Bitmap GetFFTPic(Bitmap myBitmap)
  383. {
  384. complexd[][] PicData=GetBits(myBitmap);
  385. PicData=FFT2(PicData,0);
  386. complexd[][] PicData1=Array2Array(PicData);
  387. double[][] data=GetPowerData(PicData1);
  388. double[] maxmin=GetMaxMinData(data);
  389. maxmin[0]=(int)Math.Log(1+maxmin[0],Math.E);
  390. maxmin[1]=(int)Math.Log(1+maxmin[1],Math.E);
  391. Bitmap m=new Bitmap(PicData1.Length,PicData1[0].Length);
  392. for(int i=0;i<m.Height;i++)
  393. for(int j=0;j<m.Width;j++)
  394. {
  395. int c=(255/(int)(maxmin[0]-maxmin[1]))*((int)Math.Log(1+data[i][j],Math.E));
  396. if(c>255) c=255;
  397. if(c<0) c=0;
  398. m.SetPixel(j,i,Color.FromArgb(c,c,c));
  399. }
  400. return m;
  401. }
  402. private double[][] GetPowerData(complexd[][] array)
  403. {
  404. double[][] re=new double[array.Length][];
  405. for(int i=0;i<array.Length;i++)
  406. {
  407. re[i]=new double[array[0].Length];
  408. for(int j=0;j<array[0].Length;j++)
  409. {
  410. re[i][j]=r2(array[i][j]);
  411. }
  412. }
  413. return re;
  414. }
  415. private double[] GetMaxMinData(double[][] array)
  416. {
  417. double[] re=new double[2];
  418. re[0]=array[0][0];
  419. re[1]=array[0][0];
  420. for(int i=0;i<array.Length;i++)
  421. for(int j=0;j<array[0].Length;j++)
  422. {
  423. if(array[i][j]>re[0]) re[0]=array[i][j];
  424. else re[1]=array[i][j];
  425. }
  426. return re;
  427. }
  428. public double GetError(Bitmap myBitmap1,Bitmap myBitmap2)
  429. {
  430. double[][] array1=GetArray(myBitmap1);
  431. double[][] array2=GetArray(myBitmap2);
  432. double re=0;
  433. for(int i=0;i<=array1.Length-1;i++)
  434. for(int j=0;j<=array1[0].Length-1;j++)
  435. {
  436. re+=Math.Pow((array1[i][j]-array2[i][j]),2);
  437. }
  438. re=re/(array1.Length*array1[0].Length);
  439. re=Math.Sqrt(re);
  440. return re;
  441. }
  442. private double GetError(double[][] array1,double[][] array2)
  443. {
  444. double re=0;
  445. for(int i=0;i<=array1.Length-1;i++)
  446. for(int j=0;j<=array1[0].Length-1;j++)
  447. {
  448. re+=Math.Pow((array1[i][j]-array2[i][j]),2);
  449. }
  450. re=re/(array1.Length*array1[0].Length);
  451. re=Math.Sqrt(re);
  452. return re;
  453. }
  454. }
  455. }