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

📄 fouriertransforms.cpp

📁 fft变换代码,采用基2的频率域变换代码.
💻 CPP
📖 第 1 页 / 共 2 页
字号:
*   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 + -