2011-07-31 25 views
2

与えられた画像の2次元グレースケールスペクトルを描画するプログラムを作成しようとしています。私はOpenCVとFFTWライブラリを使用しています。インターネットからヒントとコードを使用してイメージをロードし、イメージのfftを計算し、イメージをfftから再作成することができます(これは同じです)。私ができないのは、フーリエスペクトルそのものを描くことです。手伝っていただけませんか? ここで(重要度の低い線は除去)のコードは次のとおりC++(fftw、OpenCV)での画像の描画スペクトル

/* Copy input image */ 

/* Create output image */ 

/* Allocate input data for FFTW */ 
in = (fftw_complex*) fftw_malloc(sizeof(fftw_complex) * N); 
dft = (fftw_complex*) fftw_malloc(sizeof(fftw_complex) * N); 

/* Create plans */ 
plan_f = fftw_plan_dft_2d(w, h, in, dft, FFTW_FORWARD, FFTW_ESTIMATE); 

/* Populate input data in row-major order */ 
for (i = 0, k = 0; i < h; i++) 
{ 
    for (j = 0; j < w; j++, k++) 
    { 
     in[k][0] = ((uchar*)(img1->imageData + i * img1->widthStep))[j]; 
     in[k][1] = 0.; 
    } 
} 

/* forward DFT */ 
fftw_execute(plan_f); 

/* spectrum */ 
for (i = 0, k = 0; i < h; i++) 
{ 
    for (j = 0; j < w; j++, k++) 
     ((uchar*)(img2->imageData + i * img2->widthStep))[j] = sqrt(pow(dft[k][0],2) + pow(dft[k][1],2)); 
}  

cvShowImage("iplimage_dft(): original", img1); 
cvShowImage("iplimage_dft(): result", img2); 
cvWaitKey(0); 

/* Free memory */ 

}

問題は、「スペクトル」です。スペクトルの代わりに私はいくつかのノイズを取得します。私は間違って何をしていますか?私はあなたの助けに感謝します。

+0

スケーリングの問題のように聞こえる - FFT出力の大きさの範囲を確認する必要があります。 –

+0

それはどうすればいいのですか?私が異なるフォーラムで読んだことから、大きさについては、黒いイメージ(中央に白い点)があります。あなたの答えをありがとう。 – Narren

+1

マグニチュードのレンジチェックをしていないので、大きければ8ビットピクセルに割り当てるとモジュロ2をラップします(ノイズのように見えます)。そのため、範囲を確認する必要があります(例:別のループを追加して最大値と最小値を見つけ、それに応じて値をスケールし、8ビットの範囲に収まることを確認します。 –

答えて

0

IFFTステップを実行して元の画像を復元することができますか?問題がどこにあるかを段階的に確認することができます。問題を見つけるもう一つの解決策は、あなたが事前に定義した小さな行列を使ってこのプロセスを行い、MATLABでFFTを計算し、ステップごとにチェックすることです。

1

スペクトルの大きさを描く必要があります。ここにコードがあります。

void ForwardFFT(Mat &Src, Mat *FImg) 
{ 
    int M = getOptimalDFTSize(Src.rows); 
    int N = getOptimalDFTSize(Src.cols); 
    Mat padded;  
    copyMakeBorder(Src, padded, 0, M - Src.rows, 0, N - Src.cols, BORDER_CONSTANT, Scalar::all(0)); 
    // Создаем комплексное представление изображения 
    // planes[0] содержит само изображение, planes[1] его мнимую часть (заполнено нулями) 
    Mat planes[] = {Mat_<float>(padded), Mat::zeros(padded.size(), CV_32F)}; 
    Mat complexImg; 
    merge(planes, 2, complexImg); 
    dft(complexImg, complexImg);  
    // После преобразования результат так-же состоит из действительной и мнимой части 
    split(complexImg, planes); 

    // обрежем спектр, если у него нечетное количество строк или столбцов 
    planes[0] = planes[0](Rect(0, 0, planes[0].cols & -2, planes[0].rows & -2)); 
    planes[1] = planes[1](Rect(0, 0, planes[1].cols & -2, planes[1].rows & -2)); 

    Recomb(planes[0],planes[0]); 
    Recomb(planes[1],planes[1]); 
    // Нормализуем спектр 
    planes[0]/=float(M*N); 
    planes[1]/=float(M*N); 
    FImg[0]=planes[0].clone(); 
    FImg[1]=planes[1].clone(); 
} 
void ForwardFFT_Mag_Phase(Mat &src, Mat &Mag,Mat &Phase) 
{ 
    Mat planes[2]; 
    ForwardFFT(src,planes); 
    Mag.zeros(planes[0].rows,planes[0].cols,CV_32F); 
    Phase.zeros(planes[0].rows,planes[0].cols,CV_32F); 
    cv::cartToPolar(planes[0],planes[1],Mag,Phase); 
} 
Mat LogMag; 
    LogMag.zeros(Mag.rows,Mag.cols,CV_32F); 
    LogMag=(Mag+1); 
    cv::log(LogMag,LogMag); 
    //--------------------------------------------------- 
    imshow("Логарифм амплитуды", LogMag); 
    imshow("Фаза", Phase); 
    imshow("Результат фильтрации", img);