]> rtime.felk.cvut.cz Git - hercules2020/kcf.git/commitdiff
Added New-array Execute function support for FFTW.
authorShanigen <vkaraf@gmail.com>
Tue, 13 Mar 2018 10:43:18 +0000 (11:43 +0100)
committerShanigen <vkaraf@gmail.com>
Tue, 13 Mar 2018 10:43:18 +0000 (11:43 +0100)
src/fft_fftw.cpp
src/fft_fftw.h

index 1ff851609b6481a3bb532100d6b74c81ac81ac55..a26aeee255bcdf33251164468ca6f178d5345b50 100644 (file)
@@ -1,11 +1,6 @@
 #include "fft_fftw.h"
 
 #include "fft.h"
-#ifndef CUFFTW
-  #include <fftw3.h>
-#else
-  #include <cufftw.h>
-#endif //CUFFTW
 
 #ifdef OPENMP
   #include <omp.h>
@@ -19,8 +14,12 @@ void Fftw::init(unsigned width, unsigned height)
 {
     m_width = width;
     m_height = height;
+    plan_f = NULL;
+    plan_fw = NULL;
+    plan_if = NULL;
+    plan_ir = NULL;
 
-#if defined(ASYNC) || defined(OPENMP)
+-#if defined(ASYNC) || defined(OPENMP)
     fftw_init_threads();
 #endif //OPENMP
 
@@ -39,31 +38,23 @@ void Fftw::set_window(const cv::Mat &window)
 ComplexMat Fftw::forward(const cv::Mat &input)
 {
     cv::Mat complex_result(m_height, m_width / 2 + 1, CV_32FC2);
+
+    if(!plan_f){
 #ifdef ASYNC
-    std::unique_lock<std::mutex> lock(fftw_mut);
-    fftw_plan_with_nthreads(2);
+        std::unique_lock<std::mutex> lock(fftw_mut);
+        fftw_plan_with_nthreads(2);
 #elif OPENMP
 #pragma omp critical
-    fftw_plan_with_nthreads(omp_get_max_threads());
+        fftw_plan_with_nthreads(omp_get_max_threads());
 #endif
-fftwf_plan plan;
 #pragma omp critical
-    plan = fftwf_plan_dft_r2c_2d(m_height, m_width,
-                                            reinterpret_cast<float*>(input.data),
-                                            reinterpret_cast<fftwf_complex*>(complex_result.data),
-                                            FFTW_ESTIMATE);
-#ifdef ASYNC
-    lock.unlock();
-#endif
-    fftwf_execute(plan);
-#ifdef ASYNC
-    lock.lock();
-#endif
-#pragma omp critical
-    fftwf_destroy_plan(plan);
-#ifdef ASYNC
-    lock.unlock();
-#endif
+        plan_f = fftwf_plan_dft_r2c_2d(m_height, m_width,
+                                                  reinterpret_cast<float*>(input.data),
+                                                  reinterpret_cast<fftwf_complex*>(complex_result.data),
+                                                  FFTW_ESTIMATE);
+        fftwf_execute(plan_f);
+    }else{fftwf_execute_dft_r2c(plan_f,reinterpret_cast<float*>(input.data),reinterpret_cast<fftwf_complex*>(complex_result.data));}
+
     return ComplexMat(complex_result);
 }
 
@@ -77,39 +68,29 @@ ComplexMat Fftw::forward_window(const std::vector<cv::Mat> &input)
     }
     cv::Mat complex_result(n_channels*m_height, m_width/2+1, CV_32FC2);
 
-    int rank = 2;
-    int n[] = {(int)m_height, (int)m_width};
-    int howmany = n_channels;
-    int idist = m_height*m_width, odist = m_height*(m_width/2+1);
-    int istride = 1, ostride = 1;
-    int *inembed = NULL, *onembed = NULL;
     float *in = reinterpret_cast<float*>(in_all.data);
     fftwf_complex *out = reinterpret_cast<fftwf_complex*>(complex_result.data);
-#ifdef ASYNC
-    std::unique_lock<std::mutex> lock(fftw_mut);
-    fftw_plan_with_nthreads(2);
-#elif OPENMP
+    if(!plan_fw){
+        int rank = 2;
+        int n[] = {(int)m_height, (int)m_width};
+        int howmany = n_channels;
+        int idist = m_height*m_width, odist = m_height*(m_width/2+1);
+        int istride = 1, ostride = 1;
+        int *inembed = NULL, *onembed = NULL;
 #pragma omp critical
-    fftw_plan_with_nthreads(omp_get_max_threads());
-#endif
-fftwf_plan plan;
-#pragma omp critical
-    plan = fftwf_plan_many_dft_r2c(rank, n, howmany,
-                                              in,  inembed, istride, idist,
-                                              out, onembed, ostride, odist,
-                                              FFTW_ESTIMATE);
-#ifdef ASYNC
-    lock.unlock();
-#endif
-    fftwf_execute(plan);
 #ifdef ASYNC
-    lock.lock();
-#endif
+        std::unique_lock<std::mutex> lock(fftw_mut);
+        fftw_plan_with_nthreads(2);
+#elif OPENMP
 #pragma omp critical
-    fftwf_destroy_plan(plan);
-#ifdef ASYNC
-    lock.unlock();
+        fftw_plan_with_nthreads(omp_get_max_threads());
 #endif
+        plan_fw = fftwf_plan_many_dft_r2c(rank, n, howmany,
+                                                     in,  inembed, istride, idist,
+                                                     out, onembed, ostride, odist,
+                                                     FFTW_ESTIMATE);
+        fftwf_execute(plan_fw);
+    }else{fftwf_execute_dft_r2c(plan_fw,in,out);}
 
     ComplexMat result(m_height, m_width/2 + 1, n_channels);
     for (int i = 0; i < n_channels; ++i)
