📄 fft.cpp
字号:
#include "stdafx.h"
#include "FFT.h"
#include "math.h"
/***********************************************************************
* 函数名称:
* Transform_FFT()
*
*说明:无参数的构造函数,对成员变量进行初始化
***********************************************************************/
Transform_FFT::Transform_FFT()
{
m_pImgDataOut=NULL;//输出图像位图数据指针为空
m_lpColorTableOut=NULL;//输出图像颜色表指针为空
m_nColorTableLengthOut=0;//输出图像颜色表长度为0
m_nBitCountOut=0;//输出图像每像素位数为0
m_imgWidthOut=0;//输出图像的宽为0
m_imgHeightOut=0;//输出图像的高为0
m_pFFTBuf=NULL;//傅立叶变换缓冲区为空
m_pImgExpandBuf=NULL;//输入图像扩展缓冲区指针初始化为0
m_isExpanded=FALSE;// 图像没有被扩展,标志变量置假
}
/***********************************************************************
* 函数名称:
* Transform_FFT()
*
*函数参数:
* CSize size -图像大小(宽、高)
* int nBitCount -每像素所占位数
* LPRGBQUAD lpColorTable -颜色表指针
* unsigned char *pImgData -位图数据指针
*
*返回值:
* 无
*
*说明:本函数为带参数的构造函数,给定位图的大小、每像素位数、颜色表
* 及位图数据,调用ImgCenterDib()对基类成员初始化,并初始化派生类的
* 数据成员
***********************************************************************/
Transform_FFT::Transform_FFT(CSize size, int nBitCount,
LPRGBQUAD lpColorTable, unsigned char *pImgData):
ImgCenterDib(size, nBitCount, lpColorTable, pImgData)
{
//输出图像每像素位数,与输入图像相同,都为灰度图像
m_nBitCountOut=m_nBitCount;
//输出图像颜色表长度
m_nColorTableLengthOut=ComputeColorTabalLength(m_nBitCountOut);
//为输出图像申请颜色表缓冲区,并将原图像输入图像和输出图像均为灰度格式,
//故在构造函数中直接对颜色表进行拷贝处理
m_lpColorTableOut=new RGBQUAD[m_nColorTableLengthOut];
memcpy(m_lpColorTableOut,m_lpColorTable, sizeof(RGBQUAD)*m_nColorTableLengthOut);
m_pImgDataOut=NULL;//输出图像指针为空
m_pFFTBuf=NULL;//傅立叶变换缓冲区为空
m_pImgExpandBuf=NULL;//输入图像扩展缓冲区指针初始化为0
m_isExpanded=FALSE;//图像没有被扩展,标志变量置假
}
/***********************************************************************
* 函数名称:
* ~Transform_FFT()
*
*说明:析构函数,释放资源
***********************************************************************/
Transform_FFT::~Transform_FFT()
{
//释放输出图像缓冲区
if(m_pImgDataOut!=NULL){
delete []m_pImgDataOut;
m_pImgDataOut=NULL;
}
//释放输出图像颜色表缓冲区
if(m_lpColorTableOut!=NULL){
delete []m_lpColorTableOut;
m_lpColorTableOut=NULL;
}
//释放傅立叶变换缓冲区
if(m_pFFTBuf!=NULL){
delete m_pFFTBuf;
m_pFFTBuf=NULL;
}
//如果对原图像进行过扩展,则释放图像扩展缓冲区
if(m_isExpanded==TRUE){
delete []m_pImgExpandBuf;
m_pImgExpandBuf=NULL;
}
}
/***********************************************************************
* 函数名称:
* InputImgData()
*
*函数参数:
* CSize size -输入图像大小(宽、高)
* int nBitCount -每像素位数
* LPRGBQUAD lpColorTable -颜色表指针
* unsigned char *pImgData -位图数据指针
*
*返回值:
* 无
*
*说明:输入图像数据,与带参数构造函数类似,调用基类成员函数ReplaceDib创建
* 输入图像的DIB结构,并清理缓冲区,初始化输出图像的颜色表,为图像快
* 速傅立叶变换做准备
***********************************************************************/
void Transform_FFT::InputImgData(CSize size, int nBitCount,
LPRGBQUAD lpColorTable, unsigned char *pImgData)
{
//调用基类成员函数ReplaceDib为创建输入图像的DIB结构
ReplaceDib(size, nBitCount, lpColorTable, pImgData);
//清理缓冲区
if(m_pImgDataOut!=NULL){
delete []m_pImgDataOut;
m_pImgDataOut=NULL;
}
if(m_pFFTBuf!=NULL){
delete m_pFFTBuf;
m_pFFTBuf=NULL;
}
if(m_isExpanded==TRUE){
delete []m_pImgExpandBuf;
m_pImgExpandBuf=NULL;
}
//输出图像每像素位数与输入图像相同
m_nBitCountOut=m_nBitCount;
//输出图像颜色表长度
m_nColorTableLengthOut=ComputeColorTabalLength(m_nBitCountOut);
//申请输出图像颜色表缓冲区m_lpColorTableOut,并将输入图像颜色表数据拷贝
//至m_lpColorTableOut
m_lpColorTableOut=new RGBQUAD[m_nColorTableLengthOut];
memcpy(m_lpColorTableOut,m_lpColorTable, sizeof(RGBQUAD)*m_nColorTableLengthOut);
m_isExpanded=FALSE;//图像没有被扩展,标志变量置假
}
/***********************************************************************
* 函数名称:
* GetDimensions()
*
*函数参数:
* 无
*
*返回值:
* 图像的尺寸,用CSize类型表达
*
*说明:返回输出图像的宽和高
***********************************************************************/
CSize Transform_FFT::GetDimensions()
{
return CSize(m_imgWidthOut, m_imgHeightOut);
}
/***********************************************************************
* 函数名称:
* FFT1D()
*
*函数参数:
* ComplexNumber *arrayBuf -复数结构体类型数组
* int n -数组arrayBuf的长度,必须为2的幂次方
*
*返回值:
* 无
*
*说明:对复数结构体数组arrayBuf进行一维快速傅立叶变换,变换后的结果仍
* 存回arrayBuf中
***********************************************************************/
void Transform_FFT::FFT1D(ComplexNumber *arrayBuf, int n)
{
//循环变量
int i, k, r;
//申请临时复数缓冲区buf1,长度为n
ComplexNumber *buf1=new ComplexNumber[n];
//将arrayBuf拷贝进buf1
memcpy(buf1,arrayBuf,sizeof(ComplexNumber)*n);
//申请临时复数缓冲区buf2,长度为n
ComplexNumber *buf2=new ComplexNumber[n];
//将arrayBuf数组元素基2抽取并重新排列
//若0、1、2、3、4、5、6、7八点序列对调后变作0、4、2、6、1、5、3、7
int t1,t2;
for(r=1;pow(2,r)<n;r++){
t1=pow(2,r);
t2=pow(2,r-1);
for(k=0;k<t1;k++){
for(i=0;i<n/t1;i++){
buf2[k*n/t1+i].real=buf1[k/2*n/t2+i*2+k%2].real;
buf2[k*n/t1+i].imag=buf1[k/2*n/t2+i*2+k%2].imag;
}
}
memcpy(buf1,buf2,sizeof(ComplexNumber)*n);
}
//采用蝶型算法进行快速傅立叶变换
//buf1是第r级的输入,buf2存放第r级的输出
float c,s;
for(r=1;pow(2,r)<=n;r++){
t1=pow(2,r);
for(k=0;k<n/t1;k++){
for(i=t1/2;i<t1;i++){
//加权因子
c=cos(-2*PI*(i-t1/2)/t1);
s=sin(-2*PI*(i-t1/2)/t1);
buf1[k*t1+i].real= buf2[k*t1+i].real*c - buf2[k*t1+i].imag*s;
buf1[k*t1+i].imag=buf2[k*t1+i].imag*c+buf2[k*t1+i].real*s;
}
}
for(k=0; k<n/t1; k++){
for(i=0;i<t1/2;i++){
buf2[k*t1+i].real= buf1[k*t1+i].real+buf1[k*t1+i+t1/2].real;
buf2[k*t1+i].imag= buf1[k*t1+i].imag+buf1[k*t1+i+t1/2].imag;
}
for(i=t1/2;i<t1;i++){
buf2[k*t1+i].real= buf1[k*t1+i-t1/2].real-buf1[k*t1+i].real;
buf2[k*t1+i].imag= buf1[k*t1+i-t1/2].imag-buf1[k*t1+i].imag;
}
}
//第r级的输出存入buf1,作为下一级的输入数据
memcpy(buf1,buf2,sizeof(ComplexNumber)*n);
}
//傅立叶变换的结果存入arrayBuf
memcpy(arrayBuf,buf2,sizeof(ComplexNumber)*n);
//释放缓冲区
delete[]buf2;
delete[]buf1;
}
/***********************************************************************
* 函数名称:
* ImgFFT2D()
*
*函数参数:
* unsigned char* imgBuf -图像数据指针
* int width -图像宽
* int height -图像高
* unsigned char *imgBufOut -傅立叶变换后的输出图像
*
*返回值:
* 无
*
*说明:图像数据二维快速傅立叶变换将图像数据变成复数形式,进行两个一维快速
* 傅立叶变换,变换后的频谱以图像形式存入imgBufOut,此处要求图像宽和高
* 都为2的幂次方
***********************************************************************/
void Transform_FFT::ImgFFT2D(unsigned char* imgBuf, int width, int height,
unsigned char *imgBufOut)
{
//循环变量
int i, j, u, v;
//图像数据变成复数类型存入m_pFFTBuf
for(i=0;i<width*height;i++){
m_pFFTBuf[i].real=imgBuf[i];
m_pFFTBuf[i].imag=0;
}
//申请ComplexNumber结构体数组,长度为height
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;
}
FFT1D(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;
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -