]> rtime.felk.cvut.cz Git - hercules2020/kcf.git/commitdiff
Introduce new Mat types and use them in the code
authorMichal Sojka <michal.sojka@cvut.cz>
Fri, 21 Sep 2018 11:48:24 +0000 (13:48 +0200)
committerMichal Sojka <sojkam1@fel.cvut.cz>
Fri, 21 Sep 2018 19:46:16 +0000 (21:46 +0200)
This unifies matrix layout in memory and makes it easier to think about
code correctness.

12 files changed:
src/dynmem.hpp
src/fft.cpp
src/fft.h
src/fft_cufft.cpp
src/fft_cufft.h
src/fft_fftw.cpp
src/fft_fftw.h
src/fft_opencv.cpp
src/fft_opencv.h
src/kcf.cpp
src/kcf.h
src/threadctx.hpp

index 89731b2c9e07ebc946feba3bd7750386a6834b3b..395ff74118d80327d253fba1ff6df06ec3dd0548 100644 (file)
@@ -4,6 +4,7 @@
 #include <cstdlib>
 #include <opencv2/opencv.hpp>
 #include <cassert>
+#include <numeric>
 
 #if defined(CUFFT) || defined(CUFFTW)
 #include "cuda_runtime.h"
@@ -85,9 +86,9 @@ class MatDynMem : public DynMem, public cv::Mat {
     {
         assert((type & CV_MAT_DEPTH_MASK) == CV_32F);
     }
-    MatDynMem(std::array<int, 3> size, int type)
-        : DynMem(size[0] * size[1] * size[2]), cv::Mat(3, (int*)&size, type, hostMem())
-    {}
+    MatDynMem(std::vector<int> size, int type)
+        : DynMem(std::accumulate(size.begin(), size.end(), 1, std::multiplies<int>()))
+        , cv::Mat(size.size(), size.data(), type, hostMem()) {}
     MatDynMem(MatDynMem &&other) = default;
     MatDynMem(const cv::Mat &other)
         : DynMem(other.total()) , cv::Mat(other) {}
@@ -96,11 +97,6 @@ class MatDynMem : public DynMem, public cv::Mat {
         static_cast<cv::Mat>(*this) = expr;
     }
 
-    cv::Mat plane(uint i) {
-        assert(dims == 3);
-        assert(int(i) < size[0]);
-        return cv::Mat(size[1], size[2], cv::Mat::type(), ptr(i));
-    }
   private:
     static int volume(int ndims, const int *sizes)
     {
@@ -113,4 +109,41 @@ class MatDynMem : public DynMem, public cv::Mat {
     using cv::Mat::create;
 };
 
+class Mat3d : public MatDynMem
+{
+public:
+    Mat3d(uint dim0, cv::Size size) : MatDynMem({{int(dim0), size.height, size.width}}, CV_32F) {}
+
+    cv::Mat plane(uint idx) {
+        assert(dims == 3);
+        assert(int(idx) < size[0]);
+        return cv::Mat(size[1], size[2], cv::Mat::type(), ptr(idx));
+    }
+};
+
+class MatFeats : public Mat3d
+{
+public:
+    MatFeats(uint num_features, cv::Size size) : Mat3d(num_features, size) {}
+};
+class MatScales : public Mat3d
+{
+public:
+    MatScales(uint num_scales, cv::Size size) : Mat3d(num_scales, size) {}
+};
+
+class MatScaleFeats : public MatDynMem
+{
+public:
+    MatScaleFeats(uint num_scales, uint num_features, cv::Size size)
+        : MatDynMem({{int(num_scales), int(num_features), size.height, size.width}}, CV_32F) {}
+
+    cv::Mat plane(uint scale, uint feature) {
+        assert(dims == 4);
+        assert(int(scale) < size[0]);
+        assert(int(feature) < size[1]);
+        return cv::Mat(size[2], size[3], cv::Mat::type(), ptr(scale, feature));
+    }
+};
+
 #endif // DYNMEM_HPP
index 2e305f13215ad5f63cf7330589498c34cebe3037..27998861f5c51504c6b6999fd56867f707846ec9 100644 (file)
@@ -27,30 +27,42 @@ void Fft::set_window(const MatDynMem &window)
     (void)window;
 }
 
-void Fft::forward(const MatDynMem &real_input, ComplexMat &complex_result)
+void Fft::forward(const MatScales &real_input, ComplexMat &complex_result)
 {
-    assert(real_input.dims == 2);
-    assert(real_input.size().width == int(m_width));
-    assert(real_input.size().height == int(m_height));
+    assert(real_input.dims == 3);
+    assert(real_input.size[0] == IF_BIG_BATCH(int(m_num_of_scales), 1));
+    assert(real_input.size[1] == int(m_height));
+    assert(real_input.size[2] == int(m_width));
+
     (void)real_input;
     (void)complex_result;
 }
 
-void Fft::forward_window(MatDynMem &patch_feats, ComplexMat &complex_result, MatDynMem &tmp)
+void Fft::forward_window(MatFeats &patch_feats, ComplexMat &complex_result, MatFeats &tmp)
 {
         assert(patch_feats.dims == 3);
-#ifndef BIG_BATCH
         assert(patch_feats.size[0] == int(m_num_of_feats));
-#else
-        assert(patch_feats.size[0] == int(m_num_of_feats * m_num_of_scales));
-#endif
         assert(patch_feats.size[1] == int(m_height));
         assert(patch_feats.size[2] == int(m_width));
 
+        (void)tmp;
+        (void)complex_result;
+        (void)patch_feats;
+}
+
+void Fft::forward_window(MatScaleFeats &patch_feats, ComplexMat &complex_result, MatScaleFeats &tmp)
+{
+        assert(patch_feats.dims == 4);
+        assert(patch_feats.size[0] == IF_BIG_BATCH(int(m_num_of_scales), 1));
+        assert(patch_feats.size[1] == int(m_num_of_feats));
+        assert(patch_feats.size[2] == int(m_height));
+        assert(patch_feats.size[3] == int(m_width));
+
         assert(tmp.dims == patch_feats.dims);
         assert(tmp.size[0] == patch_feats.size[0]);
         assert(tmp.size[1] == patch_feats.size[1]);
         assert(tmp.size[2] == patch_feats.size[2]);
+        assert(tmp.size[3] == patch_feats.size[3]);
 
         (void)patch_feats;
         (void)complex_result;
@@ -59,14 +71,11 @@ void Fft::forward_window(MatDynMem &patch_feats, ComplexMat &complex_result, Mat
 
 void Fft::inverse(ComplexMat &complex_input, MatDynMem &real_result)
 {
-    assert(real_result.dims == 3);
-#ifndef BIG_BATCH
-    assert(real_result.size[0] == int(m_num_of_feats));
-#else
-    assert(real_result.size[0] == int(m_num_of_feats * m_num_of_scales));
-#endif
-    assert(real_result.size[1] == int(m_height));
-    assert(real_result.size[2] == int(m_width));
+    assert(real_result.dims == 4);
+    assert(real_result.size[0] == IF_BIG_BATCH(int(m_num_of_scales), 1));
+    assert(real_result.size[1] == int(m_num_of_feats));
+    assert(real_result.size[2] == int(m_height));
+    assert(real_result.size[3] == int(m_width));
 
     (void)complex_input;
     (void)real_result;
index a8c22bc215ae4aa281c0b26804fe23ca751e3fa8..1732e64c7ce5372d8206f60e68545e7e9d4c71be 100644 (file)
--- a/src/fft.h
+++ b/src/fft.h
@@ -25,8 +25,9 @@ class Fft
 public:
     virtual void init(unsigned width, unsigned height, unsigned num_of_feats, unsigned num_of_scales);
     virtual void set_window(const MatDynMem &window);
-    virtual void forward(const MatDynMem &real_input, ComplexMat &complex_result);
-    virtual void forward_window(MatDynMem &patch_feats_in, ComplexMat &complex_result, MatDynMem &tmp);
+    virtual void forward(const MatScales &real_input, ComplexMat &complex_result);
+    virtual void forward_window(MatFeats &patch_feats_in, ComplexMat &complex_result, MatFeats &tmp);
+    virtual void forward_window(MatScaleFeats &patch_feats_in, ComplexMat &complex_result, MatScaleFeats &tmp);
     virtual void inverse(ComplexMat &complex_input, MatDynMem &real_result);
     virtual ~Fft() = 0;
 
index b2167ff724b1ec8afaacfd175168118dab64c84b..955c5321bf60e5ab0cf7176f44f158a8090779ba 100644 (file)
@@ -69,15 +69,15 @@ void cuFFT::set_window(const MatDynMem &window)
     m_window = window;
 }
 
-void cuFFT::forward(const MatDynMem &real_input, ComplexMat &complex_result)
+void cuFFT::forward(const MatScales &real_input, ComplexMat &complex_result)
 {
     Fft::forward(real_input, complex_result);
-    auto in = static_cast<cufftReal *>(const_cast<MatDynMem&>(real_input).deviceMem());
+    auto in = static_cast<cufftReal *>(const_cast<MatScales&>(real_input).deviceMem());
 
     cudaErrorCheck(cufftExecR2C(plan_f, in, complex_result.get_p_data()));
 }
 
-void cuFFT::forward_window(MatDynMem &feat, ComplexMat &complex_result, MatDynMem &temp)
+void cuFFT::forward_window(MatScaleFeats &feat, ComplexMat &complex_result, MatScaleFeats &temp)
 {
     Fft::forward_window(feat, complex_result, temp);
 
@@ -85,9 +85,11 @@ void cuFFT::forward_window(MatDynMem &feat, ComplexMat &complex_result, MatDynMe
     cufftReal *temp_data = temp.deviceMem();
 
     for (uint i = 0; i < n_channels; ++i) {
-        cv::Mat feat_plane = feat.plane(i);
-        cv::Mat temp_plane = temp.plane(i);
-        temp_plane = feat_plane.mul(m_window);
+        for (uint j = 0; j < uint(feat.size[1]); ++j) {
+            cv::Mat feat_plane = feat.plane(i, j);
+            cv::Mat temp_plane = temp.plane(i, j);
+            temp_plane = feat_plane.mul(m_window);
+        }
     }
     cudaErrorCheck(cufftExecR2C(plan_fw, temp_data, complex_result.get_p_data()));
 }
index bbc64258920f1f506be2fbfc3657c7cb27251dd8..34c50be2084d0009ef03cc10e2c5b7ee2ef8f7ec 100644 (file)
@@ -18,8 +18,8 @@ public:
     cuFFT();
     void init(unsigned width, unsigned height, unsigned num_of_feats, unsigned num_of_scales) override;
     void set_window(const MatDynMem &window) override;
-    void forward(const MatDynMem &real_input, ComplexMat &complex_result) override;
-    void forward_window(MatDynMem &patch_feats_in, ComplexMat &complex_result, MatDynMem &tmp) override;
+    void forward(const MatScales &real_input, ComplexMat &complex_result) override;
+    void forward_window(MatScaleFeats &patch_feats_in, ComplexMat &complex_result, MatScaleFeats &tmp) override;
     void inverse(ComplexMat &complex_input, MatDynMem &real_result) override;
     ~cuFFT() override;
 
index aff4c7b1dd4973e9f0e6b51cbb54f3e5c2d8eec3..36b290b058743cace9dcdb47c872a92b700c24a2 100644 (file)
@@ -170,7 +170,7 @@ void Fftw::set_window(const MatDynMem &window)
     m_window = window;
 }
 
-void Fftw::forward(const MatDynMem &real_input, ComplexMat &complex_result)
+void Fftw::forward(const MatScales &real_input, ComplexMat &complex_result)
 {
     Fft::forward(real_input, complex_result);
 
@@ -184,21 +184,23 @@ void Fftw::forward(const MatDynMem &real_input, ComplexMat &complex_result)
     return;
 }
 
-void Fftw::forward_window(MatDynMem &feat, ComplexMat & complex_result, MatDynMem &temp)
+void Fftw::forward_window(MatScaleFeats  &feat, ComplexMat & complex_result, MatScaleFeats &temp)
 {
     Fft::forward_window(feat, complex_result, temp);
 
-    int n_channels = feat.size[0];
-    for (int i = 0; i < n_channels; ++i) {
-        cv::Mat feat_plane = feat.plane(i);
-        cv::Mat temp_plane = temp.plane(i);
-        temp_plane = feat_plane.mul(m_window);
+    uint n_channels = feat.size[0];
+    for (uint i = 0; i < n_channels; ++i) {
+        for (uint j = 0; j < uint(feat.size[1]); ++j) {
+            cv::Mat feat_plane = feat.plane(i, j);
+            cv::Mat temp_plane = temp.plane(i, j);
+            temp_plane = feat_plane.mul(m_window);
+        }
     }
 
     float *in = temp.ptr<float>();
     fftwf_complex *out = reinterpret_cast<fftwf_complex *>(complex_result.get_p_data());
 
-    if (n_channels <= int(m_num_of_feats))
+    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);
index 8fcc31b8005321913f4e2598eae9acd297e5bfac..0fc3b672406103adfd70f7bde21d1bad7a2f5fef 100644 (file)
@@ -20,8 +20,8 @@ public:
     Fftw();
     void init(unsigned width, unsigned height, unsigned num_of_feats, unsigned num_of_scales) override;
     void set_window(const MatDynMem &window) override;
-    void forward(const MatDynMem &real_input, ComplexMat &complex_result) override;
-    void forward_window(MatDynMem &patch_feats_in, ComplexMat &complex_result, MatDynMem &tmp) override;
+    void forward(const MatScales &real_input, ComplexMat &complex_result) override;
+    void forward_window(MatScaleFeats &patch_feats_in, ComplexMat &complex_result, MatScaleFeats &tmp) override;
     void inverse(ComplexMat &complex_input, MatDynMem &real_result) override;
     ~Fftw() override;
 private:
index 282996bb6bebb7da4007689534d09acc8cd6efe7..1a509d9e33c4029b98ab6f6c20d373b8574d93e7 100644 (file)
@@ -11,7 +11,7 @@ void FftOpencv::set_window(const MatDynMem &window)
     m_window = window;
 }
 
-void FftOpencv::forward(const MatDynMem &real_input, ComplexMat &complex_result)
+void FftOpencv::forward(const MatScales &real_input, ComplexMat &complex_result)
 {
     Fft::forward(real_input, complex_result);
 
@@ -20,16 +20,18 @@ void FftOpencv::forward(const MatDynMem &real_input, ComplexMat &complex_result)
     complex_result = ComplexMat(tmp);
 }
 
-void FftOpencv::forward_window(MatDynMem &feat, ComplexMat &complex_result, MatDynMem &temp)
+void FftOpencv::forward_window(MatScaleFeats &feat, ComplexMat &complex_result, MatScaleFeats &temp)
 {
     Fft::forward_window(feat, complex_result, temp);
 
     uint n_channels = feat.size[0];
     for (uint i = 0; i < n_channels; ++i) {
-        cv::Mat complex_res;
-        cv::Mat channel = feat.plane(i);
-        cv::dft(channel.mul(m_window), complex_res, cv::DFT_COMPLEX_OUTPUT);
-        complex_result.set_channel(int(i), complex_res);
+        for (uint j = 0; j < uint(feat.size[1]); ++j) {
+            cv::Mat complex_res;
+            cv::Mat channel = feat.plane(i, j);
+            cv::dft(channel.mul(m_window), complex_res, cv::DFT_COMPLEX_OUTPUT);
+            complex_result.set_channel(int(i), complex_res);
+        }
     }
 }
 
index f57906997a1a06a78b7356907b8b21664b03be68..26fce739c75aad21041441e88942baa4d3894a20 100644 (file)
@@ -9,8 +9,8 @@ class FftOpencv : public Fft
 public:
     void init(unsigned width, unsigned height, unsigned num_of_feats, unsigned num_of_scales) override;
     void set_window(const MatDynMem &window) override;
-    void forward(const MatDynMem &real_input, ComplexMat &complex_result) override;
-    void forward_window(MatDynMem &patch_feats_in, ComplexMat &complex_result, MatDynMem &tmp) override;
+    void forward(const MatScales &real_input, ComplexMat &complex_result) override;
+    void forward_window(MatScaleFeats &patch_feats_in, ComplexMat &complex_result, MatScaleFeats &tmp) override;
     void inverse(ComplexMat &complex_input, MatDynMem &real_result) override;
     ~FftOpencv() override;
 private:
index 1eeb0ee600d6fae437d1ba8e07a529391795ffad..9c6c93d30e4bb0ca688b7dc18250278e0a11c87f 100644 (file)
@@ -28,7 +28,7 @@ static bool kcf_debug = false;
 #define DEBUG_PRINTM(obj)                                                                                              \
     if (kcf_debug) {                                                                                                     \
         std::cout << #obj << " @" << __LINE__ << " " << (obj).size() << " CH: " << (obj).channels() << std::endl       \
-                  << (obj) << std::endl;                                                                               \
+                  /*<< (obj)*/ << std::endl;                                                                               \
     }
 
 template <typename T>
@@ -66,9 +66,9 @@ KCF_Tracker::~KCF_Tracker()
 void KCF_Tracker::train(cv::Mat input_gray, cv::Mat input_rgb, double interp_factor)
 {
     // obtain a sub-window for training
-    int sizes[3] = {p_num_of_feats, p_roi.height, p_roi.width};
-    MatDynMem patch_feats(3, sizes, CV_32FC1);
-    MatDynMem temp(3, sizes, CV_32FC1);
+    // TODO: Move Mats outside from here
+    MatFeats patch_feats(p_num_of_feats, p_roi);
+    MatFeats temp(p_num_of_feats, p_roi);
     get_features(patch_feats, input_rgb, input_gray, p_pose.cx, p_pose.cy,
                  p_windows_size.width, p_windows_size.height,
                  p_current_scale);
@@ -217,13 +217,14 @@ void KCF_Tracker::init(cv::Mat &img, const cv::Rect &bbox, int fit_size_x, int f
 
 #ifndef BIG_BATCH
     for (auto scale: p_scales)
-        d.threadctxs.emplace_back(p_roi, p_num_of_feats, 1, scale);
+        d.threadctxs.emplace_back(p_roi, p_num_of_feats, scale);
 #else
-    d.threadctxs.emplace_back(p_roi, p_num_of_feats * p_num_scales, p_num_scales);
+    d.threadctxs.emplace_back(p_roi, p_num_of_feats, p_num_scales);
 #endif
 
-    gaussian_correlation.reset(new GaussianCorrelation(p_roi, IF_BIG_BATCH(p_num_scales, 1),
-                                                       p_num_of_feats * IF_BIG_BATCH(p_num_scales, 1)));
+    gaussian_correlation.reset(
+                new GaussianCorrelation(IF_BIG_BATCH(p_num_scales, 1),
+                                        p_num_of_feats, p_roi));
 
     p_current_scale = 1.;
 
@@ -245,7 +246,9 @@ void KCF_Tracker::init(cv::Mat &img, const cv::Rect &bbox, int fit_size_x, int f
     fft.set_window(MatDynMem(cosine_window_function(p_roi.width, p_roi.height)));
 
     // window weights, i.e. labels
-    fft.forward(gaussian_shaped_labels(p_output_sigma, p_roi.width, p_roi.height), p_yf);
+    MatScales gsl(1, p_roi);
+    gaussian_shaped_labels(p_output_sigma, p_roi.width, p_roi.height).copyTo(gsl.plane(0));
+    fft.forward(gsl, p_yf);
     DEBUG_PRINTM(p_yf);
 
     // train initial model
@@ -413,9 +416,8 @@ void KCF_Tracker::track(cv::Mat &img)
 void ThreadCtx::track(const KCF_Tracker &kcf, cv::Mat &input_rgb, cv::Mat &input_gray)
 {
     // TODO: Move matrices to thread ctx
-    int sizes[3] = {kcf.p_num_of_feats, kcf.p_windows_size.height, kcf.p_windows_size.width};
-    MatDynMem patch_feats(3, sizes, CV_32FC1);
-    MatDynMem temp(3, sizes, CV_32FC1);
+    MatFeats patch_feats(kcf.p_num_of_feats, kcf.p_roi);
+    MatFeats temp(kcf.p_num_of_feats, kcf.p_roi);
 
 #ifdef BIG_BATCH
     BIG_BATCH_OMP_PARALLEL_FOR
@@ -469,12 +471,12 @@ void ThreadCtx::track(const KCF_Tracker &kcf, cv::Mat &input_rgb, cv::Mat &input
 
 // ****************************************************************************
 
-void KCF_Tracker::get_features(MatDynMem &result_3d, cv::Mat &input_rgb, cv::Mat &input_gray, int cx, int cy,
+void KCF_Tracker::get_features(MatFeats &result, cv::Mat &input_rgb, cv::Mat &input_gray, int cx, int cy,
                                int size_x, int size_y, double scale) const
 {
-    assert(result_3d.size[0] == p_num_of_feats);
-    assert(result_3d.size[1] == size_y / p_cell_size);
-    assert(result_3d.size[2] == size_x / p_cell_size);
+    assert(result.size[0] == p_num_of_feats);
+    assert(result.size[1] == size_y / p_cell_size);
+    assert(result.size[2] == size_x / p_cell_size);
 
     int size_x_scaled = floor(size_x * scale);
     int size_y_scaled = floor(size_y * scale);
@@ -524,15 +526,13 @@ void KCF_Tracker::get_features(MatDynMem &result_3d, cv::Mat &input_rgb, cv::Mat
 
     hog_feat.insert(hog_feat.end(), color_feat.begin(), color_feat.end());
 
-    for (uint i = 0; i < hog_feat.size(); ++i) {
-        cv::Mat result_plane(result_3d.dims - 1, result_3d.size + 1, result_3d.cv::Mat::type(), result_3d.ptr<void>(i));
-        hog_feat[i].copyTo(result_plane);
-    }
+    for (uint i = 0; i < hog_feat.size(); ++i)
+        hog_feat[i].copyTo(result.plane(i));
 }
 
-MatDynMem KCF_Tracker::gaussian_shaped_labels(double sigma, int dim1, int dim2)
+cv::Mat KCF_Tracker::gaussian_shaped_labels(double sigma, int dim1, int dim2)
 {
-    MatDynMem labels(dim2, dim1, CV_32FC1);
+    cv::Mat labels(dim2, dim1, CV_32FC1);
     int range_y[2] = {-dim2 / 2, dim2 - dim2 / 2};
     int range_x[2] = {-dim1 / 2, dim1 - dim1 / 2};
 
@@ -554,9 +554,9 @@ MatDynMem KCF_Tracker::gaussian_shaped_labels(double sigma, int dim1, int dim2)
     return rot_labels;
 }
 
-MatDynMem KCF_Tracker::circshift(const cv::Mat &patch, int x_rot, int y_rot)
+cv::Mat KCF_Tracker::circshift(const cv::Mat &patch, int x_rot, int y_rot)
 {
-    MatDynMem rot_patch(patch.size(), CV_32FC1);
+    cv::Mat rot_patch(patch.size(), CV_32FC1);
     cv::Mat tmp_x_rot(patch.size(), CV_32FC1);
 
     // circular rotate x-axis
index 7ce4f2dd493ae138f1d46c6893aae2d1eb900d3d..2a7572dc2f6757c954437ca6ac2485371a852bd6 100644 (file)
--- a/src/kcf.h
+++ b/src/kcf.h
@@ -130,11 +130,11 @@ private:
 
     class GaussianCorrelation {
       public:
-        GaussianCorrelation(cv::Size size, uint num_scales, uint num_feats)
+        GaussianCorrelation(uint num_scales, uint num_feats, cv::Size size)
             : xf_sqr_norm(num_scales)
             , xyf(Fft::freq_size(size), num_scales)
-            , ifft_res({{int(num_feats * num_scales), size.height, size.width}}, CV_32F)
-            , k({{int(num_scales), size.height, size.width}}, CV_32F)
+            , ifft_res(num_scales, num_feats, size)
+            , k(num_scales, size)
         {}
         void operator()(const KCF_Tracker &kcf, ComplexMat &result, const ComplexMat &xf, const ComplexMat &yf, double sigma, bool auto_correlation = false);
 
@@ -142,18 +142,18 @@ private:
         DynMem xf_sqr_norm;
         DynMem yf_sqr_norm{1};
         ComplexMat xyf;
-        MatDynMem ifft_res;
-        MatDynMem k;
+        MatScaleFeats ifft_res;
+        MatScales k;
     };
 
     //helping functions
     void scale_track(ThreadCtx &vars, cv::Mat &input_rgb, cv::Mat &input_gray);
     cv::Mat get_subwindow(const cv::Mat &input, int cx, int cy, int size_x, int size_y) const;
-    MatDynMem gaussian_shaped_labels(double sigma, int dim1, int dim2);
+    cv::Mat gaussian_shaped_labels(double sigma, int dim1, int dim2);
     std::unique_ptr<GaussianCorrelation> gaussian_correlation;
-    MatDynMem circshift(const cv::Mat &patch, int x_rot, int y_rot);
+    cv::Mat circshift(const cv::Mat &patch, int x_rot, int y_rot);
     cv::Mat cosine_window_function(int dim1, int dim2);
-    void get_features(MatDynMem &feat_3d, cv::Mat &input_rgb, cv::Mat &input_gray, int cx, int cy, int size_x, int size_y, double scale) const;
+    void get_features(MatFeats &result, cv::Mat &input_rgb, cv::Mat &input_gray, int cx, int cy, int size_x, int size_y, double scale) const;
     cv::Point2f sub_pixel_peak(cv::Point &max_loc, cv::Mat &response) const;
     double sub_grid_scale(uint index);
     void resizeImgs(cv::Mat &input_rgb, cv::Mat &input_gray);
index 548b6aa2930d6a983f2f826f4efb32ebba74e05b..f9db762dfba7487c7448427784e5f50a752460ff 100644 (file)
@@ -15,14 +15,16 @@ class KCF_Tracker;
 
 struct ThreadCtx {
   public:
-    ThreadCtx(cv::Size roi, uint num_channels, uint num_of_scales
-#ifndef BIG_BATCH
+    ThreadCtx(cv::Size roi, uint num_features
+#ifdef BIG_BATCH
+              , uint num_of_scales
+#else
               , double scale
 #endif
              )
         : roi(roi)
-        , num_channels(num_channels)
-        , num_of_scales(num_of_scales)
+        , num_features(num_features)
+        , num_of_scales(IF_BIG_BATCH(num_of_scales, 1))
 #ifndef BIG_BATCH
         , scale(scale)
 #endif
@@ -33,16 +35,16 @@ struct ThreadCtx {
     void track(const KCF_Tracker &kcf, cv::Mat &input_rgb, cv::Mat &input_gray);
 private:
     cv::Size roi;
-    uint num_channels;
+    uint num_features;
     uint num_of_scales;
     cv::Size freq_size = Fft::freq_size(roi);
 
 
-    KCF_Tracker::GaussianCorrelation gaussian_correlation{roi, num_of_scales, num_channels};
+    KCF_Tracker::GaussianCorrelation gaussian_correlation{num_of_scales, num_features, roi};
 
-    MatDynMem ifft2_res{roi, CV_32FC(int(num_channels))};
+    MatDynMem ifft2_res{roi, CV_32FC(int(num_features))};
 
-    ComplexMat zf{uint(freq_size.height), uint(freq_size.width), num_channels, num_of_scales};
+    ComplexMat zf{uint(freq_size.height), uint(freq_size.width), num_features, num_of_scales};
     ComplexMat kzf{uint(freq_size.height), uint(freq_size.width), num_of_scales};
 
 public:
@@ -50,7 +52,7 @@ public:
     std::future<void> async_res;
 #endif
 
-    MatDynMem response{roi, CV_32FC(int(num_of_scales))};
+    MatScales response{num_of_scales, roi};
 
     struct Max {
         cv::Point2i loc;