離散フーリエ変換コード


以下のコードは私が以前ブログでノックしたものですが、時間が長くてどのブログで見たのか分からないので、アドレスリンクを与えることができず、削除しました.私は自分の理解に従ってコードに注釈をつけた.
#include
#include

using namespace cv;
using namespace std;

int main()
{
    Mat input = imread("C:\\Users\\dushuang\\Desktop\\lotsfiles\\bhs\\1.jpg",0);
    imshow("input", input);
    //FFT                             ,           
    //      ,             n                n/2             
    //         m           ,      ,          2   (2,4,8,16,32…)         ,
    //       2、3、5   (  :300 = 5*5*3*2*2)          。 
    int w = getOptimalDFTSize(input.cols);
    int h = getOptimalDFTSize(input.rows);
    Mat padded;
    copyMakeBorder(input, padded, 0, h - input.rows, 0, w - input.cols, BORDER_CONSTANT, Scalar::all(0));
    padded.convertTo(padded, CV_32FC1);//              
    imshow("padded", padded);//          ,  inshow    8U   ,32F        

    //     pow(-1,i+j)                   ,               
    for (int i = 0; i < padded.rows; i++)
    {
        float *ptr = padded.ptr<float>(i);
        for (int j = 0; j < padded.cols; j++)
            ptr[j] *= pow(-1, i + j);
    }

    Mat plane[] = { padded, Mat::zeros(padded.size(), CV_32F) };//    Mat           ,  Fm           Mat      
    Mat complexImg;
    merge(plane, 2, complexImg);// Mat            ,           。
    dft(complexImg, complexImg);//        ,      。

    /*****************gaussian*******************/
    Mat gaussianBlur(padded.size(), CV_32FC2);
    Mat gaussianSharpen(padded.size(), CV_32FC2);
    float D0 = 2 * 10 * 10;
    for (int i = 0; i < padded.rows; i++)//          
    {
        float*p = gaussianBlur.ptr<float>(i);
        float*q = gaussianSharpen.ptr<float>(i);
        for (int j = 0; j < padded.cols; j++)
        {
            float d = pow(i - padded.rows / 2, 2) + pow(j - padded.cols / 2, 2);//  d            
            p[2 * j] = expf(-d / D0);//gaussianBlur     ,expf return float exp.
            p[2 * j + 1] = expf(-d / D0);//gaussianBlur     

            q[2 * j] = 1 - expf(-d / D0);//gaossianShapen     
            q[2 * j + 1] = 1 - expf(-d / D0);//gaussianShapen     
        }
    }
    multiply(complexImg, gaussianBlur, gaussianBlur);//        ,  ,       
    multiply(complexImg, gaussianSharpen, gaussianSharpen);//           (              )
    /***********************       **************************/
    split(complexImg, plane);
    magnitude(plane[0], plane[1], plane[0]);//  
    plane[0] += Scalar::all(1);//    ,      log  
    log(plane[0], plane[0]);//     ,    。  1000 100          ,  2 3      。
    normalize(plane[0], plane[0], 1, 0, CV_MINMAX);
    imshow("dft", plane[0]);
    /*********************            ************************/
    split(gaussianBlur, plane);
    magnitude(plane[0], plane[1], plane[0]);
    plane[0] += Scalar::all(1);
    log(plane[0], plane[0]);
    normalize(plane[0], plane[0], 1, 0, CV_MINMAX);
    imshow("gaussianBlur", plane[0]);

    split(gaussianSharpen, plane);
    magnitude(plane[0], plane[1], plane[0]);
    plane[0] += Scalar::all(1);
    log(plane[0], plane[0]);
    normalize(plane[0], plane[0], 1, 0, CV_MINMAX);
    imshow("gaussianShapen", plane[0]);

    /************************idft*****************************/
    idft(gaussianBlur, gaussianBlur);//        
    idft(gaussianSharpen, gaussianSharpen);
    split(gaussianBlur, plane);
    magnitude(plane[0], plane[1], plane[0]);//      magnitude
    normalize(plane[0], plane[0], 1, 0, CV_MINMAX);
    imshow("idft-gaussianBlur", plane[0]);

    split(gaussianSharpen, plane);
    magnitude(plane[0], plane[1], plane[0]);
    normalize(plane[0], plane[0], 1, 0, CV_MINMAX);
    imshow("idft_gaussianSharpen", plane[0]);

    waitKey();
    return 0;
}

最初の3つの文章と結びつけて、このコードはとても理解しているはずです.ここでは、画像の周囲に0を記入する操作を行うと、画像の周波数領域サイズも大きくなりますが、0を記入しているので、周波数領域の画素値は私たちの空域値を係数としているので、係数は変化しませんが、私たちの基板のMとN値は変換されますが、変化は微小で、影響は大きくありません.