⭐ 欢迎来到虫虫下载站! | 📦 资源下载 📁 资源专辑 ℹ️ 关于我们
⭐ 虫虫下载站

📄 fft.cs

📁 2维fft用于数字图像处理 C# dll装配件
💻 CS
字号:
using System;
using System.Drawing;


namespace MyApp.FFT
{
	/// <summary>
	/// Summary description for Class1.
	/// </summary>
	/// 	
	public class complexd
	{
		public double real;
		public double im;
		public complexd(double x,double y)
		{
			real=x;
			im=y;
		}
	}
	public class MyFFT
	{
		private int myHeight;
		private int myWidth;
		private double[][] BitIll;

		public MyFFT()
		{
			InitialBitIll();
		}
		private void InitialBitIll()
		{
			BitIll=new double[5][];
			BitIll[0]=new double[5];
			BitIll[0][0]=0;
			BitIll[0][1]=1;
			BitIll[0][2]=2;
			BitIll[0][3]=1;
			BitIll[0][4]=0;
			BitIll[1]=new double[5];
			BitIll[1][0]=1;
			BitIll[1][1]=4;
			BitIll[1][2]=8;
			BitIll[1][3]=4;
			BitIll[1][4]=1;
			BitIll[2]=new double[5];
			BitIll[2][0]=2;
			BitIll[2][1]=8;
			BitIll[2][2]=16;
			BitIll[2][3]=8;
			BitIll[2][4]=2;
			BitIll[3]=new double[5];
			BitIll[3][0]=1;
			BitIll[3][1]=4;
			BitIll[3][2]=8;
			BitIll[3][3]=4;
			BitIll[3][4]=1;
			BitIll[4]=new double[5];
			BitIll[4][0]=0;
			BitIll[4][1]=1;
			BitIll[4][2]=2;
			BitIll[4][3]=1;
			BitIll[4][4]=0;
			for(int i=0;i<5;i++)
				for(int j=0;j<5;j++)
				BitIll[i][j]=BitIll[i][j]/80;		
		}
		private complexd[][] GetBits(Bitmap myBitmap)
		{
			int height=myBitmap.Height;
			int width=myBitmap.Width;
			int nHeight=(int) Math.Pow(2,Math.Ceiling(Math.Log(height,2)));
			int nWidth=(int) Math.Pow(2,Math.Ceiling(Math.Log(width,2)));
			myHeight=height;
			myWidth=width;
			complexd[][] array=new complexd[nHeight][];
			int i,j;
			for(i=0;i<=nHeight-1;i++)
			{
				array[i]=new complexd[nWidth];
				for(j=0;j<=nWidth-1;j++)
				{
					if(i<height&&j<width)
						array[i][j]=new complexd(myBitmap.GetPixel(j,i).R,0);
					else array[i][j]=new complexd(0,0);
				}
			}
			return array;
		}
		private double[][] GetArray(Bitmap myBitmap)
		{
			int height=myBitmap.Height;
			int width=myBitmap.Width;

			double[][] array=new double[height][];
			int i,j;
			for(i=0;i<=height-1;i++)
			{
				array[i]=new double[width];
				for(j=0;j<=width-1;j++)
				{
					array[i][j]=myBitmap.GetPixel(j,i).R;
				}
			}
			return array;
		}
		private complexd Mux(complexd x1,complexd x2)
		{		
			double real=x1.real*x2.real-x1.im*x2.im;
			double im=x1.real*x2.im+x1.im*x2.real;
			complexd x=new complexd(real,im);
			return x;
		}
		private complexd Add(complexd x1,complexd x2)
		{
			complexd x=new complexd(0,0);
			x.real=x1.real+x2.real;
			x.im=x1.im+x2.im;
			return x;
		}
		private complexd Del(complexd x1,complexd x2)
		{
			complexd x=new complexd(0,0);
			x.real=x1.real-x2.real;
			x.im=x1.im-x2.im;
			return x;
		}
		private void BitReverse(int[] br, int m,int N)
		{
			for(int i=0;i<N;i++)
			{
				br[i]=i;
			}
			int lh=N/2;
			int j=lh;
			int n1=N-2;

			for(int i=1;i<=n1;i++)
			{
				if(i<j)
				{
					int t=br[i];
					br[i]=br[j];
					br[j]=t;
				}
				int k=lh;
				while(j>=k)
				{
					j=j-k;
					k/=2;
				}
				j=j+k;
			}
		}
		private complexd WNR(int N,int r)
		{
			double x=Math.Cos(((-2)*r*Math.PI)/N);
			double y=Math.Sin(((-2)*r*Math.PI)/N);
			complexd c=new complexd(x,y);
			return c;
		}
		private complexd IWNR(int N,int r)
		{
			double x=Math.Cos(((-2)*r*Math.PI)/N);
			double y=Math.Sin(((-2)*r*Math.PI)/N);
			complexd c=new complexd(x,y);
			return c;
		}
		private complexd[][] Rotate(complexd[][] array)
		{
			int n=array[0].Length;
			complexd[][] ar=new complexd[n][];
			for(int i=0;i<n;i++)
			{
				ar[i]=new complexd[array.Length];
				for(int j=0;j<array.Length;j++)
					ar[i][j]=array[j][i];
			}
			return ar;
		}
		private void Operate(complexd[] array,int i,int j,complexd W)
		{
			complexd ii=array[i];
			complexd jj=array[j];
			array[i]=Add(ii,Mux(W,jj));
			array[j]=Del(ii,Mux(W,jj));
		}
		private void FFT1(complexd[] array,int sig)
		{
			int Width=array.Length;
			int bit=(int)Math.Ceiling(Math.Log(Width,2))+1;
			int[] br=new int[Width];
			BitReverse(br,bit,Width);
			complexd[] ar=(complexd[])array.Clone();
			for(int i=0;i<Width;i++)
				array[i]=ar[br[i]];
			int m=(int) Math.Log(Width,2);
			
			for(int l=1;l<=m;l++)
			{
				int b=(int)Math.Pow(2,l-1);
				for(int j=0;j<=b-1;j++)
				{
					int r=(int)Math.Pow(2,m-l)*j;
					for (int k=j;k<=Width-1;k+=(int)Math.Pow(2,l))
					{
						complexd w;
						if(sig==0)
							w=WNR(Width,r);
						else w=IWNR(Width,r);
						Operate(array,k,k+b,w);
					}
				}
			}
			if(sig==1)
			{
				for(int i=0;i<Width;i++)
				{
					array[i].real=array[i].real/Width;
					array[i].im=array[i].im/Width;
				}
			}
		}
		private complexd[][] FFT2(complexd[][] PicData,int sig)
		{
			int height=PicData.Length;
			int width=PicData[0].Length;
			for(int i=0;i<height;i++)
				FFT1(PicData[i],sig);	
			PicData=Rotate(PicData);
			for(int i=0;i<width;i++)
				FFT1(PicData[i],sig);	
			PicData=Rotate(PicData);
			return PicData;
		}
		private complexd[][] FFT2(Bitmap myBitmap)
		{
			complexd[][] PicData=GetBits(myBitmap);
			PicData=FFT2(PicData,0);
			PicData=Array2Array(PicData);
			return PicData;
		}
		public Bitmap Butterworth(Bitmap myBitmap,double pass)
		{
			complexd[][] PicData=FFT2(myBitmap);
			Bitmap m=new Bitmap(PicData.Length,PicData[0].Length);
			//Bitmap m=new Bitmap(myHeight,myWidth);
			double tp=TotalPower(PicData);
			int D0=0;
			int M=m.Height;
			int N=m.Width;
			while(true)
			{
				if(PartPower(PicData,D0)/tp>=pass)
					break;
				else D0++;
			}
			complexd[][] f=new complexd[M][];

			for(int i=0;i<M;i++)
			{
				f[i]=new complexd[N];
				for(int j=0;j<N;j++)
				{
					double bt=Math.Sqrt(Math.Pow(Math.Abs(i-M/2),2)+Math.Pow(Math.Abs(j-N/2),2))/D0;
					bt=1/(1+Math.Pow(bt,2));
					f[i][j]=new complexd(PicData[i][j].real*bt,PicData[i][j].im*bt);
				}
			}
			f=Array2Array(f);
			f=FFT2(f,1);
			for(int i=0;i<M;i++)
				for(int j=0;j<N;j++)
				{
					int c=(int)r2(f[i][j]);
					if(c>255) c=255;
					if(c<0) c=0;
					m.SetPixel(j,i,Color.FromArgb(c,c,c));
				}
			m.RotateFlip(RotateFlipType.Rotate180FlipNone);
			Rectangle rect=new Rectangle(0,0,myWidth,myHeight);
			m=m.Clone(rect,m.PixelFormat);
			return m;
		}

