From 3748e7e9a8a41c4ba9ce4ef2c225b49f7e3feadc Mon Sep 17 00:00:00 2001 From: Michal Sojka Date: Sun, 30 Sep 2018 22:06:10 +0200 Subject: [PATCH] Do not allow creation of ComplexMat with unknown size To avoid memory (re)allocation after we switch ComplexMat to DynMem, we need to know the size before hand. --- src/complexmat.hpp | 6 +++++- src/kcf.cpp | 39 ++++++++++++++++++--------------------- src/kcf.h | 22 +++++++++++++++------- 3 files changed, 38 insertions(+), 29 deletions(-) diff --git a/src/complexmat.hpp b/src/complexmat.hpp index 62f1145..0f5bd02 100644 --- a/src/complexmat.hpp +++ b/src/complexmat.hpp @@ -14,7 +14,6 @@ template class ComplexMat_ { uint n_channels; uint n_scales; - ComplexMat_() : cols(0), rows(0), n_channels(0), n_scales(0) {} 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) { @@ -32,6 +31,11 @@ template class ComplexMat_ { p_data = convert(mat); } + static ComplexMat_ same_size(const ComplexMat_ &o) + { + return ComplexMat_(o.cols, o.rows, o.n_channels / o.n_scales, o.n_scales); + } + void create(uint _rows, uint _cols, uint _n_channels, uint _n_scales = 1) { rows = _rows; diff --git a/src/kcf.cpp b/src/kcf.cpp index 2afa209..199b1cc 100644 --- a/src/kcf.cpp +++ b/src/kcf.cpp @@ -76,26 +76,26 @@ void KCF_Tracker::train(cv::Mat input_rgb, cv::Mat input_gray, double interp_fac p_windows_size.width, p_windows_size.height, p_current_scale).copyTo(patch_feats.scale(0)); DEBUG_PRINT(patch_feats); - fft.forward_window(patch_feats, p_xf, temp); - DEBUG_PRINTM(p_xf); - p_model_xf = p_model_xf * (1. - interp_factor) + p_xf * interp_factor; - DEBUG_PRINTM(p_model_xf); + fft.forward_window(patch_feats, model->xf, temp); + DEBUG_PRINTM(model->xf); + model->model_xf = model->model_xf * (1. - interp_factor) + model->xf * interp_factor; + DEBUG_PRINTM(model->model_xf); if (m_use_linearkernel) { - ComplexMat xfconj = p_xf.conj(); - p_model_alphaf_num = xfconj.mul(p_yf); - p_model_alphaf_den = (p_xf * xfconj); + ComplexMat xfconj = model->xf.conj(); + model->model_alphaf_num = xfconj.mul(model->yf); + model->model_alphaf_den = (model->xf * xfconj); } else { // Kernel Ridge Regression, calculate alphas (in Fourier domain) cv::Size sz(Fft::freq_size(feature_size)); ComplexMat kf(sz.height, sz.width, 1); - (*gaussian_correlation)(kf, p_model_xf, p_model_xf, p_kernel_sigma, true, *this); + (*gaussian_correlation)(kf, model->model_xf, model->model_xf, p_kernel_sigma, true, *this); DEBUG_PRINTM(kf); - p_model_alphaf_num = p_yf * kf; - p_model_alphaf_den = kf * (kf + p_lambda); + model->model_alphaf_num = model->yf * kf; + model->model_alphaf_den = kf * (kf + p_lambda); } - p_model_alphaf = p_model_alphaf_num / p_model_alphaf_den; - DEBUG_PRINTM(p_model_alphaf); + model->model_alphaf = model->model_alphaf_num / model->model_alphaf_den; + DEBUG_PRINTM(model->model_alphaf); // p_model_alphaf = p_yf / (kf + p_lambda); //equation for fast training } @@ -200,10 +200,7 @@ void KCF_Tracker::init(cv::Mat &img, const cv::Rect &bbox, int fit_size_x, int f } #endif - cv::Size csz = Fft::freq_size(feature_size); - p_model_xf.create(csz.height, csz.width, p_num_of_feats); - p_yf.create(csz.height, csz.width, 1); - p_xf.create(csz.height, csz.width, p_num_of_feats); + model.reset(new Model(Fft::freq_size(feature_size), p_num_of_feats)); #ifndef BIG_BATCH for (auto scale: p_scales) @@ -241,8 +238,8 @@ void KCF_Tracker::init(cv::Mat &img, const cv::Rect &bbox, int fit_size_x, int f // window weights, i.e. labels MatScales gsl(1, feature_size); gaussian_shaped_labels(p_output_sigma, feature_size.width, feature_size.height).copyTo(gsl.plane(0)); - fft.forward(gsl, p_yf); - DEBUG_PRINTM(p_yf); + fft.forward(gsl, model->yf); + DEBUG_PRINTM(model->yf); // train initial model train(input_rgb, input_gray, 1.0); @@ -423,11 +420,11 @@ void ThreadCtx::track(const KCF_Tracker &kcf, cv::Mat &input_rgb, cv::Mat &input DEBUG_PRINTM(zf); if (kcf.m_use_linearkernel) { - kzf = zf.mul(kcf.p_model_alphaf).sum_over_channels(); + kzf = zf.mul(kcf.model->model_alphaf).sum_over_channels(); } else { - gaussian_correlation(kzf, zf, kcf.p_model_xf, kcf.p_kernel_sigma, false, kcf); + gaussian_correlation(kzf, zf, kcf.model->model_xf, kcf.p_kernel_sigma, false, kcf); DEBUG_PRINTM(kzf); - kzf = kzf.mul(kcf.p_model_alphaf); + kzf = kzf.mul(kcf.model->model_alphaf); } kcf.fft.inverse(kzf, response); diff --git a/src/kcf.h b/src/kcf.h index cc735d7..48eb18d 100644 --- a/src/kcf.h +++ b/src/kcf.h @@ -120,13 +120,20 @@ private: Kcf_Tracker_Private &d; - //model - ComplexMat p_yf; - ComplexMat p_model_alphaf; - ComplexMat p_model_alphaf_num; - ComplexMat p_model_alphaf_den; - ComplexMat p_model_xf; - ComplexMat p_xf; + class Model { + 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_xf {height, width, n_feats}; + ComplexMat xf {height, width, n_feats}; + + Model(cv::Size freq_size, uint _n_feats) : height(freq_size.height), width(freq_size.width), n_feats(_n_feats) {} + }; + + std::unique_ptr model; class GaussianCorrelation { public: @@ -146,6 +153,7 @@ private: 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; -- 2.39.2