]> rtime.felk.cvut.cz Git - hercules2020/kcf.git/commitdiff
Convert ComplexMat to use DynMem class
authorMichal Sojka <michal.sojka@cvut.cz>
Sun, 30 Sep 2018 22:48:56 +0000 (00:48 +0200)
committerMichal Sojka <michal.sojka@cvut.cz>
Sun, 30 Sep 2018 23:02:40 +0000 (01:02 +0200)
This is the first step to unification of CPU and GPU implementations.

It also fixes a incorrect dimensions of ComplexMats in
Gaussian_Correlation, which was unnoticed, because the matrices were
reallocated on the fly. Now, we use assertions in DynMem, which
prevents this. Ideally, we don't want any allocation during ComplexMat
computations, but we're not there yet.

src/complexmat.hpp
src/dynmem.hpp
src/kcf.cpp
src/kcf.h
src/threadctx.hpp

index 0f5bd02be2873ea6909296de331814b69c915e90..eca36a75b9106fe50152a00a6164718aa15c4b8a 100644 (file)
@@ -15,35 +15,24 @@ template <typename T> class ComplexMat_ {
     uint n_scales;
 
     ComplexMat_(uint _rows, uint _cols, uint _n_channels, uint _n_scales = 1)
-        : cols(_cols), rows(_rows), n_channels(_n_channels * _n_scales), n_scales(_n_scales)
-    {
-        p_data.resize(n_channels * cols * rows);
-    }
+        : cols(_cols), rows(_rows), n_channels(_n_channels * _n_scales), n_scales(_n_scales),
+          p_data(n_channels * cols * rows) {}
     ComplexMat_(cv::Size size, uint _n_channels, uint _n_scales = 1)
         : cols(size.width), rows(size.height), n_channels(_n_channels * _n_scales), n_scales(_n_scales)
-    {
-        p_data.resize(n_channels * cols * rows);
-    }
+        , p_data(n_channels * cols * rows) {}
 
     // assuming that mat has 2 channels (real, img)
     ComplexMat_(const cv::Mat &mat) : cols(uint(mat.cols)), rows(uint(mat.rows)), n_channels(1), n_scales(1)
+                                    , p_data(n_channels * cols * rows)
     {
-        p_data = convert(mat);
+        memcpy(p_data.hostMem(), mat.ptr<std::complex<T>>(), mat.total() * mat.elemSize());
     }
 
     static ComplexMat_ same_size(const ComplexMat_ &o)
     {
-        return ComplexMat_(o.cols, o.rows, o.n_channels / o.n_scales, o.n_scales);
+        return ComplexMat_(o.rows, o.cols, o.n_channels / o.n_scales, o.n_scales);
     }
 
-    void create(uint _rows, uint _cols, uint _n_channels, uint _n_scales = 1)
-    {
-        rows = _rows;
-        cols = _cols;
-        n_channels = _n_channels * _n_scales;
-        n_scales = _n_scales;
-        p_data.resize(n_channels * cols * rows);
-    }
     // cv::Mat API compatibility
     cv::Size size() const { return cv::Size(cols, rows); }
     uint channels() const { return n_channels; }
@@ -55,7 +44,7 @@ template <typename T> class ComplexMat_ {
         for (uint i = 0; i < rows; ++i) {
             const std::complex<T> *row = mat.ptr<std::complex<T>>(i);
             for (uint j = 0; j < cols; ++j)
-                p_data[idx * rows * cols + i * cols + j] = row[j];
+                p_data.hostMem()[idx * rows * cols + i * cols + j] = row[j];
         }
     }
 
@@ -80,8 +69,8 @@ template <typename T> class ComplexMat_ {
         for (uint scale = 0; scale < n_scales; ++scale) {
             T sum_sqr_norm = 0;
             for (int i = 0; i < n_channels_per_scale; ++i)
-                for (auto lhs = p_data.begin() + i * rows * cols + scale * scale_offset;
-                     lhs != p_data.begin() + (i + 1) * rows * cols + scale * scale_offset; ++lhs)
+                for (auto lhs = p_data.hostMem() + i * rows * cols + scale * scale_offset;
+                     lhs != p_data.hostMem() + (i + 1) * rows * cols + scale * scale_offset; ++lhs)
                     sum_sqr_norm += lhs->real() * lhs->real() + lhs->imag() * lhs->imag();
             result.hostMem()[scale] = sum_sqr_norm / static_cast<T>(cols * rows);
         }
@@ -100,7 +89,7 @@ template <typename T> class ComplexMat_ {
 
     ComplexMat_<T> sum_over_channels() const
     {
-        assert(p_data.size() == n_channels * rows * cols);
+        assert(p_data.num_elem == n_channels * rows * cols);
 
         uint n_channels_per_scale = n_channels / n_scales;
         uint scale_offset = n_channels_per_scale * rows * cols;
@@ -111,7 +100,7 @@ template <typename T> class ComplexMat_ {
                 std::complex<T> acc = 0;
                 for (uint ch = 0; ch < n_channels_per_scale; ++ch)
                     acc +=  p_data[scale * scale_offset + i + ch * rows * cols];
-                result.p_data[scale * rows * cols + i] = acc;
+                result.p_data.hostMem()[scale * rows * cols + i] = acc;
             }
         }
         return result;
@@ -135,8 +124,8 @@ template <typename T> class ComplexMat_ {
         return result;
     }
 
-    std::complex<T> *get_p_data() { return p_data.data(); }
-    const std::complex<T> *get_p_data() const { return p_data.data(); }
+    std::complex<T> *get_p_data() { return p_data.hostMem(); }
+    const std::complex<T> *get_p_data() const { return p_data.hostMem(); }
 
     // element-wise per channel multiplication, division and addition
     ComplexMat_<T> operator*(const ComplexMat_<T> &rhs) const
@@ -190,7 +179,7 @@ template <typename T> class ComplexMat_ {
     }
 
   private:
-    std::vector<std::complex<T>> p_data;
+    DynMem_<std::complex<T>> p_data;
 
     // convert 2 channel mat (real, imag) to vector row-by-row
     std::vector<std::complex<T>> convert(const cv::Mat &mat)
@@ -213,8 +202,8 @@ template <typename T> class ComplexMat_ {
 
         ComplexMat_<T> result = *this;
         for (uint s = 0; s < n_scales; ++s) {
-            auto lhs = result.p_data.begin() + (s * n_channels/n_scales * rows * cols);
-            auto rhs = mat_rhs.p_data.begin();
+            auto lhs = result.p_data.hostMem() + (s * n_channels/n_scales * rows * cols);
+            auto rhs = mat_rhs.p_data.hostMem();
             for (uint i = 0; i < n_channels/n_scales * rows * cols; ++i)
                 op(*(lhs + i), *(rhs + i));
         }
@@ -228,9 +217,9 @@ template <typename T> class ComplexMat_ {
 
         ComplexMat_<T> result = *this;
         for (uint i = 0; i < n_channels; ++i) {
-            auto lhs = result.p_data.begin() + i * rows * cols;
-            auto rhs = mat_rhs.p_data.begin();
-            for (; lhs != result.p_data.begin() + (i + 1) * rows * cols; ++lhs, ++rhs)
+            auto lhs = result.p_data.hostMem() + i * rows * cols;
+            auto rhs = mat_rhs.p_data.hostMem();
+            for (; lhs != result.p_data.hostMem() + (i + 1) * rows * cols; ++lhs, ++rhs)
                 op(*lhs, *rhs);
         }
 
@@ -259,8 +248,8 @@ template <typename T> class ComplexMat_ {
     {
         ComplexMat_<T> result = *this;
         for (uint i = 0; i < n_channels; ++i)
-            for (auto lhs = result.p_data.begin() + i * rows * cols;
-                 lhs != result.p_data.begin() + (i + 1) * rows * cols; ++lhs)
+            for (auto lhs = result.p_data.hostMem() + i * rows * cols;
+                 lhs != result.p_data.hostMem() + (i + 1) * rows * cols; ++lhs)
                 op(*lhs);
         return result;
     }
index ad36f61ef6e50959b6f8900a4e663f11e0d8d6b5..c830a5e8099f78dd724bbae106127398730f29db 100644 (file)
@@ -32,6 +32,10 @@ template <typename T> class DynMem_ {
         ptr_h = new T[num_elem];
 #endif
     }
+    DynMem_(const DynMem_ &other) : DynMem_(other.num_elem)
+    {
+        memcpy(ptr_h, other.ptr_h, num_elem * sizeof(T));
+    }
     DynMem_(DynMem_ &&other) : num_elem(other.num_elem)
     {
         ptr_h = other.ptr_h;
@@ -50,6 +54,7 @@ template <typename T> class DynMem_ {
 #endif
     }
     T *hostMem() { return ptr_h; }
+    const T *hostMem() const { return ptr_h; }
 #ifdef CUFFT
     T *deviceMem() { return ptr_d; }
 #endif
index 39a72ae62c2a9233b2688ca225fd61104c116a99..19b5817488fc4b7abe63041ab2d8fc69c4b9df88 100644 (file)
@@ -208,7 +208,7 @@ void KCF_Tracker::init(cv::Mat &img, const cv::Rect &bbox, int fit_size_x, int f
     d.threadctxs.emplace_back(feature_size, p_num_of_feats, p_num_scales);
 #endif
 
-    gaussian_correlation.reset(new GaussianCorrelation(1, feature_size));
+    gaussian_correlation.reset(new GaussianCorrelation(1, p_num_of_feats, feature_size));
 
     p_current_center = p_init_pose.center();
     p_current_scale = 1.;
index 48eb18dcb101d1488803e3aec99d86cf968964b0..10b189a678c27a9b87d5950b59a0a1a7602ef704 100644 (file)
--- a/src/kcf.h
+++ b/src/kcf.h
@@ -124,9 +124,9 @@ private:
         uint height, width, n_feats;
     public:
         ComplexMat yf {height, width, 1};
-        ComplexMat model_alphaf {height, width, n_feats};
-        ComplexMat model_alphaf_num {height, width, n_feats};
-        ComplexMat model_alphaf_den {height, width, n_feats};
+        ComplexMat model_alphaf {height, width, 1};
+        ComplexMat model_alphaf_num {height, width, 1};
+        ComplexMat model_alphaf_den {height, width, 1};
         ComplexMat model_xf {height, width, n_feats};
         ComplexMat xf {height, width, n_feats};
 
@@ -137,9 +137,9 @@ private:
 
     class GaussianCorrelation {
       public:
-        GaussianCorrelation(uint num_scales, cv::Size size)
+        GaussianCorrelation(uint num_scales, uint num_feats, cv::Size size)
             : xf_sqr_norm(num_scales)
-            , xyf(Fft::freq_size(size), 1, num_scales)
+            , xyf(Fft::freq_size(size), num_feats, num_scales)
             , ifft_res(num_scales, size)
             , k(num_scales, size)
         {}
index 317f9f4d8658d7925949eff8241e45518ff8d148..2faceb1e1d5805bef0dfed6ba392b8a56c85b81d 100644 (file)
@@ -42,7 +42,7 @@ private:
     MatScaleFeats patch_feats{num_scales, num_features, roi};
     MatScaleFeats temp{num_scales, num_features, roi};
 
-    KCF_Tracker::GaussianCorrelation gaussian_correlation{num_scales, roi};
+    KCF_Tracker::GaussianCorrelation gaussian_correlation{num_scales, num_features, roi};
 
     MatScales ifft2_res{num_scales, roi};