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

📄 fft.cpp

📁 将数字图像处理的一般算法都集中在一个MFC的框架中
💻 CPP
📖 第 1 页 / 共 2 页
字号:
		}
	}
	delete []array;

	//再横向一维快速傅立叶变换
	for(v=0;v<height;v++){
		FFT1D(m_pFFTBuf+v*width, width);
	}

	//将频谱图以图像形式存入imgBufOut
	float t;
	int i0,j0;
	for(i=0;i<height;i++){
		//i0 = i;
		//j0 = j;
		for(j=0;j<width;j++){
			if(i<height/2)
				i0=i+height/2;
			else
				i0=i-height/2;
			if(j<width/2)
				j0=j+width/2;
			else
				j0=j-width/2;
			
			t=sqrt(m_pFFTBuf[i0*width+j0].real*m_pFFTBuf[i0*width+j0].real
				+m_pFFTBuf[i0*width+j0].imag*m_pFFTBuf[i0*width+j0].imag);
			t=t/500;
			if(t>255)
				imgBufOut[i*width+j]=255;
			else 
				imgBufOut[i*width+j]=t;
		}
	}

}

/***********************************************************************
* 函数名称:
* IFFT1D()
*
*函数参数:
*  ComplexNumber *arrayBuf  -复数结构体类型数组
*  int n  -数组arrayBuf的长度,必须为2的幂次方
*
*返回值:
*   无
*
*说明:对复数结构体数组arrayBuf进行一维快速傅立叶反变换,变换后的结果仍
*      存回arrayBuf中
***********************************************************************/
void Transform_FFT::IFFT1D(ComplexNumber *arrayBuf, int n)
{
	//变量
	int i;

	//对数组arrayBuf求共轭
	for(i=0;i<n;i++)
		arrayBuf[i].imag=-arrayBuf[i].imag;

	//一维快速傅立叶变换
	FFT1D(arrayBuf, n);

	//时域数据求共轭,并除以N
	for(i=0;i<n;i++){
		arrayBuf[i].real=arrayBuf[i].real/n;
		arrayBuf[i].imag=-arrayBuf[i].imag/n;
	}

}


/***********************************************************************
* 函数名称:
* ImgIFFT2D()
*
*函数参数:
*  unsigned char* imgBufOut  -输出图像数据指针
*  int width  -图像宽
*  int height  -图像高
*
*返回值:
*   无
*
*说明:对傅立叶变换缓冲区m_pFFTBuf里的数据,进行两个一维快速傅立叶反变换,
*      变换后的频谱即是原图像的恢复数据,将恢复数据存入imgBufOut,此处要求
*      图像宽和高均为2的幂次方    
***********************************************************************/
void Transform_FFT::ImgIFFT2D(unsigned char* imgBufOut, int width, int height)
{
	//若傅立叶变换缓冲区为空,则失败返回
	if(!m_pFFTBuf)
		return;

	//变量
	int i, u, v;
	
	//先纵向傅立叶反变换
	ComplexNumber *array=new ComplexNumber[height];
	for(u=0;u<width;u++){
		for(v=0;v<height;v++){
			array[v].real=m_pFFTBuf[v*width+u].real;
			array[v].imag=m_pFFTBuf[v*width+u].imag;
		}
		IFFT1D(array, height);
		for(v=0;v<height;v++){
			m_pFFTBuf[v*width+u].real=array[v].real;
			m_pFFTBuf[v*width+u].imag=array[v].imag;
		}
	}
	delete []array;

	//再横向傅立叶反变换
	for(v=0;v<height;v++){
		IFFT1D(m_pFFTBuf+v*width, width);
	}

	//求m_pFFTBuf的幅度谱,恢复图像存入imgBufOut
	float t;
	for(i=0;i<width*height;i++){
		t=sqrt(m_pFFTBuf[i].real*m_pFFTBuf[i].real
			         +m_pFFTBuf[i].imag*m_pFFTBuf[i].imag);
		if(t>255)
			imgBufOut[i]=255;
		else imgBufOut[i]=t;
	}
}



/***********************************************************************
* 函数名称:
* Fourier()
*
*函数参数:
*  无
*
*返回值:
*   无
*
*说明:对输入图像进行快速傅立叶变换,要求输入图像的宽和高必须是2的幂次方
***********************************************************************/
void Transform_FFT::Fourier()
{
	//输出图像的大小与输入图像相同
	m_imgWidthOut=m_imgWidth;
	m_imgHeightOut=m_imgHeight;

	//申请输出图像缓冲区,并初始化为0
	m_pImgDataOut=new unsigned char[m_imgWidthOut*m_imgHeightOut];
	memset(m_pImgDataOut, 0, m_imgWidthOut*m_imgHeightOut);
	
	//申请傅立叶缓冲区,并初始化为0
	m_pFFTBuf=new ComplexNumber[m_imgWidthOut*m_imgHeightOut];
	memset(m_pFFTBuf, 0, sizeof(ComplexNumber)*m_imgWidthOut*m_imgHeightOut);

	//输入图像数据进行二维傅立叶变换
	ImgFFT2D(m_pImgData, m_imgWidthOut, m_imgHeightOut, m_pImgDataOut);
}

