4

私は OpenCV と画像処理アルゴリズムの初心者です。C++ の OpenCV で逆離散フーリエ変換を行う必要がありますが、方法がわかりません。インターネットで検索しましたが、答えが見つかりませんでした。このページのコードを使用して、プログラムでフーリエ変換を行っています: http://opencv.itseez.com/doc/tutorials/core/discrete_fourier_transform/discrete_fourier_transform.html。そのコードとは逆のことをしようとしましたが、どこが間違っているのかわかりません。私のコードはここにあります(コード全体が間違っていると思います):

void doFourierInverse(const Mat &src, Mat &dst) {
  normalize(src, dst, 0, -1, CV_MINMAX); 

  int cx = dst.cols/2;
  int cy = dst.rows/2;

  Mat q0(dst, Rect(0, 0, cx, cy));   
  Mat q1(dst, Rect(cx, 0, cx, cy));  
  Mat q2(dst, Rect(0, cy, cx, cy));  
  Mat q3(dst, Rect(cx, cy, cx, cy)); 

  Mat tmp;         
  q0.copyTo(tmp);
  q3.copyTo(q0);
  tmp.copyTo(q3);

  q1.copyTo(tmp);      
  q2.copyTo(q1);
  tmp.copyTo(q2);

  dst = dst(Rect(0, 0, dst.cols & -2, dst.rows & -2));

  exp(dst, dst);
  dst -= Scalar::all(1);  

  Mat planes[2];

  polarToCart(dst, Mat::zeros(dst.rows, dst.cols, dst.type()), planes[0], planes[1]);

  merge(planes, 2, dst);    

  idft(dst, dst, DFT_INVERSE | DFT_SCALE); 

  split(dst, planes);   

  dst = planes[0];
}
4

1 に答える 1

17

実際には、異なる象限を交換する必要はありません。人間で、FFT 結果のより自然な視覚化が必要な場合にのみ必要です (つまり、0 周波数が中央、負周波数が左/下、正)周波数を上/右)。

FFT を反転するには、順変換の結果を「そのまま」(または必要な周波数フィルタリングの後に) 同じ dft() 関数に渡し、フラグ DFT_INVERSE のみを追加する必要があります。FFT に関する数学を覚えていれば、順方向変換と逆方向変換の定式化には非常にきついねじれがあります...

- - 編集 - -

何がうまくいかないのですか?次のコードは、順方向の後に逆方向の FFT を実行し、すべてが期待どおりに正常に機能します。

// Load an image
cv::Mat inputImage = cv::imread(argv[argc-1], 0);

// Go float
cv::Mat fImage;
inputImage.convertTo(fImage, CV_32F);

// FFT
std::cout << "Direct transform...\n";
cv::Mat fourierTransform;
cv::dft(fImage, fourierTransform, cv::DFT_SCALE|cv::DFT_COMPLEX_OUTPUT);

// Some processing
doSomethingWithTheSpectrum();

// IFFT
std::cout << "Inverse transform...\n";
cv::Mat inverseTransform;
cv::dft(fourierTransform, inverseTransform, cv::DFT_INVERSE|cv::DFT_REAL_OUTPUT);

// Back to 8-bits
cv::Mat finalImage;
inverseTransform.convertTo(finalImage, CV_8U);
于 2012-04-23T10:26:17.773 に答える