FFTW†Visual C++ でのインストール†
実数データの多次元DFT†実数データの多次元DFTには以下のプランナを用いる. fftw_plan fftw_plan_dft_r2c_2d(int n0, int n1, double *in, fftw_complex *out, unsigned flags); fftw_plan fftw_plan_dft_r2c_3d(int n0, int n1, int n2, double *in, fftw_complex *out, unsigned flags); fftw_plan fftw_plan_dft_r2c(int rank, const int *n, double *in, fftw_complex *out, unsigned flags); r2cはreal to complexのことであり,complex to real の場合は関数名のr2cをc2rに置き換えればよい. 出力のサイズが異なるのは,DFT変換後のデータがエルミート冗長性を持ち, out[i]がout[n-i]の共役になっており,メモリの節約のためにサイズを小さくしている. 描画などでフルデータが必要ならば for(int i = 0; i < w; ++i){ for(int j = 0; j < h; ++j){ double re, im; if(j >= h/2+1){ int j0 = h-j-1; re = out[j0+i*h1][0]; im = -out[j0+i*h1][1]; } else{ re = out[j+i*h1][0]; im = out[j+i*h1][1]; } } } のように変換する. 2次元の画像データからの変換例として, void FFTW_c2r(Array2 &reImg, Array2 &imImg, int w, int h) { fftw_complex *in; double *out; fftw_plan p; in = (fftw_complex*)fftw_malloc(sizeof(fftw_complex)*w*(h/2+1)); out = (double*)fftw_malloc(sizeof(double)*w*h); // プランナ設定 p = fftw_plan_dft_c2r_2d(w, h, in, out, FFTW_ESTIMATE); // for(int i = 0; i < w; ++i){ for(int j = 0; j < h/2+1; ++j){ in[j+(h/2+1)*i][0] = reImg[i][j]; in[j+(h/2+1)*i][1] = imImg[i][j]; } } fftw_execute(p); for(int i = 0; i < w; ++i){ for(int j = 0; j < h; ++j){ reImg[i][j] = out[j+h*i]; imImg[i][j] = 0.0; } } fftw_free(in); fftw_free(out); fftw_destroy_plan(p); } 2D FFTで得られたデータは四隅が低い周波数,中心が高い周波数の値を示している. 一般的な中心が低い周波数の状態にしたい場合は,第一象限と第三象限,第二象限と第四象限を入れ替えればよい. TIPS†
|