?? 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 + -