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

📄 fourier.cpp

📁 一个Fourier变换的小程序;算法简单实用。
💻 CPP
📖 第 1 页 / 共 2 页
字号:
// Fourier.cpp: implementation of the CFourier class.
//
//////////////////////////////////////////////////////////////////////

#include "stdafx.h"

#include "Fourier.h"

#ifdef _DEBUG
#undef THIS_FILE
static char THIS_FILE[]=__FILE__;
#define new DEBUG_NEW
#endif

//////////////////////////////////////////////////////////////////////
// Construction/Destruction
//////////////////////////////////////////////////////////////////////

CFourier::CFourier()
{
	w=0;
	h=0;
}

CFourier::~CFourier()
{

}

///////////////////////////////////////////////
//函数定义部分
///////////////////////////////////////////////

/************************************************************************
 *	函数名:
 *		按频率抽取的快速付立叶变换,FFT();
 *	参数:
 *		complex<float>*TD   -指向时域值的指针;
 *		complex<float>*FD   -指向频域值的指针;
 *		int r				-2的幂;
 *	说明:
 *		该函数用于实现快速傅立叶变换;
 *************************************************************************/
void CFourier::FFT(complex<float>*TD,int r)
{
	//傅立叶变换点数
	long count;
	//循环变量
	int i,j,k;
	//中间变量
	int bfsize,p;
	//角度
	double angle;
	//复数变量指针
	complex<float>*W;
	complex<float>*X1;
	complex<float>*X2;
	complex<float>*X;
	//计算傅立叶变化点数
	count=1<<r;
	//分配运算所需内存
	W=new complex<float>[count/2];
	X1=new complex<float>[count];
	X2=new complex<float>[count];
	//计算加权系数
	for(i=0;i<count/2;i++)
	{
		angle=-i*PI*2/count;
		W[i]=complex<float>(cos(angle),sin(angle));
	}
	//将时域点写入X1
	memcpy(X1,TD,sizeof(complex<float>)*count);
	//采用蝶形算法作快速傅立叶变换
	for(k=0;k<r;k++)
	{
		for(j=0;j<1<<k;j++)
		{
			bfsize=1<<(r-k);
			for(i=0;i<bfsize/2;i++)
			{
				p=j*bfsize;
				X2[i+p]=X1[i+p]+X1[i+p+bfsize/2];							//?
				X2[i+p+bfsize/2]=(X1[i+p]-X1[i+p+bfsize/2])*W[i*(1<<k)];	//?
			}
		}
		X=X1;
		X1=X2;
		X2=X;
	}

	//对频率域的值重新排序
	for(j=0;j<count;j++)
	{
		p=0;
		for(i=0;i<r;i++)
		{
			if(j&(1<<i))
			{
				p+=1<<(r-i-1);
			}
		}
//		FD[j]=X1[p];
		TD[j]=X1[p];
	}
	//释放内存
	delete[] W;
	delete[] X1;
	delete[] X2;
}

/***************************************************************
 *	函数名称:
 *		IFFT();
 *	参数:
 *		complex<float>*FD	-指向频率域的指针;
 *		complex<float>*TD	-指向时间域的指针;
 *		int r				-2的幂;
 *	说明:
 *		该函数用来实现快速傅立叶反变换;
 ****************************************************************/
void CFourier::IFFT(complex<float>*FD,int r)
{
	//傅立叶变换点数
	long count;
	//循环变量
	int i;
	complex<float>*X;
	//计算傅立叶变换点数
	count= 1<<r;
	//分配运算所需存储器
	X=new complex<float>[count];
	//将频率点写入X
	memcpy(X,FD,sizeof(complex<float>)*count);
	//计算频率的共轭
	for(i=0;i<count;i++)
	{
		X[i]=complex<float>(X[i].real(),-X[i].imag());
	}
	//调用快速傅立叶变换
	FFT(X,r);
	//求时域点的共轭
	for(i=0;i<count;i++)
	{
		FD[i]=complex<float>(X[i].real()/count,-X[i].imag()/count);
	}
	delete[] X;
}

