X-Git-Url: http://rtime.felk.cvut.cz/gitweb/hercules2020/kcf.git/blobdiff_plain/a46a489b26edaddf70c6750d54462d58dd95749b..2c6dc73e108709604927a59ec0168f0187e0270c:/src/kcf.h diff --git a/src/kcf.h b/src/kcf.h index 66cb0fa..02fe814 100644 --- a/src/kcf.h +++ b/src/kcf.h @@ -6,13 +6,10 @@ #include #include "fhog.hpp" +#include "complexmat.hpp" #ifdef CUFFT -#include "complexmat.cuh" -#include "cuda_functions.cuh" -#include "cuda/cuda_error_check.cuh" +#include "cuda_error_check.hpp" #include -#else -#include "complexmat.hpp" #endif #include "cnfeat.hpp" @@ -24,7 +21,9 @@ struct ThreadCtx; struct BBox_c { - double cx, cy, w, h; + double cx, cy, w, h, a; + + inline cv::Point2d center() const { return cv::Point2d(cx, cy); } inline void scale(double factor) { @@ -34,18 +33,6 @@ struct BBox_c h *= factor; } - inline void scale_x(double factor) - { - cx *= factor; - w *= factor; - } - - inline void scale_y(double factor) - { - cy *= factor; - h *= factor; - } - inline cv::Rect get_rect() { return cv::Rect(int(cx-w/2.), int(cy-h/2.), int(w), int(h)); @@ -56,24 +43,18 @@ struct BBox_c class KCF_Tracker { friend ThreadCtx; + friend Kcf_Tracker_Private; public: - bool m_debug {false}; - bool m_use_scale {true}; - bool m_use_color {true}; -#ifdef ASYNC - bool m_use_multithreading {true}; -#else - bool m_use_multithreading {false}; -#endif //ASYNC - bool m_use_subpixel_localization {true}; - bool m_use_subgrid_scale {true}; - bool m_use_cnfeat {true}; - bool m_use_linearkernel {false}; -#ifdef CUFFT - bool m_use_cuda {true}; -#else - bool m_use_cuda {false}; -#endif + bool m_debug {false}; + enum class vd {NONE, PATCH, RESPONSE} m_visual_debug {vd::NONE}; + constexpr static bool m_use_scale {true}; + constexpr static bool m_use_color {true}; + constexpr static bool m_use_subpixel_localization {true}; + constexpr static bool m_use_subgrid_scale {true}; + constexpr static bool m_use_subgrid_angle {true}; + constexpr static bool m_use_cnfeat {true}; + constexpr static bool m_use_linearkernel {false}; + const int p_cell_size = 4; //4 for hog (= bin_size) /* padding ... extra area surrounding the target (1.5) @@ -88,8 +69,8 @@ public: ~KCF_Tracker(); // Init/re-init methods - void init(cv::Mat & img, const cv::Rect & bbox, int fit_size_x, int fit_size_y); - void setTrackerPose(BBox_c & bbox, cv::Mat & img, int fit_size_x, int fit_size_y); + void init(cv::Mat & img, const cv::Rect & bbox, int fit_size_x = -1, int fit_size_y = -1); + void setTrackerPose(BBox_c & bbox, cv::Mat & img, int fit_size_x = -1, int fit_size_y = -1); void updateTrackerPosition(BBox_c & bbox); // frame-to-frame object tracking @@ -100,73 +81,103 @@ public: private: Fft &fft; - BBox_c p_pose; + // Initial pose of tracked object in internal image coordinates + // (scaled by p_downscale_factor if p_resize_image) + BBox_c p_init_pose; + + // Information to calculate current pose of the tracked object + cv::Point2d p_current_center; + double p_current_scale = 1.; + double p_current_angle = 0.; + double max_response = -1.; bool p_resize_image = false; - bool p_fit_to_pw2 = false; - const double p_downscale_factor = 0.5; - double p_scale_factor_x = 1; - double p_scale_factor_y = 1; - const double p_floating_error = 0.0001; + constexpr static double p_downscale_factor = 0.5; + constexpr static double p_floating_error = 0.0001; - double p_padding = 1.5; - double p_output_sigma_factor = 0.1; + const double p_padding = 1.5; + const double p_output_sigma_factor = 0.1; double p_output_sigma; - double p_kernel_sigma = 0.5; //def = 0.5 - double p_lambda = 1e-4; //regularization in learning step - double p_interp_factor = 0.02; //def = 0.02, linear interpolation factor for adaptation - int p_cell_size = 4; //4 for hog (= bin_size) - cv::Size p_windows_size; - uint p_num_scales {7}; - double p_scale_step = 1.02; - double p_current_scale = 1.; + const double p_kernel_sigma = 0.5; //def = 0.5 + const double p_lambda = 1e-4; //regularization in learning step + const double p_interp_factor = 0.02; //def = 0.02, linear interpolation factor for adaptation + cv::Size p_windows_size; // size of the patch to find the tracked object in + cv::Size fit_size; // size to which rescale the patch for better FFT performance + + constexpr static uint p_num_scales = m_use_scale ? 5 : 1; + constexpr static double p_scale_step = 1.03; double p_min_max_scale[2]; std::vector p_scales; - const int p_num_of_feats = 31 + m_use_color ? 3 : 0 + m_use_cnfeat ? 10 : 0; - cv::Size p_roi; + constexpr static uint p_num_angles = 3; + constexpr static int p_angle_step = 10; + std::vector p_angles; + + constexpr static int p_num_of_feats = 31 + (m_use_color ? 3 : 0) + (m_use_cnfeat ? 10 : 0); + cv::Size feature_size; - Kcf_Tracker_Private &d; + std::unique_ptr d; - //CUDA compability - cv::Mat p_rot_labels; - DynMem p_rot_labels_data; + class Model { + cv::Size feature_size; + uint height, width, n_feats; + public: + ComplexMat yf {height, width, 1}; + 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}; - //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; + // Temporary variables for trainig + MatScaleFeats patch_feats{1, n_feats, feature_size}; + MatScaleFeats temp{1, n_feats, feature_size}; + + + + Model(cv::Size feature_size, uint _n_feats) + : feature_size(feature_size) + , height(Fft::freq_size(feature_size).height) + , width(Fft::freq_size(feature_size).width) + , n_feats(_n_feats) {} + }; + + std::unique_ptr model; class GaussianCorrelation { public: - GaussianCorrelation(cv::Size fft_result, uint num_of_scales) - : xf_sqr_norm(num_of_scales * sizeof(float)) - , xyf(fft_result.height, fft_result.width, num_of_scales) + GaussianCorrelation(uint num_scales, uint num_feats, cv::Size size) + : xf_sqr_norm(num_scales) + , xyf(Fft::freq_size(size), num_feats, num_scales) + , ifft_res(num_scales, 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); + void operator()(ComplexMat &result, const ComplexMat &xf, const ComplexMat &yf, double sigma, bool auto_correlation, const KCF_Tracker &kcf); private: DynMem xf_sqr_norm; - DynMem yf_sqr_norm{sizeof(float)}; + DynMem yf_sqr_norm{1}; ComplexMat xyf; + MatScales 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); + 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, double angle) const; cv::Mat gaussian_shaped_labels(double sigma, int dim1, int dim2); std::unique_ptr gaussian_correlation; - cv::Mat circshift(const cv::Mat & patch, int x_rot, int y_rot); - MatDynMem 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 = 1.); - cv::Point2f sub_pixel_peak(cv::Point & max_loc, cv::Mat & response); + cv::Mat circshift(const cv::Mat &patch, int x_rot, int y_rot) const; + cv::Mat cosine_window_function(int dim1, int dim2); + cv::Mat get_features(cv::Mat &input_rgb, cv::Mat &input_gray, cv::Mat *dbg_patch, int cx, int cy, int size_x, int size_y, double scale, double angle) 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); + void train(cv::Mat input_rgb, cv::Mat input_gray, double interp_factor); + double findMaxReponse(uint &max_idx, cv::Point2d &new_location) const; + double sub_grid_angle(uint max_index); }; #endif //KCF_HEADER_6565467831231