/***********************************************************************
* 函数名称:
* IFourier()
*
*函数参数:
*  无
*
*返回值:
*   无
*
*说明:输入图像的快速傅立叶反变换,与ImgFFT()成对调用
***********************************************************************/
void Transform_FFT::IFourier()
{
	//图像的二维傅立叶反变换,变换结果即是恢复的原图像,存入m_pImgDataOut
	ImgIFFT2D(m_pImgDataOut, m_imgWidthOut, m_imgHeightOut);
}



/***********************************************************************
* 函数名称:
* FourierEx()
*
*函数参数:
*  无
*
*返回值:
*   无
*
*说明:若图像长和宽是2的幂次方,则直接调用ImgFFT()进行傅立叶变换,否则,
*      对输入图像的长和宽进行2的幂次的扩展,对扩展后的图像数据进行快速傅
*      立叶变换,因此该函数适合于任意大小图像的傅立叶变换
***********************************************************************/
void Transform_FFT::FourierEx()
{
	//判断输入图像长和宽是否是2的幂次方,若是isPowerOf2置1,否则isPowerOf2置0
	int isPowerOf2=1;
	int i=1;
	while(i<m_imgWidth)
		i=i*2;
	if(i!=m_imgWidth)//宽不是2的幂次方
		isPowerOf2=0;
	
	i=1;
	while(i<m_imgHeight)
		i=i*2;
	if(i!=m_imgHeight)//高不是2的幂次方
		isPowerOf2=0;

	//输入图像长和宽若是2的幂次方,则不需要扩展,直接调用ImgFFT()函数即可
	if(isPowerOf2) {
		Fourier();
	}
	else{
		//输入图像长或宽不是2的幂次方,则将图像补零扩展

		//计算应扩展缓冲区的大小
		i=1;
		while(i<m_imgWidth)
			i=i*2;	
		m_imgWidthOut=i;

		i=1;
		while(i<m_imgHeight)
			i=i*2;	
		m_imgHeightOut=i;

		//申请扩展缓冲区m_pImgExpandBuf
		m_pImgExpandBuf=new unsigned char[m_imgWidthOut*m_imgHeightOut];

		//m_pImgExpandBuf缓冲区置0
		memset(m_pImgExpandBuf, 0, m_imgWidthOut*m_imgHeightOut);
		
		//循环变量,图像的坐标
		int i,j;
		//输入图像每行像素字节数
		int lineByte=(m_imgWidth*m_nBitCount/8+3)/4*4;

		//输入图像数据拷贝到m_pImgExpandBuf的左下角部分,其余为0
		for(i=0;i<m_imgHeight;i++){
			for(j=0;j<m_imgWidth;j++){
				*(m_pImgExpandBuf+i*m_imgWidthOut+j)=*(m_pImgData+i*lineByte+j);
			}
		}
		
		//申请输出图像缓冲区,并初始化为0
		m_pImgDataOut=new unsigned char[m_imgWidthOut*m_imgHeightOut];
		memset(m_pImgDataOut, 0, m_imgWidthOut*m_imgHeightOut);
		
		//申请傅立叶缓冲区,并初始化为0
		m_pFFTBuf=new ComplexNumber[m_imgWidthOut*m_imgHeightOut];
		memset(m_pFFTBuf, 0, sizeof(ComplexNumber)*m_imgWidthOut*m_imgHeightOut);
		
		//扩展后的数据进行二维傅立叶变换
		ImgFFT2D(m_pImgExpandBuf, m_imgWidthOut, m_imgHeightOut, m_pImgDataOut);

		//图像被扩展的标志变量置真
		m_isExpanded=TRUE;
	}
}

/***********************************************************************
* 函数名称:
* IFourierEx()
*
*函数参数:
*  无
*
*返回值:
*   无
*
*说明:输入图像扩展后的快速傅立叶反变换,与ImgFFTEx()成对调用
***********************************************************************/
void Transform_FFT::IFourierEx()
{
	//图像的二维傅立叶反变换,变换结果存入m_pImgDataOut
	ImgIFFT2D(m_pImgDataOut, m_imgWidthOut, m_imgHeightOut);

	//若m_isExpanded为真,则说明原图像是经过扩展补零的,m_pImgDataOut内的图
	//像数据是扩展后的恢复数据,此时应将扩展部分删除掉
	if(m_isExpanded==TRUE){
		
		//循环变量,图像的坐标
		int i,j;

		//输入图像每行像素字节数
		int lineByte=(m_imgWidth*m_nBitCount/8+3)/4*4;

		//申请输入图像大小的缓冲区,将m_pImgDataOut中真正的图像数据拷贝出来
		unsigned char *pBuf=new unsigned char[lineByte*m_imgHeight];
		for(i=0;i<m_imgHeight;i++){
			for(j=0;j<m_imgWidth;j++){
				*(pBuf+i*lineByte+j)=*(m_pImgDataOut+i*m_imgWidthOut+j);
			}
		}
		//释放扩展后的图像恢复数据m_pImgDataOut
		delete []m_pImgDataOut;

		//m_pImgDataOut指向真正图像的恢复数据
		m_pImgDataOut=pBuf;

		//输出图像的宽高
		m_imgWidthOut=m_imgWidth;
		m_imgHeightOut=m_imgHeight;
	}	
}

⌨️ 快捷键说明

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