//short数据的fft
BOOL CFourier::Fourier1(short* TDdata,long lWidth,complex<float>*FDresult)
{
	float tempD;
	long i;
	int wp;
	//计算进行傅立叶变换的宽度和高度(2的整数次方),高度要>lWidth
	w=1;	
	wp=0;
	while(w<lWidth)
	{
		w*=2;
		wp++;
	}
	//
	memset(FDresult,0,sizeof(complex<float>)*w);	//设置为0
	for(i=0;i<lWidth;i++)//行
	{
		tempD=*(TDdata+i);
		FDresult[i]=complex<float>(tempD,0);	
	}		
	FFT(FDresult,wp);
	//
	return true;
}

//int数据的fft
BOOL CFourier::Fourier1(int* TDdata,long lWidth,complex<float>*FDresult)
{
	float tempD;
	long i;
	int wp;

	w=1;	
	wp=0;
	while(w<lWidth)//计算进行傅立叶变换的宽度和高度(2的整数次方),高度要>lWidth
	{
		w*=2;
		wp++;
	}
	//
	memset(FDresult,0,sizeof(complex<float>)*w);	//设置为0
	for(i=0;i<lWidth;i++)//行
	{
		tempD=*(TDdata+i);
		FDresult[i]=complex<float>(tempD,0);	
	}		
	FFT(FDresult,wp);
	
	return true;
}
//
/*******************************************************************
 *	函数名:
 *		Fourier1()
 *	参数:
 *		lpImageData		时域数据
 *		lWidth			数据长度
 *		FDresult		频域结果
 *	说明:
 *		一维float数据的fourier变换
 *******************************************************************/
BOOL CFourier::Fourier1(float* TDdata,long lWidth,complex<float>*FDresult)
{
	float tempD;
	long i;
	int wp;

	w=1;	
	wp=0;
	while(w<lWidth)//计算进行傅立叶变换的宽度和高度(2的整数次方),高度要>lWidth
	{
		w*=2;
		wp++;
	}
	//	
	memset(FDresult,0,sizeof(complex<float>)*w);	//设置为0
	for(i=0;i<lWidth;i++)//行
	{
		tempD=*(TDdata+i);
		FDresult[i]=complex<float>(tempD,0);	
	}		
	FFT(FDresult,wp);
	
	return true;
}

/*******************************************************************
 *	函数名:
 *		Fourier1()
 *	参数:
 *		lpImageData		时域数据
 *		lWidth			数据长度
 *		FDresult		频域结果
 *	说明:
 *		一维complex<float>数据的fourier变换
 *******************************************************************/
BOOL CFourier::Fourier1(complex<float>*TDdata,long lWidth,complex<float>*FDresult)
{
	long i;
	int wp;
	//
	w=1;	
	wp=0;
	while(w<lWidth)//计算进行傅立叶变换的宽度和高度(2的整数次方),高度要>lWidth
	{
		w*=2;
		wp++;
	}
	//	
	memset(FDresult,0,sizeof(complex<float>)*w);	//设置为0
	for(i=0;i<lWidth;i++)//行
	{
		FDresult[i]=TDdata[i];
	}
	FFT(FDresult,wp);
	//
	return true;
}
/*******************************************************************
 *	函数名:
 *		InFourier1()
 *	参数:
 *		FDdata			频域数据
 *		lWidth			数据长度
 *		TDresult		时域结果
 *	说明:
 *		一维complex<float>数据的infourier变换
 *******************************************************************/
BOOL CFourier::InFourier1(complex<float>*FDdata,long lWidth,complex<float>*TDresult)
{
	long i;

	int wp=0;
	w=1;

	while(w<lWidth)
	{
		w*=2;
		wp++;
	}
	//
	memset(TDresult,0,sizeof(complex<float>)*w);	//设置为0
	for(i=0;i<lWidth;i++)
	{	
		TDresult[i]=FDdata[i];
	}
	//
	IFFT(TDresult,wp);
	//
	return true;
}

