]> rtime.felk.cvut.cz Git - hercules2020/kcf.git/commitdiff
Big batch update (not finished)
authorShanigen <vkaraf@gmail.com>
Wed, 21 Mar 2018 18:52:09 +0000 (19:52 +0100)
committerShanigen <vkaraf@gmail.com>
Wed, 21 Mar 2018 18:52:09 +0000 (19:52 +0100)
src/complexmat.hpp
src/fft_fftw.cpp
src/fft_fftw.h
src/kcf.cpp

index be35ea3bfcaef0a1225107340b85e0fbe7d82efd..a189229421119b97bb6e49c0bca8abefac54c155 100644 (file)
@@ -12,6 +12,7 @@ public:
     int cols;
     int rows;
     int n_channels;
+    int n_scales = 1;
 
     ComplexMat_() : cols(0), rows(0), n_channels(0) {}
     ComplexMat_(int _rows, int _cols, int _n_channels) : cols(_cols), rows(_rows), n_channels(_n_channels)
@@ -19,6 +20,7 @@ public:
         p_data.resize(n_channels*cols*rows);
     }
 
+
     //assuming that mat has 2 channels (real, img)
     ComplexMat_(const cv::Mat & mat) : cols(mat.cols), rows(mat.rows), n_channels(1)
     {
@@ -29,9 +31,15 @@ public:
     {
         p_data = data;
     }
+
+    ComplexMat_(int _rows, int _cols, int _n_channels,int _n_scales) : cols(_cols), rows(_rows), n_channels(_n_channels), n_scales(_n_scales)
+    {
+        p_data.resize(n_channels*cols*rows);
+    }
     // cv::Mat API compatibility
     cv::Size size() { return cv::Size(cols, rows); }
     int channels() { return n_channels; }
+    int channels() const { return n_channels; }
 
     //assuming that mat has 2 channels (real, imag)
     void set_channel(int idx, const cv::Mat & mat)
@@ -138,6 +146,12 @@ public:
         return matn_mat1_operator( [](std::complex<T> & c_lhs, const std::complex<T> & c_rhs) { c_lhs *= c_rhs; }, rhs);
     }
 
+    //multiplying element-wise multichannel by one channel mats (rhs mat is with multiple channel)
+    ComplexMat_<T> mul2(const ComplexMat_<T> & rhs) const
+    {
+        return matn_mat2_operator( [](std::complex<T> & c_lhs, const std::complex<T> & c_rhs) { c_lhs *= c_rhs; }, rhs);
+    }
+
     //text output
     friend std::ostream & operator<<(std::ostream & os, const ComplexMat_<T> & mat)
     {
@@ -199,6 +213,24 @@ private:
 
         return result;
     }
