2017-08-04 69 views
0

我最近試圖爲Opencv's 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

我想出了我的問題。 這個函數寫成是完美的(至少爲了我的目的)。 我的問題是:

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); 

在這種情況下,正確的信息是存放在dstw但不是因爲函數內部的再分配的DST。 因此,當我嘗試將我的數據可視化時,我因此得到了黑色圖像。

正確的調用使用是:

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); 

與該代碼我得到了正確的輸出。

注意根據不同的應用程序中的投資回報率(看看到操作的OpenCV的墊容器()(常量CV ::矩形&)),對應於輸入的大小可能是爲了保持尺寸有用。

謝謝你的幫助:)。

有人可以幫我把這個話題標記得很近嗎?請。