//------------------------------------------------------------------------
//二维short数据fft
BOOL CFourier::Fourier2(short *TDdata,long lWidth,long lHeight,complex<float>*FDresult)
{
	
	long i;
	long j;//循环变量

	int wp;
	int hp;//2的指数
	
	w=1;	//赋初值
	h=1;
	wp=0;
	hp=0;

	while(w<lWidth)//计算进行傅立叶变换的宽度和高度(2的整数次方)
	{
		w*=2;
		wp++;
	}
	while(h<lHeight)
	{
		h*=2;
		hp++;
	}
	//
	memset(FDresult,0,sizeof(complex<float>)*w*h);	//设置为0

	//先对行作FFT
	complex<float>*TD=new complex<float>[w];	//分配内存存储时域数据
	float tempD;		//临时变量
	for(i=0;i<lHeight;i++)
	{
		memset(TD,0,sizeof(complex<float>)*w);	//赋值0	
		for(j=0;j<lWidth;j++)
		{
			tempD=TDdata[i*lWidth+j];
			TD[j]=complex<float>(tempD,0);
		}
		//FFT
		FFT(TD,wp);
		//
		for(j=0;j<w;j++)
		{
			FDresult[i*w+j] = TD[j];
		}
	}
	delete[] TD;
	//
	//再对列做FFT
	TD=new complex<float>[h];

	for(i=0;i<w;i++)
	{
		memset(TD,0,sizeof(complex<float>)*h);
		//
		for(j=0;j<h;j++)
		{
			TD[j]=FDresult[j*w+i];
		}
		//FFT
		FFT(TD,hp);
		//
		for(j=0;j<h;j++)
		{
			FDresult[j*w+i]=TD[j];
		}
	}
	delete[] TD;
	//
	return true;
}
//二维int数据fft
BOOL CFourier::Fourier2(int *TDdata,long lWidth,long lHeight,complex<float>*FDresult)
{
	
	long i;
	long j;//循环变量

	int wp;
	int hp;//2的指数
	
	w=1;	//赋初值
	h=1;
	wp=0;
	hp=0;

	while(w<lWidth)//计算进行傅立叶变换的宽度和高度(2的整数次方)
	{
		w*=2;
		wp++;
	}
	while(h<lHeight)
	{
		h*=2;
		hp++;
	}
	//
	memset(FDresult,0,sizeof(complex<float>)*w*h);	//设置为0
	//先对行作FFT
	complex<float>*TD=new complex<float>[w];	//分配内存存储时域数据
	float tempD;		//临时变量
	for(i=0;i<lHeight;i++)
	{
		memset(TD,0,sizeof(complex<float>)*w);	//赋值0	
		for(j=0;j<lWidth;j++)
		{
			tempD=TDdata[i*lWidth+j];
			TD[j]=complex<float>(tempD,0);
		}
		//FFT
		FFT(TD,wp);
		//
		for(j=0;j<w;j++)
		{
			FDresult[i*w+j] = TD[j];
		}
	}
	delete[] TD;
	//
	//再对列做FFT
	TD=new complex<float>[h];

	for(i=0;i<w;i++)
	{
		memset(TD,0,sizeof(complex<float>)*h);
		//
		for(j=0;j<h;j++)
		{
			TD[j]=FDresult[j*w+i];
		}
		//FFT
		FFT(TD,hp);
		//
		for(j=0;j<h;j++)
		{
			FDresult[j*w+i]=TD[j];
		}
	}
	delete[] TD;
	//
	return true;
}
//
/*******************************************************************
 *	函数名:
 *		Fourier2()
 *	参数:
 *		lpImageData		时域数据
 *		lWidth			数据宽度
 *		lHeight			数据高度
 *		FDresult		频域结果
 *	说明:
 *		二维float数据的fourier变换
 *******************************************************************/