+    ComplexMat_<T> matn_mat2_operator(void (*op)(std::complex<T> & c_lhs, const std::complex<T> & c_rhs), const ComplexMat_<T> & mat_rhs) const
+    {
+        assert(mat_rhs.n_channels == n_channels/n_scales && mat_rhs.cols == cols && mat_rhs.rows == rows);
+
+        int n_channels_per_scale = n_channels/n_scales;
+        int scale_offset = n_channels_per_scale*rows*cols;
+        ComplexMat_<T> result = *this;
+        for (int i = 0; i < n_scales; ++i) {
+            for (int j = 0; j < n_channels_per_scale; ++j) {
+                auto lhs = result.p_data.begin()+(j*rows*cols)+(i*scale_offset);
+                auto rhs = mat_rhs.p_data.begin()+(j*rows*cols);
+                for ( ; lhs != result.p_data.begin()+((i+1)*rows*cols)+(i*scale_offset); ++lhs, ++rhs)
+                    op(*lhs, *rhs);
+            }
+        }
+
+        return result;
+    }
     ComplexMat_<T> mat_const_operator(const std::function<void(std::complex<T> & c_rhs)> & op) const
     {
         ComplexMat_<T> result = *this;
index 26f7887efcf27b3ea8d424efc7f7d82669b58775..7474657db24a1da901b1a0a2eb351f8a19393cbd 100644 (file)
@@ -6,9 +6,9 @@
   #include <omp.h>
 #endif
 
-#ifdef ASYNC
+#if defined(ASYNC) && !defined(CUFFTW)
 #define FFTW_PLAN_WITH_THREADS() fftw_plan_with_nthreads(m_num_threads);
-#elif OPENMP
+#elif defined(OPENMP) && !defined(CUFFTW)
 #define FFTW_PLAN_WITH_THREADS() fftw_plan_with_nthreads(omp_get_max_threads());
 #else
 #define FFTW_PLAN_WITH_THREADS()
@@ -40,7 +40,7 @@ void Fftw::init(unsigned width, unsigned height, unsigned num_of_feats, unsigned
 #else
     std::cout << "FFT: cuFFTW" << std::endl;
 #endif
-
+    //FFT forward one scale
     {
     cv::Mat in_f = cv::Mat::zeros(m_height, m_width, CV_32FC1);
     ComplexMat out_f(m_height, m_width / 2 + 1, 1);
@@ -49,7 +49,27 @@ void Fftw::init(unsigned width, unsigned height, unsigned num_of_feats, unsigned
                                    reinterpret_cast<fftwf_complex*>(out_f.get_p_data()),
                                    FFTW_MEASURE);
     }
-
+    //FFT forward all scales
+    if(num_of_scales > 1)
+    {
+    cv::Mat in_f_all = cv::Mat::zeros(m_height*m_num_of_scales, m_width, CV_32FC1);
+    ComplexMat out_f_all(m_height, m_width / 2 + 1, m_num_of_scales);
+    float *in = reinterpret_cast<float*>(in_f_all.data);
+    fftwf_complex *out = reinterpret_cast<fftwf_complex*>(out_f_all.get_p_data());
+    int rank = 2;
+    int n[] = {(int)m_height, (int)m_width};
+    int howmany = m_num_of_scales;
+    int idist = m_height*m_width, odist = m_height*(m_width/2+1);
+    int istride = 1, ostride = 1;
+    int *inembed = NULL, *onembed = NULL;
+
+    FFTW_PLAN_WITH_THREADS();
+    plan_f_all_scales = fftwf_plan_many_dft_r2c(rank, n, howmany,
+                                      in, inembed, istride, idist,
+                                      out, onembed, ostride, odist,
+                                      FFTW_MEASURE);
+    }
+    //FFT forward window one scale
     {
         cv::Mat in_fw = cv::Mat::zeros(m_height * m_num_of_feats, m_width, CV_32F);
         ComplexMat out_fw(m_height, m_width / 2 + 1, m_num_of_feats);
@@ -68,6 +88,7 @@ void Fftw::init(unsigned width, unsigned height, unsigned num_of_feats, unsigned
                                           out, onembed, ostride, odist,
                                           FFTW_MEASURE);
     }
+    //FFT forward window all scales all feats
     if(num_of_scales > 1)
     {
         cv::Mat in_all = cv::Mat::zeros(m_height * (num_of_scales*m_num_of_feats), m_width, CV_32F);
@@ -76,7 +97,7 @@ void Fftw::init(unsigned width, unsigned height, unsigned num_of_feats, unsigned
         fftwf_complex *out = reinterpret_cast<fftwf_complex*>(out_all.get_p_data());
         int rank = 2;
         int n[] = {(int)m_height, (int)m_width};
-        int howmany = num_of_scales*m_num_of_feats;
+        int howmany = m_num_of_scales*m_num_of_feats;
         int idist = m_height*m_width, odist = m_height*(m_width/2+1);
         int istride = 1, ostride = 1;
         int *inembed = NULL, *onembed = NULL;
@@ -87,7 +108,7 @@ void Fftw::init(unsigned width, unsigned height, unsigned num_of_feats, unsigned
                                                      out, onembed, ostride, odist,
                                                      FFTW_MEASURE);
     }
-
+    //FFT inverse one scale
     {
         ComplexMat in_i(m_height,m_width,m_num_of_feats);
         cv::Mat out_i = cv::Mat::zeros(m_height, m_width, CV_32FC(m_num_of_feats));
@@ -106,7 +127,27 @@ void Fftw::init(unsigned width, unsigned height, unsigned num_of_feats, unsigned
                                                   out, onembed, ostride, odist,
                                                   FFTW_MEASURE);
     }
+    //FFT inverse all scales
+    if(num_of_scales > 1)
+    {
+        ComplexMat in_i_all(m_height,m_width,m_num_of_feats*m_num_of_scales);
+        cv::Mat out_i_all = cv::Mat::zeros(m_height, m_width, CV_32FC(m_num_of_feats*m_num_of_scales));
+        fftwf_complex *in = reinterpret_cast<fftwf_complex*>(in_i_all.get_p_data());
+        float *out = reinterpret_cast<float*>(out_i_all.data);
+        int rank = 2;
+        int n[] = {(int)m_height, (int)m_width};
+        int howmany = m_num_of_feats*m_num_of_scales;
+        int idist = m_height*(m_width/2+1), odist = 1;
+        int istride = 1, ostride = m_num_of_feats;
+        int inembed[] = {(int)m_height, (int)m_width/2+1}, *onembed = n;
 
+        FFTW_PLAN_WITH_THREADS();
+        plan_i_features_all_scales = fftwf_plan_many_dft_c2r(rank, n, howmany,
+                                                  in,  inembed, istride, idist,
+                                                  out, onembed, ostride, odist,
+                                                  FFTW_MEASURE);
+    }
+    //FFT inver one channel one scale
     {
         ComplexMat in_i1(m_height,m_width,1);
         cv::Mat out_i1 = cv::Mat::zeros(m_height, m_width, CV_32FC1);
@@ -125,6 +166,26 @@ void Fftw::init(unsigned width, unsigned height, unsigned num_of_feats, unsigned
                                              out, onembed, ostride, odist,
                                              FFTW_MEASURE);
     }
+    //FFT inver one channel all scales
+    if(num_of_scales > 1)
+    {
+        ComplexMat in_i1_all(m_height,m_width,m_num_of_scales);
+        cv::Mat out_i1_all = cv::Mat::zeros(m_height, m_width, CV_32FC(m_num_of_scales));
+        fftwf_complex *in = reinterpret_cast<fftwf_complex*>(in_i1_all.get_p_data());
+        float *out = reinterpret_cast<float*>(out_i1_all.data);
+        int rank = 2;
+        int n[] = {(int)m_height, (int)m_width};
+        int howmany = m_num_of_scales;
+        int idist = m_height*(m_width/2+1), odist = 1;
+        int istride = 1, ostride = 1;
+        int inembed[] = {(int)m_height, (int)m_width/2+1}, *onembed = n;
+
+        FFTW_PLAN_WITH_THREADS();
+        plan_i_1ch_all_scales = fftwf_plan_many_dft_c2r(rank, n, howmany,
+                                             in,  inembed, istride, idist,
+                                             out, onembed, ostride, odist,
+                                             FFTW_MEASURE);
+    }
 }
 
 void Fftw::set_window(const cv::Mat &window)
@@ -134,9 +195,9 @@ 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);
+    ComplexMat complex_result(m_height, m_width / 2 + 1, 1);
 
-    fftwf_execute_dft_r2c(plan_f,reinterpret_cast<float*>(input.data),reinterpret_cast<fftwf_complex*>(complex_result.data));
+    fftwf_execute_dft_r2c(plan_f,reinterpret_cast<float*>(input.data),reinterpret_cast<fftwf_complex*>(complex_result.get_p_data()));
 
     return ComplexMat(complex_result);
 }
@@ -154,7 +215,7 @@ ComplexMat Fftw::forward_window(const std::vector<cv::Mat> &input)
     float *in = reinterpret_cast<float*>(in_all.data);
     fftwf_complex *out = reinterpret_cast<fftwf_complex*>(result.get_p_data());
 
-    if (n_channels <= 44)
+    if (n_channels <= m_num_of_feats)
         fftwf_execute_dft_r2c(plan_fw, in, out);
     else
         fftwf_execute_dft_r2c(plan_fw_all_scales, in, out);
@@ -180,8 +241,11 @@ cv::Mat Fftw::inverse(const ComplexMat &inputf)
 Fftw::~Fftw()
 {
   fftwf_destroy_plan(plan_f);
+  fftwf_destroy_plan(plan_f_all_scales);
   fftwf_destroy_plan(plan_fw);
   fftwf_destroy_plan(plan_fw_all_scales);
   fftwf_destroy_plan(plan_i_features);
+  fftwf_destroy_plan(plan_i_features_all_scales);
   fftwf_destroy_plan(plan_i_1ch);
+  fftwf_destroy_plan(plan_i_1ch_all_scales);
 }
index 12ae4df3828e2d4d650a694b97c46352d83747ff..9ca65b9ea164d8599ba5bed489cb636e9d15a70a 100644 (file)
@@ -29,7 +29,8 @@ private:
     unsigned m_num_threads = 6;
     unsigned m_width, m_height, m_num_of_feats,m_num_of_scales;
     cv::Mat m_window;
-    fftwf_plan plan_f, plan_fw, plan_fw_all_scales, plan_i_features, plan_i_1ch;
+    fftwf_plan plan_f, plan_f_all_scales, plan_fw, plan_fw_all_scales, plan_i_features,
+     plan_i_features_all_scales, plan_i_1ch, plan_i_1ch_all_scales;
 };
 
 #endif // FFT_FFTW_H
index 4bca69cb8086eab016d527d9a0c4f22e0453ec7c..898fbabad800458fcdd7e0409489d277638151b4 100644 (file)
@@ -239,11 +239,11 @@ void KCF_Tracker::track(cv::Mat &img)
             ComplexMat zf = fft.forward_window(patch_feat);
             DEBUG_PRINTM(zf);
             cv::Mat response;
-        for (size_t i = 0; i < p_scales.size(); ++i) {
+
             if (m_use_linearkernel)
-                response = fft.inverse((p_model_alphaf * zf.get_part(i,num_of_feats)).sum_over_channels());
+                response = fft.inverse((zf.mul2(p_model_alphaf)).sum_over_channels());
             else {
-                ComplexMat kzf = gaussian_correlation(zf.get_part(i,num_of_feats), p_model_xf, p_kernel_sigma);
+                ComplexMat kzf = gaussian_correlation(zf, p_model_xf, p_kernel_sigma);
                 DEBUG_PRINTM(p_model_alphaf);
                 DEBUG_PRINTM(kzf);
                 DEBUG_PRINTM(p_model_alphaf * kzf);
@@ -255,20 +255,21 @@ void KCF_Tracker::track(cv::Mat &img)
                account the fact that, if the target doesn't move, the peak
                will appear at the top-left corner, not at the center (this is
                discussed in the paper). the responses wrap around cyclically. */
-            double min_val, max_val;
-            cv::Point2i min_loc, max_loc;
-            cv::minMaxLoc(response, &min_val, &max_val, &min_loc, &max_loc);
-            DEBUG_PRINT(max_loc);
+            for (size_t i = 0; i < p_scales.size(); ++i) {
+                double min_val, max_val;
+                cv::Point2i min_loc, max_loc;
+                cv::minMaxLoc(response, &min_val, &max_val, &min_loc, &max_loc);
+                DEBUG_PRINT(max_loc);
 
-            double weight = p_scales[i] < 1. ? p_scales[i] : 1./p_scales[i];
-            if (max_val*weight > max_response) {
-                max_response = max_val*weight;
-                max_response_map = response;
-                max_response_pt = max_loc;
-                scale_index = i;
+                double weight = p_scales[i] < 1. ? p_scales[i] : 1./p_scales[i];
+                if (max_val*weight > max_response) {
+                    max_response = max_val*weight;
+                    max_response_map = response;
+                    max_response_pt = max_loc;
+                    scale_index = i;
+                }
+                scale_responses.push_back(max_val*weight);
             }
-            scale_responses.push_back(max_val*weight);
-        }
     } else {
 #pragma omp parallel for ordered  private(patch_feat) schedule(dynamic)
         for (size_t i = 0; i < p_scales.size(); ++i) {
@@ -588,7 +589,11 @@ ComplexMat KCF_Tracker::gaussian_correlation(const ComplexMat &xf, const Complex
     float xf_sqr_norm = xf.sqr_norm();
     float yf_sqr_norm = auto_correlation ? xf_sqr_norm : yf.sqr_norm();
 
-    ComplexMat xyf = auto_correlation ? xf.sqr_mag() : xf * yf.conj();
+    ComplexMat xyf;
+    if(xf.channels() != 308)
+    xyf = auto_correlation ? xf.sqr_mag() : xf * yf.conj();
+    else
+    xyf = auto_correlation ? xf.sqr_mag() : xf.mul2(yf.conj());
     DEBUG_PRINTM(xyf);
 
     //ifft2 and sum over 3rd dimension, we dont care about individual channels