X-Git-Url: http://rtime.felk.cvut.cz/gitweb/hercules2020/kcf.git/blobdiff_plain/40fca2ec92f5af176a94cb8add3aca5e9fb200bc..571f4d8d757c1c80ca19da30f7bd2937b60a7f56:/src/kcf.h diff --git a/src/kcf.h b/src/kcf.h index 951986d..76abc5e 100644 --- a/src/kcf.h +++ b/src/kcf.h @@ -3,17 +3,27 @@ #include #include +#include #include "fhog.hpp" + #include "complexmat.hpp" +#ifdef CUFFT +#include "cuda_error_check.hpp" +#include +#endif + #include "cnfeat.hpp" +#include "fft.h" +#include "pragmas.h" -#if defined(FFTW) && defined(ASYNC) -#include -#endif +class Kcf_Tracker_Private; +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) { @@ -25,30 +35,25 @@ struct BBox_c inline cv::Rect get_rect() { - return cv::Rect(cx-w/2., cy-h/2., w, h); + return cv::Rect(int(cx-w/2.), int(cy-h/2.), int(w), int(h)); } }; class KCF_Tracker { + friend ThreadCtx; + friend Kcf_Tracker_Private; public: -#ifdef OPENCV_CUFFT - bool m_use_scale {false}; - bool m_use_color {false}; -#else //OPENCV_CUFFT - bool m_use_scale {true}; - bool m_use_color {true}; -#endif //OPENCV_CUFFT -#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}; + bool m_debug {false}; + bool m_visual_debug {false}; + const bool m_use_scale {true}; + const bool m_use_color {true}; + const bool m_use_subpixel_localization {true}; + const bool m_use_subgrid_scale {true}; + const bool m_use_cnfeat {true}; + const bool m_use_linearkernel {false}; + const int p_cell_size = 4; //4 for hog (= bin_size) /* padding ... extra area surrounding the target (1.5) @@ -58,71 +63,119 @@ public: output_sigma_factor ... spatial bandwidth (proportional to target) (0.1) cell_size ... hog cell size (4) */ - KCF_Tracker(double padding, double kernel_sigma, double lambda, double interp_factor, double output_sigma_factor, int cell_size) : - p_padding(padding), p_output_sigma_factor(output_sigma_factor), p_kernel_sigma(kernel_sigma), - p_lambda(lambda), p_interp_factor(interp_factor), p_cell_size(cell_size) {} - KCF_Tracker() {} + KCF_Tracker(double padding, double kernel_sigma, double lambda, double interp_factor, double output_sigma_factor, int cell_size); + KCF_Tracker(); + ~KCF_Tracker(); // Init/re-init methods - void init(cv::Mat & img, const cv::Rect & bbox); - void setTrackerPose(BBox_c & bbox, cv::Mat & img); + 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 void track(cv::Mat & img); BBox_c getBBox(); + double getFilterResponse() const; // Measure of tracking accuracy private: - BBox_c p_pose; + Fft &fft; + + // 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 first = true; + const double p_downscale_factor = 0.5; + const 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) - int p_windows_size[2]; - cv::Mat p_cos_window; - int 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 + + const uint p_num_scales = m_use_scale ? 7 : 1; + const double p_scale_step = 1.02; double p_min_max_scale[2]; std::vector p_scales; -#ifdef OPENCV_CUFFT - cv::cuda::GpuMat src_gpu,dst_gpu,p_cos_window_d; - cv::cuda::Stream stream; -#endif //OPENCV_CUFFT - - //model - ComplexMat p_yf; - ComplexMat p_model_alphaf; - ComplexMat p_model_alphaf_num; - ComplexMat p_model_alphaf_den; - ComplexMat p_model_xf; - -#if defined(FFTW) && defined(ASYNC) - std::mutex fftw_mut; -#endif + const uint p_num_angles = 1; + const int p_angle_step = 10; + std::vector p_angles; + + const int p_num_of_feats = 31 + (m_use_color ? 3 : 0) + (m_use_cnfeat ? 10 : 0); + cv::Size feature_size; + + std::unique_ptr d; + + 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}; + + // 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(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()(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{1}; + ComplexMat xyf; + MatScales ifft_res; + MatScales k; + }; //helping functions - 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); - ComplexMat gaussian_correlation(const ComplexMat & xf, const ComplexMat & yf, double sigma, bool auto_correlation = false); - cv::Mat circshift(const cv::Mat & patch, int x_rot, int y_rot); + std::unique_ptr gaussian_correlation; + cv::Mat circshift(const cv::Mat &patch, int x_rot, int y_rot) const; cv::Mat cosine_window_function(int dim1, int dim2); - ComplexMat fft2(const cv::Mat & input); - ComplexMat fft2(const std::vector & input, const cv::Mat & cos_window); - - cv::Mat ifft2(const ComplexMat & inputf); - std::vector get_features(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); - double sub_grid_scale(std::vector & responses, int index = -1); - + 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; }; #endif //KCF_HEADER_6565467831231