📄 fourier.cpp
字号:
// 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 + -