在MFC里添加了一个函数,涉及到傅立叶变换,使用的是FFT蝶形算法
奇怪的是,对图像补零使其满足长宽为2幂次方后变换,如果是1024*1024,512*512这类,反变换得到正确图像
如果是1024*512,512*256这类,反变换图像跟原图像差距很大,灰度改变,还有帘状条纹
哪位遇到过这种情况的指点一下

解决方案 »

  1.   

    1024*512的图像不用补零了,反复尝试发现好像是算法本身的问题,但我又找不出毛病,
    为了避免补零,我变换的就是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 ;}
      

  2.   

    补充一下:
    VOID WINAPI FFT_2D(complex <double> * pCTData, int nWidth, int nHeight, complex <double> * pCFData) 
    pCTData 是时域数据指针 
    nWidth 数据宽度,已经是2幂
    nHeight 高度
    pCFData 频域数据指针
      

  3.   

    搞定了。FFT——2D的问题,最后memcpy()反了。惭~