在MFC里添加了一个函数,涉及到傅立叶变换,使用的是FFT蝶形算法
奇怪的是,对图像补零使其满足长宽为2幂次方后变换,如果是1024*1024,512*512这类,反变换得到正确图像
如果是1024*512,512*256这类,反变换图像跟原图像差距很大,灰度改变,还有帘状条纹
哪位遇到过这种情况的指点一下
奇怪的是,对图像补零使其满足长宽为2幂次方后变换,如果是1024*1024,512*512这类,反变换得到正确图像
如果是1024*512,512*256这类,反变换图像跟原图像差距很大,灰度改变,还有帘状条纹
哪位遇到过这种情况的指点一下
为了避免补零,我变换的就是512*1024的图像,但是FFT本身就不对,把代码帖出来//二维变换
VOID WINAPI FFT_2D(complex<double> * pCTData, int nWidth, int nHeight, complex<double> * pCFData)
{
int wlev,hlev;
int i,j;
double temp1; temp1=double(log(nWidth)/log(2));
wlev=ceil(temp1);
temp1=double(log(nHeight)/log(2));
hlev=ceil(temp1);
//第一次变换
for(i=0;i<nHeight;i++)
{
FFT_1D(&pCTData[nWidth * i], &pCFData[nWidth * i], wlev);
}
//转置
for(i=0;i<nHeight;i++)
{
for(j=0;j<nWidth;j++)
{
pCTData[nHeight * j + i] = pCFData[nWidth * i + j];
}
}
//第二次变换
for(i=0;i<nWidth;i++)
{
FFT_1D(&pCTData[nHeight * i], &pCFData[nHeight * i], hlev);
}
//转置
for(i=0;i<nHeight;i++)
{
for(j=0;j<nWidth;j++)
{
pCTData[nWidth * i + j] = pCFData[nHeight * j + i];
}
} memcpy(pCTData, pCFData, sizeof(complex<double>) * nHeight * nWidth); return;
}//一维变换
VOID WINAPI FFT_1D(complex<double> * pCTData, complex<double> * pCFData, int nLevel)
{
// 循环控制变量
int i;
int j;
int k; double PI = 3.1415926; // 傅立叶变换点数
int nCount =0 ; // 计算傅立叶变换点数
nCount =(int)pow(2,nLevel) ;
// 某一级的长度
int nBtFlyLen;
nBtFlyLen = 0 ;
// 变换系数的角度 =2 * PI * i / nCount
double dAngle;
complex<double> *pCW ;
// 分配内存,存储傅立叶变化需要的系数表
pCW = new complex<double>[nCount / 2]; // 计算傅立叶变换的系数
for(i = 0; i < nCount / 2; i++)
{
dAngle = -2 * PI * i / nCount;
pCW[i] = complex<double> ( cos(dAngle), sin(dAngle) );
} // 变换需要的工作空间
complex<double> *pCWork1,*pCWork2;
// 分配工作空间
pCWork1 = new complex<double>[nCount]; pCWork2 = new complex<double>[nCount];
// 临时变量
complex<double> *pCTmp;
// 初始化,写入数据
memcpy(pCWork1, pCTData, sizeof(complex<double>) * nCount); // 临时变量
int nInter;
nInter = 0; // 蝶形算法进行快速傅立叶变换
for(k = 0; k < nLevel; k++)
{
for(j = 0; j < (int)pow(2,k); j++)
{
//计算长度
nBtFlyLen = (int)pow( 2,(nLevel-k) );
//倒序重排,加权计算
for(i = 0; i < nBtFlyLen/2; i++)
{
nInter = j * nBtFlyLen;
pCWork2[i + nInter] =
pCWork1[i + nInter] + pCWork1[i + nInter + nBtFlyLen / 2];
pCWork2[i + nInter + nBtFlyLen / 2] =
(pCWork1[i + nInter] - pCWork1[i + nInter + nBtFlyLen / 2])
* pCW[(int)(i * pow(2,k))];
}
} // 交换 pCWork1和pCWork2的数据
pCTmp = pCWork1 ;
pCWork1 = pCWork2 ;
pCWork2 = pCTmp ;
}
// 重新排序
for(j = 0; j < nCount; j++)
{
nInter = 0;
for(i = 0; i < nLevel; i++)
{
if ( j&(1<<i) )
{
nInter += 1<<(nLevel-i-1);
}
}
pCFData[j]=pCWork1[nInter];
}
// 释放内存空间
delete pCW;
delete pCWork1;
delete pCWork2;
pCW = NULL ;
pCWork1 = NULL ;
pCWork2 = NULL ;}
VOID WINAPI FFT_2D(complex <double> * pCTData, int nWidth, int nHeight, complex <double> * pCFData)
pCTData 是时域数据指针
nWidth 数据宽度,已经是2幂
nHeight 高度
pCFData 频域数据指针