		public Bitmap IdealLowPass(Bitmap myBitmap,double pass)
		{
			complexd[][] PicData=FFT2(myBitmap);
			Bitmap m=new Bitmap(PicData.Length,PicData[0].Length);
			double tp=TotalPower(PicData);
			int D0=0;
			int M=PicData.Length;
			int N=PicData[0].Length;
			while(true)
			{
				if(PartPower(PicData,D0)/tp>=pass)
					break;
				else D0++;
			}
			complexd[][] f=new complexd[M][];

			for(int i=0;i<M;i++)
			{
				f[i]=new complexd[N];
				for(int j=0;j<N;j++)
				{
					f[i][j]=new complexd(0,0);
					if((Math.Pow(Math.Abs(i-M/2),2)+Math.Pow(Math.Abs(j-N/2),2))<=D0*D0)
					{
						f[i][j]=PicData[i][j];
					}
				}
			}
			f=Array2Array(f);
			f=FFT2(f,1);
			for(int i=0;i<m.Height;i++)
				for(int j=0;j<m.Width;j++)
				{
					int c=(int)r2(f[i][j]);
					if(c>255) c=255;
					if(c<0) c=0;
					m.SetPixel(j,i,Color.FromArgb(c,c,c));
				}
			m.RotateFlip(RotateFlipType.Rotate180FlipNone);
			Rectangle rect=new Rectangle(0,0,myWidth,myHeight);
			m=m.Clone(rect,m.PixelFormat);
			return m;
		}
		private double TotalPower(complexd[][] array)
		{
			double re=0;
			for(int i=0;i<array.Length;i++)
				for(int j=0;j<array[0].Length;j++)
				{
					double f=r2(array[i][j]);
					re+=f*f;
				}
			return re;
		}
		private double PartPower(complexd[][] array,int D0)
		{
			double re=0;
			int M=array.Length;
			int N=array[0].Length;
			for(int i=0;i<array.Length;i++)
				for(int j=0;j<array[0].Length;j++)
				{
					if((Math.Pow(Math.Abs(i-M/2),2)+Math.Pow(Math.Abs(j-N/2),2))<=D0*D0)
					{
						double f=r2(array[i][j]);
						re+=f*f;
					}
				}
			return re;
		}
		public complexd[][] Array2Array(complexd[][] array)
		{
			
			int M=array[0].Length;
			int N=array.Length;
			complexd[][] re=new complexd[N][];
			for(int i=0;i<N/2;i++)
			{
				re[i]=new complexd[M];
				for(int j=0;j<M/2;j++)//1
				{
					re[i][j]=array[i+N/2][j+M/2];
				}
				for(int j=M/2;j<M;j++)//2
				{
					re[i][j]=array[i+N/2][j-M/2];
				}
			}
			for(int i=N/2;i<N;i++)//4
			{
				re[i]=new complexd[M];
				for(int j=0;j<M/2;j++)
				{
					re[i][j]=array[i-N/2][j+M/2];
				}
				for(int j=M/2;j<M;j++)
				{
					re[i][j]=array[i-N/2][j-M/2];
				}
			}
			return re;
		}
		
		private double r2(complexd c)
		{
			return Math.Sqrt(c.real*c.real+c.im*c.im);
		}
		public Bitmap GetFFTPic(Bitmap myBitmap)
		{
			complexd[][] PicData=GetBits(myBitmap);
			PicData=FFT2(PicData,0);
			complexd[][] PicData1=Array2Array(PicData);
			double[][] data=GetPowerData(PicData1);
			double[] maxmin=GetMaxMinData(data);
			maxmin[0]=(int)Math.Log(1+maxmin[0],Math.E);
			maxmin[1]=(int)Math.Log(1+maxmin[1],Math.E);
			Bitmap m=new Bitmap(PicData1.Length,PicData1[0].Length);
			for(int i=0;i<m.Height;i++)
				for(int j=0;j<m.Width;j++)
				{
					int c=(255/(int)(maxmin[0]-maxmin[1]))*((int)Math.Log(1+data[i][j],Math.E));
					if(c>255) c=255;
					if(c<0) c=0;
					m.SetPixel(j,i,Color.FromArgb(c,c,c));
				}
			return m;
		}
		private double[][] GetPowerData(complexd[][] array)
		{
			double[][] re=new double[array.Length][];
			for(int i=0;i<array.Length;i++)
			{
				re[i]=new double[array[0].Length];
				for(int j=0;j<array[0].Length;j++)
				{
					re[i][j]=r2(array[i][j]);
				}
			}
			return re;
		}
		private double[] GetMaxMinData(double[][] array)
		{
			double[] re=new double[2];
			re[0]=array[0][0];
			re[1]=array[0][0];
			for(int i=0;i<array.Length;i++)
				for(int j=0;j<array[0].Length;j++)
				{
					if(array[i][j]>re[0]) re[0]=array[i][j];
					else re[1]=array[i][j];
				}
			return re;		
		}
		public double GetError(Bitmap myBitmap1,Bitmap myBitmap2)
		{
			double[][] array1=GetArray(myBitmap1);
			double[][] array2=GetArray(myBitmap2);
			double re=0;
			for(int i=0;i<=array1.Length-1;i++)
				for(int j=0;j<=array1[0].Length-1;j++)
				{
					re+=Math.Pow((array1[i][j]-array2[i][j]),2);
				}
			re=re/(array1.Length*array1[0].Length);
			re=Math.Sqrt(re);
			return re;
		}
		
		private double GetError(double[][] array1,double[][] array2)
		{
			double re=0;
			for(int i=0;i<=array1.Length-1;i++)
				for(int j=0;j<=array1[0].Length-1;j++)
				{
					re+=Math.Pow((array1[i][j]-array2[i][j]),2);
				}
			re=re/(array1.Length*array1[0].Length);
			re=Math.Sqrt(re);
			return re;
		}
		


	}
	
}

⌨️ 快捷键说明

复制代码 Ctrl + C
搜索代码 Ctrl + F
全屏模式 F11
切换主题 Ctrl + Shift + D
显示快捷键 ?
增大字号 Ctrl + =
减小字号 Ctrl + -