2017-08-04 21 views
0

私は最近、OpencvのMatのFFT関数を実装しようとしました。私は、FFTWのコードサンプルから主に私の実装を触発してから : FFTW-OpenCVfftw + opencv一貫性のない出力

私が処理を固定するために、入力画像のサイズを適応させるために細心の注意を払って。 出力が常に黒いイメージなので、私は何か間違っているようです。ここで

は私の実装です:

void fft2_32f(const cv::Mat1f& _src, cv::Mat2f& dst) 
    { 

     cv::Mat2f src; 

     const int rows = cv::getOptimalDFTSize(_src.rows); 
     const int cols = cv::getOptimalDFTSize(_src.cols); 

    // const int total = cv::alignSize(rows*cols,steps); 


     if(_src.isContinuous() && _src.rows == rows && _src.cols == cols) 
     { 

      src = cv::Mat2f::zeros(src.size()); 
      dst = cv::Mat2f::zeros(src.size()); 

      // 1) copy the source into a complex matrix (the imaginary component is set to 0). 

      cblas_scopy(src.total(), _src.ptr<float>(), 1, src.ptr<float>(), 2); 

      // 2) prepare and apply the transform. 

      fftwf_complex* ptr_in = reinterpret_cast<fftwf_complex*>(src.ptr<float>()); 
      fftwf_complex* ptr_out = reinterpret_cast<fftwf_complex*>(dst.ptr<float>()); 

    //  fftwf_plan fft = fftwf_plan_dft_1d(src.total(), ptr_in, ptr_out, FFTW_FORWARD, FFTW_ESTIMATE); 
      fftwf_plan fft = fftwf_plan_dft_2d(src.rows, src.cols, ptr_in, ptr_out, FFTW_FORWARD, FFTW_ESTIMATE); 

      fftwf_execute(fft); 
      fftwf_destroy_plan(fft); 

      // 3) normalize 

      cblas_saxpy(dst.rows * dst.step1(), 1.f/dst.total(), dst.ptr<float>(), 1, dst.ptr<float>(), 1); 

     } 
     else 
     { 

      src = cv::Mat2f::zeros(rows, cols); 
      dst = cv::Mat2f::zeros(rows, cols); 

      // 1) copy the source into a complex matrix (the imaginary component is set to 0). 

      support::parallel_for(cv::Range(0, _src.rows), [&src, &_src](const cv::Range& range)->void 
      { 

       for(int r=range.start; r<range.end; r++) 
       { 
        int c=0; 

        const float* it_src = _src[r]; 
        float* it_dst = src.ptr<float>(r); 

    #if CV_ENABLE_UNROLLED 
        for(;c<=_src.cols-4; c+=4, it_src+=4, it_dst+=8) 
        { 
         *it_dst = *it_src; 
         *(it_dst+2) = *(it_src+1); 
         *(it_dst+4) = *(it_src+2); 
         *(it_dst+6) = *(it_src+3); 
        } 
    #endif 
        for(; c<_src.cols; c++, it_src++, it_dst+=2) 
         *it_dst = *it_src; 
       } 
      }, 0x80); 

      // 2) prepare and apply the transform. 

      fftwf_complex* ptr_in = reinterpret_cast<fftwf_complex*>(src.ptr<float>()); 
      fftwf_complex* ptr_out = reinterpret_cast<fftwf_complex*>(dst.ptr<float>()); 

      fftwf_plan fft = fftwf_plan_dft_2d(src.rows, src.cols, ptr_in, ptr_out, FFTW_FORWARD, FFTW_ESTIMATE); 

      fftwf_execute(fft); 
      fftwf_destroy_plan(fft); 

      double min(0.); 
      double max(0.); 

      // 3) normalize 

      cblas_saxpy(dst.rows * dst.step1(), 1.f/dst.total(), dst.ptr<float>(), 1, dst.ptr<float>(), 1); 

     }  
    } 

注:任意の助けを事前にHow to use lambda as a parameter to parallel_for_

ありがとう:

parallel_for実装が触発されています。

+0

連続バージョンは機能しますか?正規化を削除したり、 'fftw_execute'の直後に削除しても機能しますか?これをデバッグする方法はたくさんあります... –

+0

実際、fftはどちらの場合も連続データに適用されます。最初のケースでは、イメージサイズが最適なDFTディメンションに合っていると、データを複素行列にコピーする方が高速です。 しかし、それらのうちのどれもうまくいきません。 –

答えて

0

私の問題を解明します。 この関数は、(少なくとも私が作った目的のために)完全に動作します。正しい情報が原因関数の内部で再配分のDSTにdstwに店舗ではなく、その場合には

cv::Mat dst = cv::Mat::zeros(src.size(), CV_32FC2); 

cv::Mat1f srcw = src; 
cv::Mat1f dstw = dst; 

fft2_32f(srcw, dstw); // realocate dstw to the optimal size for receive the output depending on the size of srcw. ... so the dstw is reallocate but not dst. 

dst.copyTo(_outputVariable); 

: 私の問題は、ということでした。 私は私のデータを視覚化しようとすると、そのために私は黒い画像を持っていました。

なるように適切なコールを使用:

cv::Mat dst; 

cv::Mat1f srcw = src; 
cv::Mat1f dstw; 

fft2_32f(srcw, dstw); // realocate dstw to the optimal size for receive the output depending on the size of srcw. ... so the dstw is reallocate but not dst. 

dst = dstw; 

dst.copyTo(_outputVariable); // or dstw.copyTo(_outputVariable); 

そのコードで、私は適切な出力を得ました。

アプリケーションによっては、入力のサイズに対応するroi(OpenCVのMatコンテナのoperator()(const cv :: Rect &)を参照してください)は、寸法を保持するのに便利です。

ありがとうございました:)

このトピックを近くにマークするのに役立つ人はいますか?お願いします。

関連する問題