BOOL CFourier::Fourier2(float*TDdata,long lWidth,long lHeight,complex<float>*FDresult)
{
	
	long i;
	long j;//循环变量

	int wp;
	int hp;//2的指数
	
	w=1;	//赋初值
	h=1;
	wp=0;
	hp=0;

	while(w<lWidth)//计算进行傅立叶变换的宽度和高度(2的整数次方)
	{
		w*=2;
		wp++;
	}
	while(h<lHeight)
	{
		h*=2;
		hp++;
	}
	//
	memset(FDresult,0,sizeof(complex<float>)*w*h);	//设置为0

	//先对行作FFT
	complex<float>*TD=new complex<float>[w];	//分配内存存储时域数据

	for(i=0;i<lHeight;i++)
	{
		memset(TD,0,sizeof(complex<float>)*w);	//赋值0	
		for(j=0;j<lWidth;j++)
		{
			TD[j]=complex<float>(TDdata[i*lWidth+j],0);
		}
		//FFT
		FFT(TD,wp);
		//
		for(j=0;j<w;j++)
		{
			FDresult[i*w+j] = TD[j];
		}
	}
	delete[] TD;
	//
	//再对列做FFT
	TD=new complex<float>[h];

	for(i=0;i<w;i++)
	{
		memset(TD,0,sizeof(complex<float>)*h);
		//
		for(j=0;j<h;j++)
		{
			TD[j]=FDresult[j*w+i];
		}
		//FFT
		FFT(TD,hp);
		//
		for(j=0;j<h;j++)
		{
			FDresult[j*w+i]=TD[j];
		}
	}
	delete[] TD;
	//
	return true;
}
//short数据的二维中的一维 
BOOL CFourier::Fourier2(short*TDdata,long lWidth,long lHeight,complex<float>*FDresult,int flag)
{
	long i;
	long j;//循环变量

	int wp;
	int hp;//2的指数
	
	w=1;	//赋初值
	h=1;
	wp=0;
	hp=0;

	while(w<lWidth)//计算进行傅立叶变换的宽度和高度(2的整数次方)
	{
		w*=2;
		wp++;
	}
	while(h<lHeight)
	{
		h*=2;
		hp++;
	}
	//
	float tempD;		//临时变量
	if(flag==2)			//对行作fft
	{
		memset(FDresult,0,sizeof(complex<float>)*w*lHeight);	//设置为0
		//
		complex<float>*TD=new complex<float>[w];		//分配内存存储时域数据
		//
		for(i=0;i<lHeight;i++)//行
		{
			memset(TD,0,sizeof(complex<float>)*w);	//赋值0
			//转移一行数据到TD
			for(j=0;j<lWidth;j++)//列
			{
				tempD=TDdata[i*lWidth+j];
				TD[j]=complex<float>(tempD,0);
			}
			//FFT
			FFT(TD,wp);
			//
			for(j=0;j<w;j++)
			{
				FDresult[i*w+j]=TD[j];
			}
		}		
		//
		delete[]TD;
	}
	else if(flag==1)	//对列做fft
	{
		memset(FDresult,0,sizeof(complex<float>)*h*lWidth);	//设置为0
		//
		complex<float>*TD=new complex<float>[h];	//分配内存存储时域数据
		//
		for(i=0;i<lWidth;i++)
		{
			memset(TD,0,sizeof(complex<float>)*h);		//赋值0
			//将一列数据存到TD中
			for(j=0;j<lHeight;j++)
			{
				tempD=TDdata[j*lWidth+i];
				TD[j]=complex<float>(tempD,0);
			}
			//对TD做FFT
			FFT(TD,hp);
			//将数据保存到FDresult
			for(j=0;j<h;j++)
			{
				FDresult[j*lWidth+i]=TD[j];
			}		
		}
		//
		delete[]TD;
	}
	return true;
}
//int数据的二维中的一维 
BOOL CFourier::Fourier2(int*TDdata,long lWidth,long lHeight,complex<float>*FDresult,int flag)
{
	long i;
	long j;//循环变量

⌨️ 快捷键说明

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