@@ -124,48 +105,76 @@ cv::Mat Fftw::inverse(const ComplexMat &inputf)
     cv::Mat real_result(m_height, m_width, CV_32FC(n_channels));
     cv::Mat complex_vconcat = inputf.to_vconcat_mat();
 
-    int rank = 2;
-    int n[] = {(int)m_height, (int)m_width};
-    int howmany = n_channels;
-    int idist = m_height*(m_width/2+1), odist = 1;
-    int istride = 1, ostride = n_channels;
+    fftwf_complex *in = reinterpret_cast<fftwf_complex*>(complex_vconcat.data);
+    float *out = reinterpret_cast<float*>(real_result.data);
+
+    if(n_channels != 1){
+        if(!plan_if){
+            int rank = 2;
+            int n[] = {(int)m_height, (int)m_width};
+            int howmany = n_channels;
+            int idist = m_height*(m_width/2+1), odist = 1;
+            int istride = 1, ostride = n_channels;
 #ifndef CUFFTW
-    int *inembed = NULL, *onembed = NULL;
+            int *inembed = NULL, *onembed = NULL;
 #else
-    int inembed[2];
-    int onembed[2];
-    inembed[1] = m_width/2+1, onembed[1] = m_width;
+            int inembed[2];
+            int onembed[2];
+            inembed[1] = m_width/2+1, onembed[1] = m_width;
 #endif
-    fftwf_complex *in = reinterpret_cast<fftwf_complex*>(complex_vconcat.data);
-    float *out = reinterpret_cast<float*>(real_result.data);
+
 #ifdef ASYNC
-    std::unique_lock<std::mutex> lock(fftw_mut);
-    fftw_plan_with_nthreads(2);
+            std::unique_lock<std::mutex> lock(fftw_mut);
+            fftw_plan_with_nthreads(2);
 #elif OPENMP
 #pragma omp critical
-    fftw_plan_with_nthreads(omp_get_max_threads());
+            fftw_plan_with_nthreads(omp_get_max_threads());
 #endif
-fftwf_plan plan;
 #pragma omp critical
-    plan = fftwf_plan_many_dft_c2r(rank, n, howmany,
-                                              in,  inembed, istride, idist,
-                                              out, onembed, ostride, odist,
-                                              FFTW_ESTIMATE);
-#ifdef ASYNC
-    lock.unlock();
+            plan_if = fftwf_plan_many_dft_c2r(rank, n, howmany,
+                                                         in,  inembed, istride, idist,
+                                                         out, onembed, ostride, odist,
+                                                         FFTW_ESTIMATE);
+            fftwf_execute(plan_if);
+        }else{fftwf_execute_dft_c2r(plan_if,in,out);}
+    }else{
+        if(!plan_ir){
+            int rank = 2;
+            int n[] = {(int)m_height, (int)m_width};
+            int howmany = n_channels;
+            int idist = m_height*(m_width/2+1), odist = 1;
+            int istride = 1, ostride = n_channels;
+#ifndef CUFFTW
+            int *inembed = NULL, *onembed = NULL;
+#else
+            int inembed[2];
+            int onembed[2];
+            inembed[1] = m_width/2+1, onembed[1] = m_width;
 #endif
-    fftwf_execute(plan);
+
 #ifdef ASYNC
-    lock.lock();
-#endif
+            std::unique_lock<std::mutex> lock(fftw_mut);
+            fftw_plan_with_nthreads(2);
+#elif OPENMP
 #pragma omp critical
-    fftwf_destroy_plan(plan);
-#ifdef ASYNC
-    lock.unlock();
+            fftw_plan_with_nthreads(omp_get_max_threads());
 #endif
+#pragma omp critical
+            plan_ir = fftwf_plan_many_dft_c2r(rank, n, howmany,
+                                                         in,  inembed, istride, idist,
+                                                         out, onembed, ostride, odist,
+                                                         FFTW_ESTIMATE);
+            fftwf_execute(plan_ir);
+    }else{fftwf_execute_dft_c2r(plan_ir,in,out);}
+  }
+
     return real_result/(m_width*m_height);
 }
 
 Fftw::~Fftw()
 {
+  fftwf_destroy_plan(plan_f);
+  fftwf_destroy_plan(plan_fw);
+  fftwf_destroy_plan(plan_if);
+  fftwf_destroy_plan(plan_ir);
 }
index 028ba6f68be96dd6d0f137025da53b6ae25d8821..e983cca534eaf3af18bfcaaa86b99ad977d53030 100644 (file)
@@ -8,6 +8,12 @@
 #include <mutex>
 #endif
 
+#ifndef CUFFTW
+  #include <fftw3.h>
+#else
+  #include <cufftw.h>
+#endif //CUFFTW
+
 class Fftw : public Fft
 {
 public:
@@ -21,6 +27,7 @@ public:
 private:
     unsigned m_width, m_height;
     cv::Mat m_window;
+    fftwf_plan plan_f, plan_fw, plan_if, plan_ir;
 #if defined(ASYNC)
     std::mutex fftw_mut;
 #endif