2017-08-04 63 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 ::矩形&)),对应于输入的大小可能是为了保持尺寸有用。

谢谢你的帮助:)。

有人可以帮我把这个话题标记得很近吗?请。