📄 fouriertransforms.cpp
字号:
* complex<double> * pCFData - 指向频域值的指针
* complex<double> * pCTData - 指向时域值的指针
* nLevel -付立叶变换蝶形算法的级数,2的幂数
*
* 返回值:
* 无。
*
* 说明:
* 该函数用来实现快速付立叶反变换。
*
************************************************************************/
LLVPRO_API void IFFT_1D(complex<double> * pCFData, complex<double> * pCTData, int nLevel)
{
// 付立叶变换点数
long lcount;
// 循环变量
int i;
complex<double> *pCWork;
// 计算付立叶变换点数
lcount = 1 << nLevel;
// 分配运算所需存储器
pCWork = new complex<double>[lcount];
// 将频域点写入pCWork
memcpy(pCWork, pCFData, sizeof(complex<double>) * lcount);
// 为了利用付立叶正变换,可以把付立叶频域的数据取共轭
// 然后直接利用正变换,输出结果就是付立叶反变换结果的共轭
for(i = 0; i < lcount; i++)
{
pCWork[i] = complex<double> (pCWork[i].real(), -pCWork[i].imag());
}
// 调用快速付立叶变换实现反变换,结果存储在pCTData中
FFT_1D_Opti(pCWork, pCTData, nLevel);
// 求时域点的共轭,求得最重结果
// 根据付立叶变换原理,利用这样的方法求的结果和实际的时域数据
// 相差一个系数nCount
for(i = 0; i < lcount; i++)
{
pCTData[i] = complex<double> (pCTData[i].real() / lcount, -pCTData[i].imag() / lcount);
}
// 释放内存
if( pCWork!=NULL )
{
delete []pCWork;
pCWork = NULL;
}
}
/*************************************************************************
*
* \函数名称:
* FFT_2D()
*
* \输入参数:
* complex<double> * pCTData - 图像数据
* complex<double> * pCFData - 傅立叶变换后的结果
* long lTransWidth - 变换数据宽度
* long lTransHeight - 变换数据高度
*
* \返回值:
* TRUE 变换成功
* FALSE 变换失败
*
* \说明:
* 二维傅立叶变换。
* 不负责pCTData的补零操作
************************************************************************/
LLVPRO_API BOOL FFT_2D(complex<double> * pCTData, complex<double> * pCFData,long lTransWidth, long lTransHeight)
{
if(pCTData==NULL||pCFData==NULL||lTransWidth<=0||lTransHeight<=0)
{
return FALSE;
}
// 循环控制变量
int x;
int y;
// x,y(行列)方向上的迭代次数
int nXLev;
int nYLev;
// 计算x,y(行列)方向上的迭代次数
nXLev = (int) ( log(lTransWidth)/log(2) ) ;
nYLev = (int) ( log(lTransHeight)/log(2)) ;
if(((1 << nXLev)!=lTransWidth)||((1 << nYLev)!=lTransHeight))
{
return FALSE;
}
for(y = 0; y < lTransHeight; y++)
{
// x方向进行快速傅立叶变换
// FFT_1D(&pCTData[lTransWidth * y], &pCFData[lTransWidth * y], nXLev);
FFT_1D_Opti(&pCTData[lTransWidth * y], &pCFData[lTransWidth * y], nXLev);
}
// pCFData中目前存储了pCTData经过行变换的结果
// 为了直接利用FFT_1D,需要把pCFData的二维数据转置,再一次利用FFT_1D进行
// 傅立叶行变换(实际上相当于对列进行傅立叶变换)
for(y = 0; y < lTransHeight; y++)
{
for(x = 0; x < lTransWidth; x++)
{
pCTData[lTransHeight * x + y] = pCFData[lTransWidth * y + x];
}
}
for(x = 0; x < lTransWidth; x++)
{
// 对x方向进行快速傅立叶变换,实际上相当于对原来的图象数据进行列方向的
// 傅立叶变换
// FFT_1D(&pCTData[lTransHeight * x], &pCFData[lTransHeight * x], nYLev);
FFT_1D_Opti(&pCTData[x * lTransHeight], &pCFData[x * lTransHeight], nYLev);
}
// pCFData中目前存储了pCTData经过二维傅立叶变换的结果,但是为了方便列方向
// 的傅立叶变换,对其进行了转置,现在把结果转置回来
for(y = 0; y < lTransHeight; y++)
{
for(x = 0; x < lTransWidth; x++)
{
pCTData[lTransWidth * y + x] = pCFData[lTransHeight * x + y];
}
}
memcpy(pCFData,pCTData, sizeof(complex<double>) * lTransHeight * lTransWidth );
return TRUE;
}
/*************************************************************************
*
* \函数名称:
* IFFT_2D()
*
* \输入参数:
* complex<double> * pCFData - 频域数据
* complex<double> * pCTData - 时域数据
* long lTransWidth - 变换数据宽度
* long lTransHeight - 变换数据高度
*
* \返回值:
* TRUE 变换成功
* FALSE 变换失败
*
* \说明:
* 二维傅立叶反变换。
*
*************************************************************************/
LLVPRO_API BOOL IFFT_2D(complex<double> * pCFData, complex<double> * pCTData, long lTransWidth, long lTransHeight)
{
if(pCTData==NULL||pCFData==NULL||lTransWidth<=0||lTransHeight<=0)
{
return FALSE;
}
// x,y(行列)方向上的迭代次数
int nXLev;
int nYLev;
// 计算x,y(行列)方向上的迭代次数
nXLev = (int) ( log(lTransWidth)/log(2) );
nYLev = (int) ( log(lTransHeight)/log(2) );
if(((1 << nXLev)!=lTransWidth)||((1 << nYLev)!=lTransHeight))
{
return FALSE;
}
// 循环控制变量
int x;
int y;
// 分配工作需要的内存空间
complex<double> *pCWork= new complex<double>[lTransWidth * lTransHeight];
//临时变量
complex<double> *pCTmp ;
// 为了利用傅立叶正变换,可以把傅立叶频域的数据取共轭
// 然后直接利用正变换,输出结果就是傅立叶反变换结果的共轭
for(y = 0; y < lTransHeight; y++)
{
for(x = 0; x < lTransWidth; x++)
{
pCTmp = &pCFData[lTransWidth * y + x] ;
pCWork[lTransWidth * y + x] = complex<double>( pCTmp->real() , -pCTmp->imag() );
}
}
// 调用傅立叶正变换
FFT_2D(pCWork, pCTData,lTransWidth, lTransHeight) ;
// 求时域点的共轭,求得最终结果
// 根据傅立叶变换原理,利用这样的方法求得的结果和实际的时域数据
// 相差一个系数
for(y = 0; y < lTransHeight; y++)
{
for(x = 0; x < lTransWidth; x++)
{
pCTmp = &pCTData[lTransWidth * y + x] ;
pCTData[lTransWidth * y + x] = complex<double>( pCTmp->real()/(lTransWidth*lTransHeight),
-pCTmp->imag()/(lTransWidth*lTransHeight) );
}
}
delete []pCWork ;
pCWork = NULL ;
return TRUE;
}
/*************************************************************************
*
* \函数名称:
* DIBFFT_2D()
*
* \输入参数:
* LPBYTE pbyImage - 图像数据
* long lWidth - 数据宽度
* long lHeight - 数据高度
* long lTransWidth - 变换宽度
* long lTransHeight - 变换高度
* complex<double> * pCFData - 频域数据,中心变换后的数据
* \返回值:
* TRUE 变换成功
* FALSE 变换失败
*
* \说明:
* 图像二维傅立叶变换。
* 若lWidth!=lTransWidth||lHeight!=lTransHeight,对时域数据进行补零操作
* pCFData 数据经过中心变换
*************************************************************************/
LLVPRO_API BOOL DIBFFT_2D(LPBYTE pbyImage,long lWidth,long lHeight,long &lTransWidth,long &lTransHeight,complex<double>* &pCFData)
{
// 空域变换尺寸必须不小于图像尺寸
if(pbyImage == NULL||lWidth <= 0||lHeight <0 )
{
return FALSE;
}
int x,y;
// 临时变量
double dTmpOne;
double dTmpTwo;
// 计算进行傅立叶变换的点数 (2的整数次幂)
dTmpOne = log(lWidth)/log(2) ;
dTmpTwo = ceil(dTmpOne) ;
dTmpTwo = pow(2,dTmpTwo) ;
lTransWidth = (long) dTmpTwo ;
// 计算进行傅立叶变换的点数 (2的整数次幂)
dTmpOne = log(lHeight)/log(2) ;
dTmpTwo = ceil(dTmpOne) ;
dTmpTwo = pow(2,dTmpTwo) ;
lTransHeight = (long) dTmpTwo ;
if(pCFData != NULL)
{
xfree(pCFData);
pCFData = NULL;
}
pCFData = (complex<double>*)xmalloc(lTransWidth * lTransHeight*sizeof(complex<double>));
if(pCFData == NULL)
{
return FALSE;
}
// 指向时域数据的指针
complex<double>* pCTData = new complex<double>[lTransWidth * lTransHeight];
// 初始化
// 图象数据的宽和高不一定是2的整数次幂,所以pCTData
// 有一部分数据需要补0
if(lHeight!=lTransHeight)
{
memset(pCTData+lHeight,0,sizeof(complex<double>)*lTransWidth*(lTransHeight-lHeight));
}
if(lWidth != lTransWidth)
{
for(y=0; y< lHeight ; y++)
{
memset(pCTData+y*lTransWidth+lWidth,0,sizeof(complex<double>)*(lTransWidth-lWidth));
}
}
// 把图象数据传给pCTData,并进行中心变换
for(y=0; y<lHeight; y++)
{
for(x=0; x<lWidth; x++)
{
BYTE unchValue = pbyImage[y*lWidth +x] ;
if((x+y)%2==0)
{
pCTData[y*lTransWidth + x]=complex<double>(unchValue,0);
}
else
{
pCTData[y*lTransWidth + x]=complex<double>(-unchValue,0);
}
}
}
// 傅立叶正变换
if(!FFT_2D(pCTData,pCFData,lTransWidth, lTransHeight) )
{
return FALSE;
}
if(pCTData!=NULL)
{
delete []pCTData;
pCTData = NULL;
}
return TRUE;
}
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -