概述
使用fftw_plan_dft_2d对图像进行FFT(常规方法)
要使用fftw_plan_dft_2d函数首先得下载并安装官方的库,安装的时候要注意64位系统与32位系统的不同的执行步骤,我安装的时候弄了挺久的
代码块
这里的输入图片变量名为pRefImg
int nFFTRow=0;
int nFFTCol=0;
nFFTRow=nRefRow;//补零则需要将nFFTRow~2的n次幂
nFFTCol=nRefCol;
//第一步:定义FFT的输入与输出。fftw_complex为fftw3内部的一种类型
fftw_complex *pRefFFTIn= (fftw_complex *)fftw_malloc(sizeof(fftw_complex) * nFFTRow*nFFTCol);
fftw_complex *pRefFFTOut= (fftw_complex *)fftw_malloc(sizeof(fftw_complex) * nFFTRow*nFFTCol);
//第二步:生成plan
fftw_plan p_for_ref;
//第三步:将输入输出的行列数、输入输出的变量名填入,根据需要选择是FFT——FFTW_FORWARD/IFFT——FFTW_BACKWARD
p_for_ref = fftw_plan_dft_2d(nFFTRow, nFFTCol, pRefFFTIn, pRefFFTOut, FFTW_FORWARD, FFTW_ESTIMATE);
//第四步:处理输入变量,按需要在此处进行变换前对图像进行拓展补零
for (i=0; i<nFFTRow; i++)
{
for (j=0; j<nFFTCol; j++)
{
pRefFFTIn[i*nFFTCol+j][0]= (double)pRefImg[i][j];//实部
pRefFFTIn[i*nFFTCol+j][1] = 0;//虚部
}
}
//第五步:执行plan
fftw_execute(p_for_ref);
//第六步:释放内存
fftw_destroy_plan(p_for_ref);
if(pRefFFTIn!=NULL) fftw_free(pRefFFTIn);//释放内存
执行此段代码后数组pRefFFTOut就存放了变换后的结果,pRefFFTOut[…][0]保存的为实部、pRefFFTOut[…][1]保存的为虚部。
可以注意到,2dfft的输入输出都是两个很长很长的数组,实际上在函数的内部也是进行的1dfft,我们告诉函数有多少行多少列,目的就是让函数知道要进行多少点的fft进行多少次。
使用fftw_plan_dft_1d函数对图像进行FFT(反常的做法)
如何由1DFFT对图像进行2D的FFT呢,很简单,只需要对图像的每一行进行FFT,然后转置,然后再对每一行进行FFT,然后再转置就行了
代码块
fftw_complex *pRefFFTIn = (fftw_complex*) fftw_malloc(sizeof(fftw_complex) * nFFTRow*nFFTCol);
for (i=0; i<nFFTRow; i++)
{
for (j=0; j<nFFTCol; j++)
{
pRefFFTIn[i*nFFTCol+j][0] = (double)pRefImg[i][j];//输入图像
pRefFFTIn[i*nFFTCol+j][1] = 0;
}
}
double **pRefFFTResult1_re = (double**)malloc(sizeof(double*)*nFFTRow);//开辟存储数组 实部
double **pRefFFTResult1_im = (double**)malloc(sizeof(double*)*nFFTRow);//开辟存储数组 虚部
for(int i=0;i<nFFTRow;i++)
{
pRefFFTResult1_re[i] = (double*)malloc(sizeof(double)*nFFTCol);
pRefFFTResult1_im[i] = (double*)malloc(sizeof(double)*nFFTCol);
}
//第一次fft
for (i=0; i<nFFTRow; i++)
{
fftw_complex *pRefFFTRowIn;
fftw_complex *pRefFFTRowOut;
pRefFFTRowIn = (fftw_complex*) fftw_malloc(sizeof(fftw_complex) * nFFTCol);
pRefFFTRowOut = (fftw_complex*) fftw_malloc(sizeof(fftw_complex) * nFFTCol);
fftw_plan p_for_ref1;
p_for_ref1 = fftw_plan_dft_1d(nFFTCol, pRefFFTRowIn, pRefFFTRowOut, FFTW_FORWARD,FFTW_ESTIMATE);
for (j=0;j<nFFTCol;j++)//行提取
{
pRefFFTRowIn[j][0] = pRefFFTIn[i*nFFTCol+j][0];
pRefFFTRowIn[j][1] = pRefFFTIn[i*nFFTCol+j][1];
}
fftw_execute(p_for_ref1);
for (j=0;j<nFFTCol;j++)
{
pRefFFTResult1_re[i][j] = pRefFFTRowOut[j][0];//存储转换结果
pRefFFTResult1_im[i][j] = pRefFFTRowOut[j][1];
}
fftw_destroy_plan(p_for_ref1);
//释放内存
if(pRefFFTRowIn!=NULL) fftw_free(pRefFFTRowIn);
if(pRefFFTRowOut!=NULL) fftw_free(pRefFFTRowOut);
}
//转置
double **pRefFFTResult1T_re = (double**)malloc(sizeof(double*)*nFFTRow);
double **pRefFFTResult1T_im = (double**)malloc(sizeof(double*)*nFFTRow);
for(int i=0;i<nFFTRow;i++)
{
pRefFFTResult1T_re[i] = (double*)malloc(sizeof(double)*nFFTCol);
pRefFFTResult1T_im[i] = (double*)malloc(sizeof(double)*nFFTCol);
}
for (i=0; i<nFFTRow; i++)
{
for (j=0; j<nFFTCol;j++)
{
pRefFFTResult1T_re[i][j] = pRefFFTResult1_re[j][i];
pRefFFTResult1T_im[i][j] = pRefFFTResult1_im[j][i];
}
}
//第二次fft
double **pRefFFTResult_re = (double**)malloc(sizeof(double*)*nFFTRow);
double **pRefFFTResult_im = (double**)malloc(sizeof(double*)*nFFTRow);
for(int i=0;i<nFFTRow;i++)
{
pRefFFTResult_re[i] = (double*)malloc(sizeof(double)*nFFTCol);
pRefFFTResult_im[i] = (double*)malloc(sizeof(double)*nFFTCol);
}
for (i=0; i<nFFTRow; i++)
{
fftw_complex *pRefFFTColIn ;
fftw_complex *pRefFFTColOut ;
pRefFFTColIn = (fftw_complex *)fftw_malloc(sizeof(fftw_complex) * nFFTRow);
pRefFFTColOut = (fftw_complex*) fftw_malloc(sizeof(fftw_complex) * nFFTRow);
fftw_plan p_for_ref2;
p_for_ref2 = fftw_plan_dft_1d(nFFTRow, pRefFFTColIn, pRefFFTColOut, FFTW_FORWARD,FFTW_ESTIMATE);
for(j=0;j<nFFTCol;j++)//行提取
{
pRefFFTColIn[j][0] = pRefFFTResult1T_re[i][j];
pRefFFTColIn[j][1] = pRefFFTResult1T_im[i][j];
}
fftw_execute(p_for_ref2);
for(j=0;j<nFFTCol;j++)
{
pRefFFTResult_re[i][j] = pRefFFTColOut[j][0];
pRefFFTResult_im[i][j] = pRefFFTColOut[j][1];
}
fftw_destroy_plan(p_for_ref2);
if(pRefFFTColIn!=NULL) fftw_free(pRefFFTColIn);
if(pRefFFTColOut!=NULL) fftw_free(pRefFFTColOut);
}
//转置
double **pRefFFTResultT_re = (double**)malloc(sizeof(double*)*nFFTRow);
double **pRefFFTResultT_im = (double**)malloc(sizeof(double*)*nFFTRow);
for(int i=0;i<nFFTRow;i++)
{
pRefFFTResultT_re[i] = (double*)malloc(sizeof(double)*nFFTCol);
pRefFFTResultT_im[i] = (double*)malloc(sizeof(double)*nFFTCol);
}
for (i=0; i<nFFTRow; i++)
{
for (j=0; j<nFFTCol;j++)
{
pRefFFTResultT_re[i][j] = pRefFFTResult_re[j][i];//最终结果的实部
pRefFFTResultT_im[i][j] = pRefFFTResult_im[j][i];//最终结果的虚部
}
}
注意:
1.首先将需要进行变换的图片根据输入一幅图片还是两幅图片进行按需要补零,因为FFT最好是变换2的n次幂点;
2.定义数组来保存中间结果并且做转置变换,注意此时需要自己定义double型的二维数组,不能直接用库里的fftw_complex来定义数组;
3.进行第一次fft后要转置再进行第二次fft,并且结果还要进行一次转置,ifft也一样
fftw3的说明文档:http://www.fftw.org/doc/Complex-One_002dDimensional-DFTs.html#Complex-One_002dDimensional-DFTs
最后
以上就是害怕唇彩为你收集整理的FFTW3的使用——对图像进行FFT的实例使用fftw_plan_dft_2d对图像进行FFT(常规方法)的全部内容,希望文章能够帮你解决FFTW3的使用——对图像进行FFT的实例使用fftw_plan_dft_2d对图像进行FFT(常规方法)所遇到的程序开发问题。
如果觉得靠谱客网站的内容还不错,欢迎将靠谱客网站推荐给程序员好友。
发表评论 取消回复