From d6d599a102e123b99a5c518346b57a2b2bfc8382 Mon Sep 17 00:00:00 2001 From: Jan Oravec Date: Sat, 30 Nov 2019 18:17:55 +0100 Subject: [PATCH 001/121] =?UTF-8?q?Predb=C4=9B=C5=BEn=C3=BD=20n=C3=A1st?= =?UTF-8?q?=C5=99el=20na=20p=C5=99enesen=C3=AD=20ComplexMat=20do=20t=C5=99?= =?UTF-8?q?=C3=ADdy=20Model?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- src/kcf.h | 135 +++++++++++++++++++++++++++++++++++++++++++++++++++++- 1 file changed, 133 insertions(+), 2 deletions(-) diff --git a/src/kcf.h b/src/kcf.h index ff322e83..a323f456 100644 --- a/src/kcf.h +++ b/src/kcf.h @@ -140,12 +140,143 @@ class KCF_Tracker 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}; - - + //------------------------------------------- + //START OF TEST COMPLEXMAT CONVERSION + //------------------------------------------- + + //consider converting to cv::Mat_< std::complex > + cv::Mat yf_Test {height, width, CV_32FC1}; + cv::Mat model_alphaf_Test {height, width, CV_32FC1}; + cv::Mat model_alphaf_num_Test {height, width, CV_32FC1}; + cv::Mat model_alphaf_den_Test {height, width, CV_32FC1}; + cv::Mat model_xf_Test {height, width, CV_32FC(n_feats)}; + cv::Mat xf_Test {height, width, CV_32FC(n_feats)}; + + + static cv::Mat same_size(const cv::Mat &o) + { + return cv::Mat(o.rows, o.cols, o.channels()); + } + + //------ + //size() and channel() already implemented in cv::Mat + //------ + + void set_channel(uint idx, const cv::Mat &mat, cv::Mat &host) + { + assert(idx < host.channels()); + //TODO, part of complexmat.hpp + cudaSync(); + for (uint i = 0; i < host.rows; ++i) { + const std::complex *row = mat.ptr>(i); + for (uint j = 0; j < host.cols; ++j) + //TODO (study its purpose, replace p_data) + //idx = likely channel number + //made for cv::Mat with 2+ channels (so i probably dont need std::complex ? [yes]) + //just put it in the premade channel in cv::Mat as needed + // + //EDIT: consider using this to access and write to channels: + // m.at( row, col )[0] = 1986.0f; + // m.at( row, col )[1] = 326.0f; + p_data.hostMem()[idx * host.rows * host.cols + i * host.cols + j] = row[j]; + } + } + + //------------------ + // YET TO BE EDITED + //------------------ + + // T is constant defined as float + float sqr_norm() const; + + void sqr_norm(DynMem_ &result) const; + + cv::Mat sqr_mag() const; + + cv::Mat conj() const; + + cv::Mat sum_over_channels() const; + + // return 2 channels (real, imag) for first complex channel + cv::Mat to_cv_mat() const + { + assert(p_data.num_elem >= 1); + return channel_to_cv_mat(0); + } + + cv::Mat channel_to_cv_mat(int channel_id) const + { + cv::Mat result(rows, cols, CV_32FC2); + for (uint y = 0; y < rows; ++y) { + std::complex *row_ptr = result.ptr>(y); + for (uint x = 0; x < cols; ++x) { + row_ptr[x] = p_data[channel_id * rows * cols + y * cols + x]; + } + } + return result; + } + + // return a vector of 2 channels (real, imag) per one complex channel + std::vector to_cv_mat_vector() const + { + std::vector result; + result.reserve(n_channels); + + for (uint i = 0; i < n_channels; ++i) + result.push_back(channel_to_cv_mat(i)); + + return result; + } + + // Probably unnecessary now, check usage + std::complex *get_p_data() { + cudaSync(); + return p_data.hostMem(); + } + // Probably unnecessary now, check usage + const std::complex *get_p_data() const { + cudaSync(); + return p_data.hostMem(); + } + + //------ + // operator functions implemented in cv::Mat + //------ + + // convert 2 channel mat (real, imag) to vector row-by-row + std::vector> convert(const cv::Mat &mat) + { + std::vector> result; + result.reserve(mat.cols * mat.rows); + for (int y = 0; y < mat.rows; ++y) { + const T *row_ptr = mat.ptr(y); + for (int x = 0; x < 2 * mat.cols; x += 2) { + result.push_back(std::complex(row_ptr[x], row_ptr[x + 1])); + } + } + return result; + } + + ComplexMat_ mat_mat_operator(void (*op)(std::complex &c_lhs, const std::complex &c_rhs), + const ComplexMat_ &mat_rhs) const; + ComplexMat_ matn_mat1_operator(void (*op)(std::complex &c_lhs, const std::complex &c_rhs), + const ComplexMat_ &mat_rhs) const; + ComplexMat_ matn_mat2_operator(void (*op)(std::complex &c_lhs, const std::complex &c_rhs), + const ComplexMat_ &mat_rhs) const; + ComplexMat_ mat_const_operator(const std::function &c_rhs)> &op) const; + + void cudaSync() const {} + + //------------------------------------------- + //END OF TEST COMPLEXMAT CONVERSION + //------------------------------------------- + + Model(cv::Size feature_size, uint _n_feats) : feature_size(feature_size) , height(Fft::freq_size(feature_size).height) From 6052c1f4f2a3b600a2027f9d1bcd35af853df8a5 Mon Sep 17 00:00:00 2001 From: Jan Oravec Date: Sat, 30 Nov 2019 20:45:32 +0100 Subject: [PATCH 002/121] Most transfered functions edited to work, but needs testing yet --- src/kcf.h | 67 ++++++++++++++++++------------------------------------- 1 file changed, 22 insertions(+), 45 deletions(-) diff --git a/src/kcf.h b/src/kcf.h index a323f456..ce9d047a 100644 --- a/src/kcf.h +++ b/src/kcf.h @@ -149,7 +149,6 @@ class KCF_Tracker //START OF TEST COMPLEXMAT CONVERSION //------------------------------------------- - //consider converting to cv::Mat_< std::complex > cv::Mat yf_Test {height, width, CV_32FC1}; cv::Mat model_alphaf_Test {height, width, CV_32FC1}; cv::Mat model_alphaf_num_Test {height, width, CV_32FC1}; @@ -157,7 +156,7 @@ class KCF_Tracker cv::Mat model_xf_Test {height, width, CV_32FC(n_feats)}; cv::Mat xf_Test {height, width, CV_32FC(n_feats)}; - + // READY FOR TESTING static cv::Mat same_size(const cv::Mat &o) { return cv::Mat(o.rows, o.cols, o.channels()); @@ -167,60 +166,37 @@ class KCF_Tracker //size() and channel() already implemented in cv::Mat //------ + // READY FOR TESTING + // assuming that mat has 2 channels (real, imag) void set_channel(uint idx, const cv::Mat &mat, cv::Mat &host) { assert(idx < host.channels()); //TODO, part of complexmat.hpp cudaSync(); + for (uint i = 0; i < host.rows; ++i) { - const std::complex *row = mat.ptr>(i); - for (uint j = 0; j < host.cols; ++j) - //TODO (study its purpose, replace p_data) - //idx = likely channel number - //made for cv::Mat with 2+ channels (so i probably dont need std::complex ? [yes]) - //just put it in the premade channel in cv::Mat as needed - // - //EDIT: consider using this to access and write to channels: - // m.at( row, col )[0] = 1986.0f; - // m.at( row, col )[1] = 326.0f; - p_data.hostMem()[idx * host.rows * host.cols + i * host.cols + j] = row[j]; + const std::complex *row = mat.ptr>(i); + const std::complex *host_ptr = host.ptr>(i); + for (uint j = 0; j < cols; ++j) + // Can I actually assign like this? Test it. + host_ptr[j] = std::complex(row[j]); } } - //------------------ - // YET TO BE EDITED - //------------------ - - // T is constant defined as float - float sqr_norm() const; - + // DEFINE (=copy definition of) THIS BLOCK IN kcf.cpp + // T type in sqr_norm() is constant defined as float + float sqr_norm() const; void sqr_norm(DynMem_ &result) const; - cv::Mat sqr_mag() const; - cv::Mat conj() const; - cv::Mat sum_over_channels() const; - // return 2 channels (real, imag) for first complex channel - cv::Mat to_cv_mat() const - { - assert(p_data.num_elem >= 1); - return channel_to_cv_mat(0); - } + //------ + // to_cv_mat() and channel_to_cv_mat() unnecesary, since the data is already cv::Mat format + //------ - cv::Mat channel_to_cv_mat(int channel_id) const - { - cv::Mat result(rows, cols, CV_32FC2); - for (uint y = 0; y < rows; ++y) { - std::complex *row_ptr = result.ptr>(y); - for (uint x = 0; x < cols; ++x) { - row_ptr[x] = p_data[channel_id * rows * cols + y * cols + x]; - } - } - return result; - } + // DECIDE IF THIS IS ACTUALLY NEEDED WITH CURRENT cv::Mat FORMAT // return a vector of 2 channels (real, imag) per one complex channel std::vector to_cv_mat_vector() const { @@ -248,20 +224,22 @@ class KCF_Tracker // operator functions implemented in cv::Mat //------ + // READY FOR TESTING // convert 2 channel mat (real, imag) to vector row-by-row - std::vector> convert(const cv::Mat &mat) + std::vector> convert(const cv::Mat &mat) { - std::vector> result; + std::vector> result; result.reserve(mat.cols * mat.rows); for (int y = 0; y < mat.rows; ++y) { - const T *row_ptr = mat.ptr(y); + const float *row_ptr = mat.ptr(y); for (int x = 0; x < 2 * mat.cols; x += 2) { - result.push_back(std::complex(row_ptr[x], row_ptr[x + 1])); + result.push_back(std::complex(row_ptr[x], row_ptr[x + 1])); } } return result; } + // DEFINE (=copy definition of) THIS BLOCK IN kcf.cpp ComplexMat_ mat_mat_operator(void (*op)(std::complex &c_lhs, const std::complex &c_rhs), const ComplexMat_ &mat_rhs) const; ComplexMat_ matn_mat1_operator(void (*op)(std::complex &c_lhs, const std::complex &c_rhs), @@ -269,7 +247,6 @@ class KCF_Tracker ComplexMat_ matn_mat2_operator(void (*op)(std::complex &c_lhs, const std::complex &c_rhs), const ComplexMat_ &mat_rhs) const; ComplexMat_ mat_const_operator(const std::function &c_rhs)> &op) const; - void cudaSync() const {} //------------------------------------------- From a3bef623c08ddfcc232e9a19ea2858b0a9783f0e Mon Sep 17 00:00:00 2001 From: Jan Oravec Date: Sun, 1 Dec 2019 23:26:39 +0100 Subject: [PATCH 003/121] Added identification of some functions in header --- src/kcf.h | 20 ++++++++++++++------ 1 file changed, 14 insertions(+), 6 deletions(-) diff --git a/src/kcf.h b/src/kcf.h index ce9d047a..fa797120 100644 --- a/src/kcf.h +++ b/src/kcf.h @@ -183,13 +183,20 @@ class KCF_Tracker } } - // DEFINE (=copy definition of) THIS BLOCK IN kcf.cpp - // T type in sqr_norm() is constant defined as float - float sqr_norm() const; - void sqr_norm(DynMem_ &result) const; + // This computes a float value using elements in individual channels + float sqr_norm(cv::Mat &host) const; + + // This edits given Dynmem to contain computed float value in its [1] position (why?) + void sqr_norm(DynMem_ &result, cv::Mat &host) const; + + // Applies square operation to all elements in all channels cv::Mat sqr_mag() const; + + // Applies "invert imaginary number" operation to all elements in all channels cv::Mat conj() const; - cv::Mat sum_over_channels() const; + + // DEFINE (=copy definition of) THIS BLOCK IN kcf.cpp + cv::Mat sum_over_channels(cv::Mat &host) const; //------ // to_cv_mat() and channel_to_cv_mat() unnecesary, since the data is already cv::Mat format @@ -221,7 +228,7 @@ class KCF_Tracker } //------ - // operator functions implemented in cv::Mat + // operator and mul() functions implemented in cv::Mat //------ // READY FOR TESTING @@ -240,6 +247,7 @@ class KCF_Tracker } // DEFINE (=copy definition of) THIS BLOCK IN kcf.cpp + // [ possibly completely replaced by cv::Mat.forEach() ] ComplexMat_ mat_mat_operator(void (*op)(std::complex &c_lhs, const std::complex &c_rhs), const ComplexMat_ &mat_rhs) const; ComplexMat_ matn_mat1_operator(void (*op)(std::complex &c_lhs, const std::complex &c_rhs), From 6c0868d830d10501cb5413a9604483da58cc022e Mon Sep 17 00:00:00 2001 From: Your Name Date: Mon, 2 Dec 2019 17:16:58 +0100 Subject: [PATCH 004/121] =?UTF-8?q?-=20Funkce=20kter=C3=A9=20byly=20p?= =?UTF-8?q?=C5=AFvodn=C4=9B=20p=C5=99esunuty=20z=20ComplexMat=20do=20KCF?= =?UTF-8?q?=5FTracker::Model=20nyn=C3=AD=20p=C5=99esunuty=20do=20nov=C3=A9?= =?UTF-8?q?ho=20souboru=20cvmat=5Ffunc.h?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- src/cvmat_func.cpp | 0 src/cvmat_func.h | 134 +++++++++++++++++++++++++++++++++++++++++++++ src/kcf.h | 111 +------------------------------------ 3 files changed, 137 insertions(+), 108 deletions(-) create mode 100644 src/cvmat_func.cpp create mode 100644 src/cvmat_func.h diff --git a/src/cvmat_func.cpp b/src/cvmat_func.cpp new file mode 100644 index 00000000..e69de29b diff --git a/src/cvmat_func.h b/src/cvmat_func.h new file mode 100644 index 00000000..34dc2489 --- /dev/null +++ b/src/cvmat_func.h @@ -0,0 +1,134 @@ + +#ifndef CVMAT_FUNC_H +#define CVMAT_FUNC_H + +#include +#include +#include +#include "fhog.hpp" + +#ifdef CUFFT +#include "cuda_error_check.hpp" +#include +#endif + +#include "cnfeat.hpp" +#ifdef FFTW +#include "fft_fftw.h" +#define FFT Fftw +#elif defined(CUFFT) +#include "fft_cufft.h" +#define FFT cuFFT +#else +#include "fft_opencv.h" +#define FFT FftOpencv +#endif +#include "pragmas.h" + + + +// READY FOR TESTING +static cv::Mat same_size(const cv::Mat &o) +{ + return cv::Mat(o.rows, o.cols, o.channels()); +} + +//------ +//size() and channel() already implemented in cv::Mat +//------ + +// READY FOR TESTING +// assuming that mat has 2 channels (real, imag) +void set_channel(uint idx, const cv::Mat &mat, cv::Mat &host) +{ + assert(idx < host.channels()); + //TODO, part of complexmat.hpp + cudaSync(); + + for (uint i = 0; i < host.rows; ++i) { + const std::complex *row = mat.ptr>(i); + const std::complex *host_ptr = host.ptr>(i); + for (uint j = 0; j < cols; ++j) + // Can I actually assign like this? Test it. + host_ptr[j] = std::complex(row[j]); + } +} + +// This computes a float value using elements in individual channels +float sqr_norm(cv::Mat &host) const; + +// This edits given Dynmem to contain computed float value in its [1] position (why?) +void sqr_norm(DynMem_ &result, cv::Mat &host) const; + +// Applies square operation to all elements in all channels +cv::Mat sqr_mag() const; + +// Applies "invert imaginary number" operation to all elements in all channels +cv::Mat conj() const; + +// DEFINE (=copy definition of) THIS BLOCK IN kcf.cpp +cv::Mat sum_over_channels(cv::Mat &host) const; + +//------ +// to_cv_mat() and channel_to_cv_mat() unnecesary, since the data is already cv::Mat format +//------ + + +// DECIDE IF THIS IS ACTUALLY NEEDED WITH CURRENT cv::Mat FORMAT +// return a vector of 2 channels (real, imag) per one complex channel +std::vector to_cv_mat_vector() const +{ + std::vector result; + result.reserve(n_channels); + + for (uint i = 0; i < n_channels; ++i) + result.push_back(channel_to_cv_mat(i)); + + return result; +} + +// Probably unnecessary now, check usage +std::complex *get_p_data() { + cudaSync(); + return p_data.hostMem(); +} +// Probably unnecessary now, check usage +const std::complex *get_p_data() const { + cudaSync(); + return p_data.hostMem(); +} + +//------ +// operator and mul() functions implemented in cv::Mat +//------ + +// READY FOR TESTING +// convert 2 channel mat (real, imag) to vector row-by-row +std::vector> convert(const cv::Mat &mat) +{ + std::vector> result; + result.reserve(mat.cols * mat.rows); + for (int y = 0; y < mat.rows; ++y) { + const float *row_ptr = mat.ptr(y); + for (int x = 0; x < 2 * mat.cols; x += 2) { + result.push_back(std::complex(row_ptr[x], row_ptr[x + 1])); + } + } + return result; +} + +// DEFINE (=copy definition of) THIS BLOCK IN kcf.cpp +// [ possibly completely replaced by cv::Mat.forEach() ] +ComplexMat_ mat_mat_operator(void (*op)(std::complex &c_lhs, const std::complex &c_rhs), + const ComplexMat_ &mat_rhs) const; +ComplexMat_ matn_mat1_operator(void (*op)(std::complex &c_lhs, const std::complex &c_rhs), + const ComplexMat_ &mat_rhs) const; +ComplexMat_ matn_mat2_operator(void (*op)(std::complex &c_lhs, const std::complex &c_rhs), + const ComplexMat_ &mat_rhs) const; +ComplexMat_ mat_const_operator(const std::function &c_rhs)> &op) const; +void cudaSync() const {} + + + +#endif /* CVMAT_FUNC_H */ + diff --git a/src/kcf.h b/src/kcf.h index fa797120..308dbd4f 100644 --- a/src/kcf.h +++ b/src/kcf.h @@ -141,14 +141,13 @@ class KCF_Tracker ComplexMat xf {height, width, n_feats}; - // Temporary variables for trainig + // Temporary variables for training MatScaleFeats patch_feats{1, n_feats, feature_size}; MatScaleFeats temp{1, n_feats, feature_size}; - //------------------------------------------- - //START OF TEST COMPLEXMAT CONVERSION - //------------------------------------------- + // FORMER ATTRIBUTES CONVERTED TO cv::Mat + // Something about not being able to tell which kind of cv::Mat (complex matrix does not equal 2 channels !) cv::Mat yf_Test {height, width, CV_32FC1}; cv::Mat model_alphaf_Test {height, width, CV_32FC1}; cv::Mat model_alphaf_num_Test {height, width, CV_32FC1}; @@ -156,110 +155,6 @@ class KCF_Tracker cv::Mat model_xf_Test {height, width, CV_32FC(n_feats)}; cv::Mat xf_Test {height, width, CV_32FC(n_feats)}; - // READY FOR TESTING - static cv::Mat same_size(const cv::Mat &o) - { - return cv::Mat(o.rows, o.cols, o.channels()); - } - - //------ - //size() and channel() already implemented in cv::Mat - //------ - - // READY FOR TESTING - // assuming that mat has 2 channels (real, imag) - void set_channel(uint idx, const cv::Mat &mat, cv::Mat &host) - { - assert(idx < host.channels()); - //TODO, part of complexmat.hpp - cudaSync(); - - for (uint i = 0; i < host.rows; ++i) { - const std::complex *row = mat.ptr>(i); - const std::complex *host_ptr = host.ptr>(i); - for (uint j = 0; j < cols; ++j) - // Can I actually assign like this? Test it. - host_ptr[j] = std::complex(row[j]); - } - } - - // This computes a float value using elements in individual channels - float sqr_norm(cv::Mat &host) const; - - // This edits given Dynmem to contain computed float value in its [1] position (why?) - void sqr_norm(DynMem_ &result, cv::Mat &host) const; - - // Applies square operation to all elements in all channels - cv::Mat sqr_mag() const; - - // Applies "invert imaginary number" operation to all elements in all channels - cv::Mat conj() const; - - // DEFINE (=copy definition of) THIS BLOCK IN kcf.cpp - cv::Mat sum_over_channels(cv::Mat &host) const; - - //------ - // to_cv_mat() and channel_to_cv_mat() unnecesary, since the data is already cv::Mat format - //------ - - - // DECIDE IF THIS IS ACTUALLY NEEDED WITH CURRENT cv::Mat FORMAT - // return a vector of 2 channels (real, imag) per one complex channel - std::vector to_cv_mat_vector() const - { - std::vector result; - result.reserve(n_channels); - - for (uint i = 0; i < n_channels; ++i) - result.push_back(channel_to_cv_mat(i)); - - return result; - } - - // Probably unnecessary now, check usage - std::complex *get_p_data() { - cudaSync(); - return p_data.hostMem(); - } - // Probably unnecessary now, check usage - const std::complex *get_p_data() const { - cudaSync(); - return p_data.hostMem(); - } - - //------ - // operator and mul() functions implemented in cv::Mat - //------ - - // READY FOR TESTING - // convert 2 channel mat (real, imag) to vector row-by-row - std::vector> convert(const cv::Mat &mat) - { - std::vector> result; - result.reserve(mat.cols * mat.rows); - for (int y = 0; y < mat.rows; ++y) { - const float *row_ptr = mat.ptr(y); - for (int x = 0; x < 2 * mat.cols; x += 2) { - result.push_back(std::complex(row_ptr[x], row_ptr[x + 1])); - } - } - return result; - } - - // DEFINE (=copy definition of) THIS BLOCK IN kcf.cpp - // [ possibly completely replaced by cv::Mat.forEach() ] - ComplexMat_ mat_mat_operator(void (*op)(std::complex &c_lhs, const std::complex &c_rhs), - const ComplexMat_ &mat_rhs) const; - ComplexMat_ matn_mat1_operator(void (*op)(std::complex &c_lhs, const std::complex &c_rhs), - const ComplexMat_ &mat_rhs) const; - ComplexMat_ matn_mat2_operator(void (*op)(std::complex &c_lhs, const std::complex &c_rhs), - const ComplexMat_ &mat_rhs) const; - ComplexMat_ mat_const_operator(const std::function &c_rhs)> &op) const; - void cudaSync() const {} - - //------------------------------------------- - //END OF TEST COMPLEXMAT CONVERSION - //------------------------------------------- Model(cv::Size feature_size, uint _n_feats) From a4935ee228d269bfc55c15c22293e63e800a8195 Mon Sep 17 00:00:00 2001 From: Your Name Date: Mon, 2 Dec 2019 17:32:58 +0100 Subject: [PATCH 005/121] =?UTF-8?q?-=20Odstran=C4=9Bny=20warning=20kter?= =?UTF-8?q?=C3=A9=20se=20objevovaly=20p=C5=99i=20=C5=BE=C3=A1dosti=20o=20p?= =?UTF-8?q?ull=20request?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- src/kcf.h | 12 ++++++------ 1 file changed, 6 insertions(+), 6 deletions(-) diff --git a/src/kcf.h b/src/kcf.h index 308dbd4f..6ad5bc88 100644 --- a/src/kcf.h +++ b/src/kcf.h @@ -148,12 +148,12 @@ class KCF_Tracker // FORMER ATTRIBUTES CONVERTED TO cv::Mat // Something about not being able to tell which kind of cv::Mat (complex matrix does not equal 2 channels !) - cv::Mat yf_Test {height, width, CV_32FC1}; - cv::Mat model_alphaf_Test {height, width, CV_32FC1}; - cv::Mat model_alphaf_num_Test {height, width, CV_32FC1}; - cv::Mat model_alphaf_den_Test {height, width, CV_32FC1}; - cv::Mat model_xf_Test {height, width, CV_32FC(n_feats)}; - cv::Mat xf_Test {height, width, CV_32FC(n_feats)}; + cv::Mat yf_Test {(int) height, (int) width, CV_32FC1}; + cv::Mat model_alphaf_Test {(int) height, (int) width, CV_32FC1}; + cv::Mat model_alphaf_num_Test {(int) height, (int) width, CV_32FC1}; + cv::Mat model_alphaf_den_Test {(int) height, (int) width, CV_32FC1}; + cv::Mat model_xf_Test {(int) height, (int) width, CV_32FC(n_feats)}; + cv::Mat xf_Test {(int) height, (int) width, CV_32FC(n_feats)}; From 67748918cfc9f50b25e6331bcf54f91ff2407475 Mon Sep 17 00:00:00 2001 From: Your Name Date: Mon, 2 Dec 2019 18:01:52 +0100 Subject: [PATCH 006/121] =?UTF-8?q?-=20Odstran=C4=9Bna=20funkce=20get=5Fp?= =?UTF-8?q?=5Fdata()?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- src/cvmat_func.h | 17 +++++------------ 1 file changed, 5 insertions(+), 12 deletions(-) diff --git a/src/cvmat_func.h b/src/cvmat_func.h index 34dc2489..dd1d92f7 100644 --- a/src/cvmat_func.h +++ b/src/cvmat_func.h @@ -28,7 +28,7 @@ // READY FOR TESTING -static cv::Mat same_size(const cv::Mat &o) +cv::Mat same_size(const cv::Mat &o) { return cv::Mat(o.rows, o.cols, o.channels()); } @@ -38,6 +38,8 @@ static cv::Mat same_size(const cv::Mat &o) //------ // READY FOR TESTING +// ANALYSE USAGE +// Used only at fft_opencv.cpp in a single place. // assuming that mat has 2 channels (real, imag) void set_channel(uint idx, const cv::Mat &mat, cv::Mat &host) { @@ -87,19 +89,10 @@ std::vector to_cv_mat_vector() const return result; } -// Probably unnecessary now, check usage -std::complex *get_p_data() { - cudaSync(); - return p_data.hostMem(); -} -// Probably unnecessary now, check usage -const std::complex *get_p_data() const { - cudaSync(); - return p_data.hostMem(); -} //------ -// operator and mul() functions implemented in cv::Mat +// get_p_data() unnecessary +// mul() and operator functions implemented in cv::Mat //------ // READY FOR TESTING From 7c6f8db1b20848dafa3ab154aebf8a342ea34e21 Mon Sep 17 00:00:00 2001 From: Your Name Date: Mon, 2 Dec 2019 18:58:24 +0100 Subject: [PATCH 007/121] =?UTF-8?q?-=20N=C3=A1st=C5=99el=20na=20definici?= =?UTF-8?q?=20sqr=5Fnorm=20-=20Prozat=C3=ADm=20asi=20jedin=C3=A1=20u=C5=BE?= =?UTF-8?q?ite=C4=8Dn=C3=A1=20v=C4=9Bc=20odstran=C4=9Bn=C3=AD=20warning=20?= =?UTF-8?q?a=20p=C5=99esun=20do=20nov=C3=A9ho=20souboru=20-=20je=20t=C5=99?= =?UTF-8?q?eba=20p=C5=99ipravit=20=C3=BApravy=20vol=C3=A1n=C3=AD=20v=20k?= =?UTF-8?q?=C3=B3du=20k=20otestov=C3=A1n=C3=AD?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- src/cvmat_func.cpp | 16 ++++++++++++++++ src/cvmat_func.h | 10 ++++------ 2 files changed, 20 insertions(+), 6 deletions(-) diff --git a/src/cvmat_func.cpp b/src/cvmat_func.cpp index e69de29b..66798764 100644 --- a/src/cvmat_func.cpp +++ b/src/cvmat_func.cpp @@ -0,0 +1,16 @@ + +#include + +float sqr_norm(cv::Mat &host) const +{ + int n_channels_per_scale = host.channels(); + float sum_sqr_norm = 0; + for (int i = 0; i < n_channels_per_scale; ++i) { + for (auto lhs = p_data.hostMem() + i * host.rows * host.cols; + lhs != p_data.hostMem() + (i + 1) * host.rows * host.cols; ++lhs) + // consider using cv::norm() of type NORM_L2SQR for each channel + sum_sqr_norm += lhs->real() * lhs->real() + lhs->imag() * lhs->imag(); + } + sum_sqr_norm = sum_sqr_norm / (float)(host.cols * host.rows); + return sum_sqr_norm; +} \ No newline at end of file diff --git a/src/cvmat_func.h b/src/cvmat_func.h index dd1d92f7..767ecffa 100644 --- a/src/cvmat_func.h +++ b/src/cvmat_func.h @@ -27,7 +27,7 @@ -// READY FOR TESTING +// CHECK USAGE, OTHERWISE DONE cv::Mat same_size(const cv::Mat &o) { return cv::Mat(o.rows, o.cols, o.channels()); @@ -37,9 +37,8 @@ cv::Mat same_size(const cv::Mat &o) //size() and channel() already implemented in cv::Mat //------ -// READY FOR TESTING -// ANALYSE USAGE -// Used only at fft_opencv.cpp in a single place. +// ANALYSE USAGE, EDIT AND SIMPLIYFY +// Used only in a single place at fft_opencv.cpp . // assuming that mat has 2 channels (real, imag) void set_channel(uint idx, const cv::Mat &mat, cv::Mat &host) { @@ -56,7 +55,7 @@ void set_channel(uint idx, const cv::Mat &mat, cv::Mat &host) } } -// This computes a float value using elements in individual channels +// This computes a float value using elements in individual channels (seems unused) float sqr_norm(cv::Mat &host) const; // This edits given Dynmem to contain computed float value in its [1] position (why?) @@ -119,7 +118,6 @@ ComplexMat_ matn_mat1_operator(void (*op)(std::complex &c_lhs, const std::com ComplexMat_ matn_mat2_operator(void (*op)(std::complex &c_lhs, const std::complex &c_rhs), const ComplexMat_ &mat_rhs) const; ComplexMat_ mat_const_operator(const std::function &c_rhs)> &op) const; -void cudaSync() const {} From 4cdc769d5e80d3c0efec8fc5d420a4cccea9fca2 Mon Sep 17 00:00:00 2001 From: Jan Oravec Date: Mon, 2 Dec 2019 22:46:49 +0100 Subject: [PATCH 008/121] test --- src/cvmat_func.cpp | 31 ++++++++++++++++--------------- 1 file changed, 16 insertions(+), 15 deletions(-) diff --git a/src/cvmat_func.cpp b/src/cvmat_func.cpp index 66798764..f1d38a6d 100644 --- a/src/cvmat_func.cpp +++ b/src/cvmat_func.cpp @@ -1,16 +1,17 @@ - -#include - -float sqr_norm(cv::Mat &host) const -{ - int n_channels_per_scale = host.channels(); - float sum_sqr_norm = 0; - for (int i = 0; i < n_channels_per_scale; ++i) { - for (auto lhs = p_data.hostMem() + i * host.rows * host.cols; - lhs != p_data.hostMem() + (i + 1) * host.rows * host.cols; ++lhs) - // consider using cv::norm() of type NORM_L2SQR for each channel - sum_sqr_norm += lhs->real() * lhs->real() + lhs->imag() * lhs->imag(); - } - sum_sqr_norm = sum_sqr_norm / (float)(host.cols * host.rows); - return sum_sqr_norm; + +#include + +float sqr_norm(cv::Mat &host) const +{ + // test + int n_channels_per_scale = host.channels(); + float sum_sqr_norm = 0; + for (int i = 0; i < n_channels_per_scale; ++i) { + for (auto lhs = p_data.hostMem() + i * host.rows * host.cols; + lhs != p_data.hostMem() + (i + 1) * host.rows * host.cols; ++lhs) + // consider using cv::norm() of type NORM_L2SQR for each channel + sum_sqr_norm += lhs->real() * lhs->real() + lhs->imag() * lhs->imag(); + } + sum_sqr_norm = sum_sqr_norm / (float)(host.cols * host.rows); + return sum_sqr_norm; } \ No newline at end of file From fe39e3cd7c59759969808d014efcacb361598f6a Mon Sep 17 00:00:00 2001 From: Jan Oravec Date: Tue, 3 Dec 2019 01:08:58 +0100 Subject: [PATCH 009/121] Added probably final definiton for set_channel() - also removed test comment --- src/cvmat_func.cpp | 1 - src/cvmat_func.h | 235 +++++++++++++++++++++------------------------ 2 files changed, 110 insertions(+), 126 deletions(-) diff --git a/src/cvmat_func.cpp b/src/cvmat_func.cpp index f1d38a6d..8ed303e2 100644 --- a/src/cvmat_func.cpp +++ b/src/cvmat_func.cpp @@ -3,7 +3,6 @@ float sqr_norm(cv::Mat &host) const { - // test int n_channels_per_scale = host.channels(); float sum_sqr_norm = 0; for (int i = 0; i < n_channels_per_scale; ++i) { diff --git a/src/cvmat_func.h b/src/cvmat_func.h index 767ecffa..c4c868bd 100644 --- a/src/cvmat_func.h +++ b/src/cvmat_func.h @@ -1,125 +1,110 @@ - -#ifndef CVMAT_FUNC_H -#define CVMAT_FUNC_H - -#include -#include -#include -#include "fhog.hpp" - -#ifdef CUFFT -#include "cuda_error_check.hpp" -#include -#endif - -#include "cnfeat.hpp" -#ifdef FFTW -#include "fft_fftw.h" -#define FFT Fftw -#elif defined(CUFFT) -#include "fft_cufft.h" -#define FFT cuFFT -#else -#include "fft_opencv.h" -#define FFT FftOpencv -#endif -#include "pragmas.h" - - - -// CHECK USAGE, OTHERWISE DONE -cv::Mat same_size(const cv::Mat &o) -{ - return cv::Mat(o.rows, o.cols, o.channels()); -} - -//------ -//size() and channel() already implemented in cv::Mat -//------ - -// ANALYSE USAGE, EDIT AND SIMPLIYFY -// Used only in a single place at fft_opencv.cpp . -// assuming that mat has 2 channels (real, imag) -void set_channel(uint idx, const cv::Mat &mat, cv::Mat &host) -{ - assert(idx < host.channels()); - //TODO, part of complexmat.hpp - cudaSync(); - - for (uint i = 0; i < host.rows; ++i) { - const std::complex *row = mat.ptr>(i); - const std::complex *host_ptr = host.ptr>(i); - for (uint j = 0; j < cols; ++j) - // Can I actually assign like this? Test it. - host_ptr[j] = std::complex(row[j]); - } -} - -// This computes a float value using elements in individual channels (seems unused) -float sqr_norm(cv::Mat &host) const; - -// This edits given Dynmem to contain computed float value in its [1] position (why?) -void sqr_norm(DynMem_ &result, cv::Mat &host) const; - -// Applies square operation to all elements in all channels -cv::Mat sqr_mag() const; - -// Applies "invert imaginary number" operation to all elements in all channels -cv::Mat conj() const; - -// DEFINE (=copy definition of) THIS BLOCK IN kcf.cpp -cv::Mat sum_over_channels(cv::Mat &host) const; - -//------ -// to_cv_mat() and channel_to_cv_mat() unnecesary, since the data is already cv::Mat format -//------ - - -// DECIDE IF THIS IS ACTUALLY NEEDED WITH CURRENT cv::Mat FORMAT -// return a vector of 2 channels (real, imag) per one complex channel -std::vector to_cv_mat_vector() const -{ - std::vector result; - result.reserve(n_channels); - - for (uint i = 0; i < n_channels; ++i) - result.push_back(channel_to_cv_mat(i)); - - return result; -} - - -//------ -// get_p_data() unnecessary -// mul() and operator functions implemented in cv::Mat -//------ - -// READY FOR TESTING -// convert 2 channel mat (real, imag) to vector row-by-row -std::vector> convert(const cv::Mat &mat) -{ - std::vector> result; - result.reserve(mat.cols * mat.rows); - for (int y = 0; y < mat.rows; ++y) { - const float *row_ptr = mat.ptr(y); - for (int x = 0; x < 2 * mat.cols; x += 2) { - result.push_back(std::complex(row_ptr[x], row_ptr[x + 1])); - } - } - return result; -} - -// DEFINE (=copy definition of) THIS BLOCK IN kcf.cpp -// [ possibly completely replaced by cv::Mat.forEach() ] -ComplexMat_ mat_mat_operator(void (*op)(std::complex &c_lhs, const std::complex &c_rhs), - const ComplexMat_ &mat_rhs) const; -ComplexMat_ matn_mat1_operator(void (*op)(std::complex &c_lhs, const std::complex &c_rhs), - const ComplexMat_ &mat_rhs) const; -ComplexMat_ matn_mat2_operator(void (*op)(std::complex &c_lhs, const std::complex &c_rhs), - const ComplexMat_ &mat_rhs) const; -ComplexMat_ mat_const_operator(const std::function &c_rhs)> &op) const; - - - -#endif /* CVMAT_FUNC_H */ - + +#ifndef CVMAT_FUNC_H +#define CVMAT_FUNC_H + +#include +#include +#include +#include "fhog.hpp" + +#ifdef CUFFT +#include "cuda_error_check.hpp" +#include +#endif + +#include "cnfeat.hpp" +#ifdef FFTW +#include "fft_fftw.h" +#define FFT Fftw +#elif defined(CUFFT) +#include "fft_cufft.h" +#define FFT cuFFT +#else +#include "fft_opencv.h" +#define FFT FftOpencv +#endif +#include "pragmas.h" + + +//------ +//same_size() only used in complexmat.cu , ignored +//size() and channel() already implemented in cv::Mat +//------ + +// READY FOR USE +// Used only in a single place at fft_opencv.cpp, target is ComplexMat (convert first) +// Probably easier to use this inline. +void set_channel(uint idx, const cv::Mat &mat, cv::Mat &host) +{ + assert(idx < host.channels()); + cv::mixChannels( &mat, 1, &host, 1, { idx,idx }, 1 ); +} + +// This computes a float value using elements in individual channels (seems unused) +float sqr_norm(cv::Mat &host) const; + +// This edits given Dynmem to contain computed float value in its [1] position (why?) +void sqr_norm(DynMem_ &result, cv::Mat &host) const; + +// Applies square operation to all elements in all channels +cv::Mat sqr_mag() const; + +// Applies "invert imaginary number" operation to all elements in all channels +cv::Mat conj() const; + +// DEFINE (=copy definition of) THIS BLOCK IN kcf.cpp +cv::Mat sum_over_channels(cv::Mat &host) const; + +//------ +// to_cv_mat() and channel_to_cv_mat() unnecesary, since the data is already cv::Mat format +//------ + + +// DECIDE IF THIS IS ACTUALLY NEEDED WITH CURRENT cv::Mat FORMAT +// return a vector of 2 channels (real, imag) per one complex channel +std::vector to_cv_mat_vector() const +{ + std::vector result; + result.reserve(n_channels); + + for (uint i = 0; i < n_channels; ++i) + result.push_back(channel_to_cv_mat(i)); + + return result; +} + + +//------ +// get_p_data() unnecessary +// mul() and operator functions implemented in cv::Mat +//------ + +// READY FOR TESTING +// convert 2 channel mat (real, imag) to vector row-by-row +std::vector> convert(const cv::Mat &mat) +{ + std::vector> result; + result.reserve(mat.cols * mat.rows); + for (int y = 0; y < mat.rows; ++y) { + const float *row_ptr = mat.ptr(y); + for (int x = 0; x < 2 * mat.cols; x += 2) { + result.push_back(std::complex(row_ptr[x], row_ptr[x + 1])); + } + } + return result; +} + +// DEFINE (=copy definition of) THIS BLOCK IN kcf.cpp +// [ possibly completely replaced by cv::Mat.forEach() ] +ComplexMat_ mat_mat_operator(void (*op)(std::complex &c_lhs, const std::complex &c_rhs), + const ComplexMat_ &mat_rhs) const; +ComplexMat_ matn_mat1_operator(void (*op)(std::complex &c_lhs, const std::complex &c_rhs), + const ComplexMat_ &mat_rhs) const; +ComplexMat_ matn_mat2_operator(void (*op)(std::complex &c_lhs, const std::complex &c_rhs), + const ComplexMat_ &mat_rhs) const; +ComplexMat_ mat_const_operator(const std::function &c_rhs)> &op) const; + + + +#endif /* CVMAT_FUNC_H */ + From 453953dbcec4c0f037ae5d94507652d7e5c96e64 Mon Sep 17 00:00:00 2001 From: Jan Oravec Date: Tue, 3 Dec 2019 01:11:11 +0100 Subject: [PATCH 010/121] Added assert to set_channel --- src/cvmat_func.h | 1 + 1 file changed, 1 insertion(+) diff --git a/src/cvmat_func.h b/src/cvmat_func.h index c4c868bd..80ebaa5f 100644 --- a/src/cvmat_func.h +++ b/src/cvmat_func.h @@ -37,6 +37,7 @@ void set_channel(uint idx, const cv::Mat &mat, cv::Mat &host) { assert(idx < host.channels()); + assert(idx < mat.channels()); cv::mixChannels( &mat, 1, &host, 1, { idx,idx }, 1 ); } From d91f2becce56b477574d812da6ed536b2e46c8fc Mon Sep 17 00:00:00 2001 From: Your Name Date: Tue, 10 Dec 2019 17:17:38 +0100 Subject: [PATCH 011/121] =?UTF-8?q?P=C5=99id=C3=A1no=20upraven=C3=A9=20vol?= =?UTF-8?q?=C3=A1n=C3=AD=20fft.forward()=20p=C5=99i=20inicializaci=20track?= =?UTF-8?q?eru.=20-=20v=C3=BDsledek=20nov=C3=A9ho=20vol=C3=A1n=C3=AD=20je?= =?UTF-8?q?=202=20kan=C3=A1lov=C3=BD=20cv::Mat=20-=20obsah=20je=20stejn?= =?UTF-8?q?=C3=BD=20jako=20jeho=20prot=C4=9Bj=C5=A1ek=20v=20ComplexMat=20(?= =?UTF-8?q?otestov=C3=A1no)=20-=20p=C5=AFvodn=C3=AD=20vol=C3=A1n=C3=AD=20z?= =?UTF-8?q?at=C3=ADm=20ponech=C3=A1no,=20vol=C3=A1=20se=20te=C4=8F=20z?= =?UTF-8?q?=C3=A1pis=20do=20p=C5=AFvodn=C3=AD=20i=20upraven=C3=A9=20prom?= =?UTF-8?q?=C4=9Bnn=C3=A9?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- src/fft_opencv.cpp | 7 +++++++ src/fft_opencv.h | 4 ++++ src/kcf.cpp | 12 ++++++++++++ src/kcf.h | 8 ++++---- 4 files changed, 27 insertions(+), 4 deletions(-) diff --git a/src/fft_opencv.cpp b/src/fft_opencv.cpp index a41412a3..95c051c1 100644 --- a/src/fft_opencv.cpp +++ b/src/fft_opencv.cpp @@ -20,6 +20,13 @@ void FftOpencv::forward(const MatScales &real_input, ComplexMat &complex_result) complex_result = ComplexMat(tmp); } +void FftOpencv::forward(const cv::Mat &real_input, cv::Mat &complex_result) +{ +// Fft::forward(real_input, complex_result); + + cv::dft(real_input, complex_result, cv::DFT_COMPLEX_OUTPUT); +} + void FftOpencv::forward_window(MatScaleFeats &feat, ComplexMat &complex_result, MatScaleFeats &temp) { Fft::forward_window(feat, complex_result, temp); diff --git a/src/fft_opencv.h b/src/fft_opencv.h index 032989b4..804bd5db 100644 --- a/src/fft_opencv.h +++ b/src/fft_opencv.h @@ -10,6 +10,10 @@ class FftOpencv : public Fft void init(unsigned width, unsigned height, unsigned num_of_feats, unsigned num_of_scales); void set_window(const MatDynMem &window); void forward(const MatScales &real_input, ComplexMat &complex_result); + + //REPLACEMENT + void forward(const cv::Mat &real_input, cv::Mat &complex_result); + void forward_window(MatScaleFeats &patch_feats_in, ComplexMat &complex_result, MatScaleFeats &tmp); void inverse(ComplexMat &complex_input, MatScales &real_result); ~FftOpencv(); diff --git a/src/kcf.cpp b/src/kcf.cpp index d2b7dbef..7ca361ed 100644 --- a/src/kcf.cpp +++ b/src/kcf.cpp @@ -236,8 +236,20 @@ void KCF_Tracker::init(cv::Mat &img, const cv::Rect &bbox, int fit_size_x, int f MatScales gsl(1, feature_size); gaussian_shaped_labels(p_output_sigma, feature_size.width, feature_size.height).copyTo(gsl.plane(0)); fft.forward(gsl, model->yf); + +// REPLACEMENT + cv::Mat gsl2(feature_size,CV_32F); + gaussian_shaped_labels(p_output_sigma, feature_size.width, feature_size.height).copyTo(gsl2); + fft.forward(gsl2, model->yf_Test); + DEBUG_PRINTM(model->yf); + DEBUG_PRINTM(model->yf_Test); +// Accessing cv::Mat real/imag channels +// std::complex* f1 = model->yf_Test.ptr< std::complex >(0); +// float f2 = (*f1).real(); +// float f3 = (*f1).imag(); + // train initial model train(input_rgb, input_gray, 1.0); } diff --git a/src/kcf.h b/src/kcf.h index 6ad5bc88..c6dee7c8 100644 --- a/src/kcf.h +++ b/src/kcf.h @@ -148,10 +148,10 @@ class KCF_Tracker // FORMER ATTRIBUTES CONVERTED TO cv::Mat // Something about not being able to tell which kind of cv::Mat (complex matrix does not equal 2 channels !) - cv::Mat yf_Test {(int) height, (int) width, CV_32FC1}; - cv::Mat model_alphaf_Test {(int) height, (int) width, CV_32FC1}; - cv::Mat model_alphaf_num_Test {(int) height, (int) width, CV_32FC1}; - cv::Mat model_alphaf_den_Test {(int) height, (int) width, CV_32FC1}; + cv::Mat yf_Test {(int) height, (int) width, CV_32FC2}; + cv::Mat model_alphaf_Test {(int) height, (int) width, CV_32FC2}; + cv::Mat model_alphaf_num_Test {(int) height, (int) width, CV_32FC2}; + cv::Mat model_alphaf_den_Test {(int) height, (int) width, CV_32FC2}; cv::Mat model_xf_Test {(int) height, (int) width, CV_32FC(n_feats)}; cv::Mat xf_Test {(int) height, (int) width, CV_32FC(n_feats)}; From 7d648aab841d9827a3d3cae8f9d6ea34e10bebef Mon Sep 17 00:00:00 2001 From: Your Name Date: Mon, 16 Dec 2019 18:36:46 +0100 Subject: [PATCH 012/121] =?UTF-8?q?Zm=C4=9Bna=20typu=20attribut=C5=AF=20pa?= =?UTF-8?q?tch=5Ffeats=20a=20temp=20ve=20t=C5=99=C3=ADd=C3=A1ch=20Model=20?= =?UTF-8?q?a=20ThreadCtx=20-=20zm=C4=9Bna=20z=20typu=20MatScaleFeats=20na?= =?UTF-8?q?=20cv::Mat=20-=20p=C5=99id=C3=A1no=20alternativn=C3=AD=20vol?= =?UTF-8?q?=C3=A1n=C3=AD=20na=20za=C4=8D=C3=A1tku=20funkce=20KCF=5FTracker?= =?UTF-8?q?::train=20-=20funkce=20plane()=20a=20scale()=20pat=C5=99=C3=ADc?= =?UTF-8?q?=C3=AD=20do=20MatScaleFeats=20byly=20p=C5=99eps=C3=A1ny=20do=20?= =?UTF-8?q?cvmat=5Ffunc.cpp?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- src/cvmat_func.cpp | 13 +++++++++++++ src/cvmat_func.h | 14 +++++++++++++- src/kcf.cpp | 7 +++++++ src/kcf.h | 2 ++ src/threadctx.hpp | 4 ++++ 5 files changed, 39 insertions(+), 1 deletion(-) diff --git a/src/cvmat_func.cpp b/src/cvmat_func.cpp index 8ed303e2..b7626079 100644 --- a/src/cvmat_func.cpp +++ b/src/cvmat_func.cpp @@ -13,4 +13,17 @@ float sqr_norm(cv::Mat &host) const } sum_sqr_norm = sum_sqr_norm / (float)(host.cols * host.rows); return sum_sqr_norm; +} + +cv::Mat plane(uint scale, uint feature, cv::Mat &host) { + assert(host.dims == 4); + assert(int(scale) < host.size[0]); + assert(int(feature) < host.size[1]); + return cv::Mat(host.size[2], host.size[3], host.type(), host.ptr(scale, feature)); +} + +cv::Mat scale(uint scale, cv::Mat &host) { + assert(host.dims == 4); + assert(int(scale) < host.size[0]); + return cv::Mat(3, std::vector({host.size[1], host.size[2], host.size[3]}).data(), host.type(), host.ptr(scale)); } \ No newline at end of file diff --git a/src/cvmat_func.h b/src/cvmat_func.h index 80ebaa5f..02d5310b 100644 --- a/src/cvmat_func.h +++ b/src/cvmat_func.h @@ -104,7 +104,19 @@ ComplexMat_ matn_mat1_operator(void (*op)(std::complex &c_lhs, const std::com ComplexMat_ matn_mat2_operator(void (*op)(std::complex &c_lhs, const std::complex &c_rhs), const ComplexMat_ &mat_rhs) const; ComplexMat_ mat_const_operator(const std::function &c_rhs)> &op) const; - + + +/* + * Function for getting cv::Mat header referencing height and width of the input matrix. + * Presumes input matrix of 4 dimensions with format: {scales, features, height, width} + **/ +cv::Mat plane(uint scale, uint feature, cv::Mat &host); + +/* + * Function for getting cv::Mat header referencing features, height and width of the input matrix. + * Presumes input matrix of 4 dimensions with format: {scales, features, height, width} + **/ +cv::Mat scale(uint scale, cv::Mat &host); #endif /* CVMAT_FUNC_H */ diff --git a/src/kcf.cpp b/src/kcf.cpp index 7ca361ed..3ad768fa 100644 --- a/src/kcf.cpp +++ b/src/kcf.cpp @@ -1,4 +1,5 @@ #include "kcf.h" +#include "cvmat_func.h" #include #include #include @@ -74,6 +75,12 @@ void KCF_Tracker::train(cv::Mat input_rgb, cv::Mat input_gray, double interp_fac get_features(input_rgb, input_gray, nullptr, p_current_center.x, p_current_center.y, p_windows_size.width, p_windows_size.height, p_current_scale, p_current_angle).copyTo(model->patch_feats.scale(0)); + + // REPLACEMENT + get_features(input_rgb, input_gray, nullptr, p_current_center.x, p_current_center.y, + p_windows_size.width, p_windows_size.height, + p_current_scale, p_current_angle).copyTo(scale(0, model->patch_feats_Test)); + DEBUG_PRINT(model->patch_feats); fft.forward_window(model->patch_feats, model->xf, model->temp); DEBUG_PRINTM(model->xf); diff --git a/src/kcf.h b/src/kcf.h index c6dee7c8..57951ecf 100644 --- a/src/kcf.h +++ b/src/kcf.h @@ -155,6 +155,8 @@ class KCF_Tracker cv::Mat model_xf_Test {(int) height, (int) width, CV_32FC(n_feats)}; cv::Mat xf_Test {(int) height, (int) width, CV_32FC(n_feats)}; + cv::Mat patch_feats_Test{ 4, std::vector({1, int(n_feats), feature_size.height, feature_size.width}).data(), CV_32F}; + cv::Mat temp_Test{ 4, std::vector({1, int(n_feats), feature_size.height, feature_size.width}).data(), CV_32F}; Model(cv::Size feature_size, uint _n_feats) diff --git a/src/threadctx.hpp b/src/threadctx.hpp index 0b237071..2a6c3f10 100644 --- a/src/threadctx.hpp +++ b/src/threadctx.hpp @@ -68,6 +68,10 @@ struct ThreadCtx { MatScaleFeats patch_feats{num_scales * num_angles, num_features, roi}; MatScaleFeats temp{num_scales * num_angles, num_features, roi}; + + // REPLACEMENT + cv::Mat patch_feats_Test{ 4, std::vector({ num_scales * num_angles, int(num_features), roi.height, roi.width}).data(), CV_32F}; + cv::Mat temp_Test{ 4, std::vector({ num_scales * num_angles, int(num_features), roi.height, roi.width}).data(), CV_32F}; KCF_Tracker::GaussianCorrelation gaussian_correlation{num_scales * num_angles, num_features, roi}; From 0ce85cd72aa1a4c1e668fce63b167874b9f964c3 Mon Sep 17 00:00:00 2001 From: Your Name Date: Mon, 16 Dec 2019 20:05:26 +0100 Subject: [PATCH 013/121] =?UTF-8?q?Drobn=C3=A9=20zm=C4=9Bny=20ve=20funkci?= =?UTF-8?q?=20forward=5Fwindow?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- src/cvmat_func.cpp | 35 ++++++---- src/cvmat_func.h | 163 +++++++++++++++++++-------------------------- src/fft_opencv.cpp | 17 +++++ src/fft_opencv.h | 3 +- src/kcf.cpp | 3 + src/threadctx.hpp | 4 +- 6 files changed, 114 insertions(+), 111 deletions(-) diff --git a/src/cvmat_func.cpp b/src/cvmat_func.cpp index b7626079..607865c4 100644 --- a/src/cvmat_func.cpp +++ b/src/cvmat_func.cpp @@ -1,19 +1,19 @@ - +#include "cvmat_func.h" #include -float sqr_norm(cv::Mat &host) const -{ - int n_channels_per_scale = host.channels(); - float sum_sqr_norm = 0; - for (int i = 0; i < n_channels_per_scale; ++i) { - for (auto lhs = p_data.hostMem() + i * host.rows * host.cols; - lhs != p_data.hostMem() + (i + 1) * host.rows * host.cols; ++lhs) - // consider using cv::norm() of type NORM_L2SQR for each channel - sum_sqr_norm += lhs->real() * lhs->real() + lhs->imag() * lhs->imag(); - } - sum_sqr_norm = sum_sqr_norm / (float)(host.cols * host.rows); - return sum_sqr_norm; -} +//float sqr_norm(cv::Mat &host) const +//{ +// int n_channels_per_scale = host.channels(); +// float sum_sqr_norm = 0; +// for (int i = 0; i < n_channels_per_scale; ++i) { +// for (auto lhs = p_data.hostMem() + i * host.rows * host.cols; +// lhs != p_data.hostMem() + (i + 1) * host.rows * host.cols; ++lhs) +// // consider using cv::norm() of type NORM_L2SQR for each channel +// sum_sqr_norm += lhs->real() * lhs->real() + lhs->imag() * lhs->imag(); +// } +// sum_sqr_norm = sum_sqr_norm / (float)(host.cols * host.rows); +// return sum_sqr_norm; +//} cv::Mat plane(uint scale, uint feature, cv::Mat &host) { assert(host.dims == 4); @@ -26,4 +26,11 @@ cv::Mat scale(uint scale, cv::Mat &host) { assert(host.dims == 4); assert(int(scale) < host.size[0]); return cv::Mat(3, std::vector({host.size[1], host.size[2], host.size[3]}).data(), host.type(), host.ptr(scale)); +} + +void set_channel(uint idx, cv::Mat &source, cv::Mat &target) +{ + assert(idx < target.channels()); + assert(source.channels() == 1); + cv::mixChannels( &source, 1, &target, 1, { 0,idx }, 1 ); } \ No newline at end of file diff --git a/src/cvmat_func.h b/src/cvmat_func.h index 02d5310b..5870073e 100644 --- a/src/cvmat_func.h +++ b/src/cvmat_func.h @@ -3,27 +3,6 @@ #define CVMAT_FUNC_H #include -#include -#include -#include "fhog.hpp" - -#ifdef CUFFT -#include "cuda_error_check.hpp" -#include -#endif - -#include "cnfeat.hpp" -#ifdef FFTW -#include "fft_fftw.h" -#define FFT Fftw -#elif defined(CUFFT) -#include "fft_cufft.h" -#define FFT cuFFT -#else -#include "fft_opencv.h" -#define FFT FftOpencv -#endif -#include "pragmas.h" //------ @@ -31,80 +10,71 @@ //size() and channel() already implemented in cv::Mat //------ -// READY FOR USE -// Used only in a single place at fft_opencv.cpp, target is ComplexMat (convert first) -// Probably easier to use this inline. -void set_channel(uint idx, const cv::Mat &mat, cv::Mat &host) -{ - assert(idx < host.channels()); - assert(idx < mat.channels()); - cv::mixChannels( &mat, 1, &host, 1, { idx,idx }, 1 ); -} - -// This computes a float value using elements in individual channels (seems unused) -float sqr_norm(cv::Mat &host) const; - -// This edits given Dynmem to contain computed float value in its [1] position (why?) -void sqr_norm(DynMem_ &result, cv::Mat &host) const; - -// Applies square operation to all elements in all channels -cv::Mat sqr_mag() const; - -// Applies "invert imaginary number" operation to all elements in all channels -cv::Mat conj() const; - -// DEFINE (=copy definition of) THIS BLOCK IN kcf.cpp -cv::Mat sum_over_channels(cv::Mat &host) const; - -//------ -// to_cv_mat() and channel_to_cv_mat() unnecesary, since the data is already cv::Mat format -//------ - -// DECIDE IF THIS IS ACTUALLY NEEDED WITH CURRENT cv::Mat FORMAT -// return a vector of 2 channels (real, imag) per one complex channel -std::vector to_cv_mat_vector() const -{ - std::vector result; - result.reserve(n_channels); - - for (uint i = 0; i < n_channels; ++i) - result.push_back(channel_to_cv_mat(i)); - - return result; -} - - -//------ -// get_p_data() unnecessary -// mul() and operator functions implemented in cv::Mat -//------ - -// READY FOR TESTING -// convert 2 channel mat (real, imag) to vector row-by-row -std::vector> convert(const cv::Mat &mat) -{ - std::vector> result; - result.reserve(mat.cols * mat.rows); - for (int y = 0; y < mat.rows; ++y) { - const float *row_ptr = mat.ptr(y); - for (int x = 0; x < 2 * mat.cols; x += 2) { - result.push_back(std::complex(row_ptr[x], row_ptr[x + 1])); - } - } - return result; -} - -// DEFINE (=copy definition of) THIS BLOCK IN kcf.cpp -// [ possibly completely replaced by cv::Mat.forEach() ] -ComplexMat_ mat_mat_operator(void (*op)(std::complex &c_lhs, const std::complex &c_rhs), - const ComplexMat_ &mat_rhs) const; -ComplexMat_ matn_mat1_operator(void (*op)(std::complex &c_lhs, const std::complex &c_rhs), - const ComplexMat_ &mat_rhs) const; -ComplexMat_ matn_mat2_operator(void (*op)(std::complex &c_lhs, const std::complex &c_rhs), - const ComplexMat_ &mat_rhs) const; -ComplexMat_ mat_const_operator(const std::function &c_rhs)> &op) const; - +//// This computes a float value using elements in individual channels (seems unused) +//float sqr_norm(cv::Mat &host) const; +// +//// This edits given Dynmem to contain computed float value in its [1] position (why?) +//void sqr_norm(DynMem_ &result, cv::Mat &host) const; +// +//// Applies square operation to all elements in all channels +//cv::Mat sqr_mag() const; +// +//// Applies "invert imaginary number" operation to all elements in all channels +//cv::Mat conj() const; +// +//// DEFINE (=copy definition of) THIS BLOCK IN kcf.cpp +//cv::Mat sum_over_channels(cv::Mat &host) const; +// +////------ +//// to_cv_mat() and channel_to_cv_mat() unnecesary, since the data is already cv::Mat format +////------ +// +// +//// DECIDE IF THIS IS ACTUALLY NEEDED WITH CURRENT cv::Mat FORMAT +//// return a vector of 2 channels (real, imag) per one complex channel +//std::vector to_cv_mat_vector() const +//{ +// std::vector result; +// result.reserve(n_channels); +// +// for (uint i = 0; i < n_channels; ++i) +// result.push_back(channel_to_cv_mat(i)); +// +// return result; +//} +// +// +////------ +//// get_p_data() unnecessary +//// mul() and operator functions implemented in cv::Mat +////------ +// +//// READY FOR TESTING +//// convert 2 channel mat (real, imag) to vector row-by-row +//std::vector> convert(const cv::Mat &mat) +//{ +// std::vector> result; +// result.reserve(mat.cols * mat.rows); +// for (int y = 0; y < mat.rows; ++y) { +// const float *row_ptr = mat.ptr(y); +// for (int x = 0; x < 2 * mat.cols; x += 2) { +// result.push_back(std::complex(row_ptr[x], row_ptr[x + 1])); +// } +// } +// return result; +//} +// +//// DEFINE (=copy definition of) THIS BLOCK IN kcf.cpp +//// [ possibly completely replaced by cv::Mat.forEach() ] +//ComplexMat_ mat_mat_operator(void (*op)(std::complex &c_lhs, const std::complex &c_rhs), +// const ComplexMat_ &mat_rhs) const; +//ComplexMat_ matn_mat1_operator(void (*op)(std::complex &c_lhs, const std::complex &c_rhs), +// const ComplexMat_ &mat_rhs) const; +//ComplexMat_ matn_mat2_operator(void (*op)(std::complex &c_lhs, const std::complex &c_rhs), +// const ComplexMat_ &mat_rhs) const; +//ComplexMat_ mat_const_operator(const std::function &c_rhs)> &op) const; +// /* * Function for getting cv::Mat header referencing height and width of the input matrix. @@ -118,6 +88,11 @@ cv::Mat plane(uint scale, uint feature, cv::Mat &host); **/ cv::Mat scale(uint scale, cv::Mat &host); +/* + * Sets the source as channel number idx of target matrix. + **/ +void set_channel(uint idx, cv::Mat &source, cv::Mat &target); + #endif /* CVMAT_FUNC_H */ diff --git a/src/fft_opencv.cpp b/src/fft_opencv.cpp index 95c051c1..3e4f3a41 100644 --- a/src/fft_opencv.cpp +++ b/src/fft_opencv.cpp @@ -1,4 +1,5 @@ #include "fft_opencv.h" +#include "cvmat_func.h" void FftOpencv::init(unsigned width, unsigned height, unsigned num_of_feats, unsigned num_of_scales) { @@ -20,6 +21,7 @@ void FftOpencv::forward(const MatScales &real_input, ComplexMat &complex_result) complex_result = ComplexMat(tmp); } +// REPLACEMENT void FftOpencv::forward(const cv::Mat &real_input, cv::Mat &complex_result) { // Fft::forward(real_input, complex_result); @@ -41,6 +43,21 @@ void FftOpencv::forward_window(MatScaleFeats &feat, ComplexMat &complex_result, } } +// REPLACEMENT +void FftOpencv::forward_window(cv::Mat &feat, cv::Mat &complex_result, cv::Mat &temp) +{ + //Fft::forward_window(feat, complex_result, temp); +(void) temp; + for (uint i = 0; i < uint(feat.size[0]); ++i) { + for (uint j = 0; j < uint(feat.size[1]); ++j) { + cv::Mat complex_res; + cv::Mat channel = plane(i, j, feat); + cv::dft(channel.mul(m_window), complex_res, cv::DFT_COMPLEX_OUTPUT); + set_channel(int(j), complex_res, complex_result); + } + } +} + void FftOpencv::inverse(ComplexMat & complex_input, MatScales & real_result) { Fft::inverse(complex_input, real_result); diff --git a/src/fft_opencv.h b/src/fft_opencv.h index 804bd5db..559c16f9 100644 --- a/src/fft_opencv.h +++ b/src/fft_opencv.h @@ -10,11 +10,12 @@ class FftOpencv : public Fft void init(unsigned width, unsigned height, unsigned num_of_feats, unsigned num_of_scales); void set_window(const MatDynMem &window); void forward(const MatScales &real_input, ComplexMat &complex_result); + void forward_window(MatScaleFeats &patch_feats_in, ComplexMat &complex_result, MatScaleFeats &tmp); //REPLACEMENT void forward(const cv::Mat &real_input, cv::Mat &complex_result); + void forward_window(cv::Mat &feat, cv::Mat &complex_result, cv::Mat &temp); - void forward_window(MatScaleFeats &patch_feats_in, ComplexMat &complex_result, MatScaleFeats &tmp); void inverse(ComplexMat &complex_input, MatScales &real_result); ~FftOpencv(); private: diff --git a/src/kcf.cpp b/src/kcf.cpp index 3ad768fa..ff434d9d 100644 --- a/src/kcf.cpp +++ b/src/kcf.cpp @@ -82,8 +82,11 @@ void KCF_Tracker::train(cv::Mat input_rgb, cv::Mat input_gray, double interp_fac p_current_scale, p_current_angle).copyTo(scale(0, model->patch_feats_Test)); DEBUG_PRINT(model->patch_feats); + DEBUG_PRINT(model->patch_feats_Test); fft.forward_window(model->patch_feats, model->xf, model->temp); + fft.forward_window(model->patch_feats_Test, model->xf_Test, model->temp_Test); DEBUG_PRINTM(model->xf); + DEBUG_PRINTM(model->xf_Test); model->model_xf = model->model_xf * (1. - interp_factor) + model->xf * interp_factor; DEBUG_PRINTM(model->model_xf); diff --git a/src/threadctx.hpp b/src/threadctx.hpp index 2a6c3f10..333a3248 100644 --- a/src/threadctx.hpp +++ b/src/threadctx.hpp @@ -70,8 +70,8 @@ struct ThreadCtx { MatScaleFeats temp{num_scales * num_angles, num_features, roi}; // REPLACEMENT - cv::Mat patch_feats_Test{ 4, std::vector({ num_scales * num_angles, int(num_features), roi.height, roi.width}).data(), CV_32F}; - cv::Mat temp_Test{ 4, std::vector({ num_scales * num_angles, int(num_features), roi.height, roi.width}).data(), CV_32F}; + cv::Mat patch_feats_Test{ 4, std::vector({ int(num_scales * num_angles), int(num_features), roi.height, roi.width}).data(), CV_32F}; + cv::Mat temp_Test{ 4, std::vector({ int(num_scales * num_angles), int(num_features), roi.height, roi.width}).data(), CV_32F}; KCF_Tracker::GaussianCorrelation gaussian_correlation{num_scales * num_angles, num_features, roi}; From 71b7a1c122353214f00cbc1bb2a72fa56df1e1d5 Mon Sep 17 00:00:00 2001 From: Your Name Date: Sun, 22 Dec 2019 18:53:22 +0100 Subject: [PATCH 014/121] =?UTF-8?q?Opravena=20drobn=C3=A1=20chyba=20ve=20v?= =?UTF-8?q?=C3=BDpisu=20debug.=20-=20pro=20v=C3=BDpis=20cv::Mat=20je=20te?= =?UTF-8?q?=C4=8F=20zohledn=C4=9Bna=20p=C5=99=C3=ADtomnost=20v=C3=A1ce=20k?= =?UTF-8?q?an=C3=A1l=C5=AF,=20p=C5=99i=20volb=C4=9B=20po=C4=8Dtu=20vypsan?= =?UTF-8?q?=C3=BDch=20element=C5=AF?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- src/debug.cpp | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/debug.cpp b/src/debug.cpp index 4f21a39d..99e04694 100644 --- a/src/debug.cpp +++ b/src/debug.cpp @@ -8,7 +8,7 @@ std::ostream &operator<<(std::ostream &os, const DbgTracer::Printer &p) os << p.obj.size << " " << p.obj.channels() << "ch ";// << static_cast(p.obj.data); os << " = [ "; const size_t num = 10; //p.obj.total(); - for (size_t i = 0; i < std::min(num, p.obj.total()); ++i) + for (size_t i = 0; i < std::min(num, p.obj.total() * p.obj.channels()); ++i) os << p.obj.ptr()[i] << ", "; os << (num < p.obj.total() ? "... ]" : "]"); return os; From d0112f639c4731b206851fcca2f4c1ccacd6fabd Mon Sep 17 00:00:00 2001 From: Your Name Date: Sun, 22 Dec 2019 19:17:41 +0100 Subject: [PATCH 015/121] =?UTF-8?q?Opravena=20drobn=C3=A1=20chyba=20ve=20v?= =?UTF-8?q?=C3=BDpisu=20debug.=20-=20pro=20v=C3=BDpis=20cv::Mat=20je=20te?= =?UTF-8?q?=C4=8F=20zohledn=C4=9Bna=20p=C5=99=C3=ADtomnost=20v=C3=A1ce=20k?= =?UTF-8?q?an=C3=A1l=C5=AF,=20p=C5=99i=20volb=C4=9B=20po=C4=8Dtu=20vypsan?= =?UTF-8?q?=C3=BDch=20element=C5=AF?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- src/debug.cpp | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/debug.cpp b/src/debug.cpp index 99e04694..808bd83f 100644 --- a/src/debug.cpp +++ b/src/debug.cpp @@ -10,7 +10,7 @@ std::ostream &operator<<(std::ostream &os, const DbgTracer::Printer &p) const size_t num = 10; //p.obj.total(); for (size_t i = 0; i < std::min(num, p.obj.total() * p.obj.channels()); ++i) os << p.obj.ptr()[i] << ", "; - os << (num < p.obj.total() ? "... ]" : "]"); + os << (num < (p.obj.total() * p.obj.channels()) ? "... ]" : "]"); return os; } From e68a1ba68787363fb631246712c80342e5667168 Mon Sep 17 00:00:00 2001 From: Your Name Date: Sun, 22 Dec 2019 19:45:22 +0100 Subject: [PATCH 016/121] =?UTF-8?q?Zm=C4=9Bna=20soubor=C5=AF=20cvmat=5Ffun?= =?UTF-8?q?c.h=20-=20p=C5=99ejmenov=C3=A1no=20na=20matutil.h=20-=20nepou?= =?UTF-8?q?=C5=BE=C3=ADvan=C3=A9=20funkce=20zakomentov=C3=A1ny=20-=20funkc?= =?UTF-8?q?e=20p=C5=99esunuty=20do=20hlavi=C4=8Dky=20ve=20form=C4=9B=20sta?= =?UTF-8?q?tick=C3=BDch=20funkc=C3=AD=20t=C5=99=C3=ADdy=20MatUtil=20(defin?= =?UTF-8?q?ice=20v=20souboru=20.cpp=20nejsou=20viditeln=C3=A9=20kompil?= =?UTF-8?q?=C3=A1torem=20=3F)?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- src/matutil.cpp | 32 ++++++++++++ src/matutil.h | 127 ++++++++++++++++++++++++++++++++++++++++++++++++ 2 files changed, 159 insertions(+) create mode 100644 src/matutil.cpp create mode 100644 src/matutil.h diff --git a/src/matutil.cpp b/src/matutil.cpp new file mode 100644 index 00000000..679c4bc9 --- /dev/null +++ b/src/matutil.cpp @@ -0,0 +1,32 @@ +//#include "matutil.h" +//#include +//#include +// +//cv::Mat MatUtil::plane(uint scale, uint feature, cv::Mat &host) { +// assert(host.dims == 4); +// assert(int(scale) < host.size[0]); +// assert(int(feature) < host.size[1]); +// return cv::Mat(host.size[2], host.size[3], host.type(), host.ptr(scale, feature)); +//} +// +///* +// * Function for getting cv::Mat header referencing features, height and width of the input matrix. +// * Presumes input matrix of 4 dimensions with format: {scales, features, height, width} +// **/ +//cv::Mat MatUtil::scale(uint scale, cv::Mat &host) { +// assert(host.dims == 4); +// assert(int(scale) < host.size[0]); +// return cv::Mat(3, std::vector({host.size[1], host.size[2], host.size[3]}).data(), host.type(), host.ptr(scale)); +//} +// +// +///* +// * Sets the source as channel number idx of target matrix. +// **/ +//void MatUtil::set_channel(int idx, cv::Mat &source, cv::Mat &target) +//{ +// assert(idx < target.channels()); +// assert(source.channels() == 1); +// int from_to[] = { 0,idx }; +// cv::mixChannels( &source, 1, &target, 1, from_to, 1 ); +//} \ No newline at end of file diff --git a/src/matutil.h b/src/matutil.h new file mode 100644 index 00000000..6d6c5605 --- /dev/null +++ b/src/matutil.h @@ -0,0 +1,127 @@ + +#ifndef MAT_UTIL_H +#define MAT_UTIL_H + +#include +#include + + + +//------ +//same_size() only used in complexmat.cu , ignored +//size() and channel() already implemented in cv::Mat +//------ + + +//// This computes a float value using elements in individual channels (seems unused) +//float sqr_norm(cv::Mat &host) const; +// +//// This edits given Dynmem to contain computed float value in its [1] position (why?) +//void sqr_norm(DynMem_ &result, cv::Mat &host) const; +// +//// Applies square operation to all elements in all channels +//cv::Mat sqr_mag() const; +// +//// Applies "invert imaginary number" operation to all elements in all channels +//cv::Mat conj() const; +// +//// DEFINE (=copy definition of) THIS BLOCK IN kcf.cpp +//cv::Mat sum_over_channels(cv::Mat &host) const; +// +////------ +//// to_cv_mat() and channel_to_cv_mat() unnecesary, since the data is already cv::Mat format +////------ +// +// +//// DECIDE IF THIS IS ACTUALLY NEEDED WITH CURRENT cv::Mat FORMAT +//// return a vector of 2 channels (real, imag) per one complex channel +//std::vector to_cv_mat_vector() const +//{ +// std::vector result; +// result.reserve(n_channels); +// +// for (uint i = 0; i < n_channels; ++i) +// result.push_back(channel_to_cv_mat(i)); +// +// return result; +//} +// +// +////------ +//// get_p_data() unnecessary +//// mul() and operator functions implemented in cv::Mat +////------ +// +//// READY FOR TESTING +//// convert 2 channel mat (real, imag) to vector row-by-row +//std::vector> convert(const cv::Mat &mat) +//{ +// std::vector> result; +// result.reserve(mat.cols * mat.rows); +// for (int y = 0; y < mat.rows; ++y) { +// const float *row_ptr = mat.ptr(y); +// for (int x = 0; x < 2 * mat.cols; x += 2) { +// result.push_back(std::complex(row_ptr[x], row_ptr[x + 1])); +// } +// } +// return result; +//} +// +//// DEFINE (=copy definition of) THIS BLOCK IN kcf.cpp +//// [ possibly completely replaced by cv::Mat.forEach() ] +//ComplexMat_ mat_mat_operator(void (*op)(std::complex &c_lhs, const std::complex &c_rhs), +// const ComplexMat_ &mat_rhs) const; +//ComplexMat_ matn_mat1_operator(void (*op)(std::complex &c_lhs, const std::complex &c_rhs), +// const ComplexMat_ &mat_rhs) const; +//ComplexMat_ matn_mat2_operator(void (*op)(std::complex &c_lhs, const std::complex &c_rhs), +// const ComplexMat_ &mat_rhs) const; +//ComplexMat_ mat_const_operator(const std::function &c_rhs)> &op) const; +// + +class MatUtil{ +public: +/* + * Function for getting cv::Mat header referencing height and width of the input matrix. + * Presumes input matrix of 4 dimensions with format: {scales, features, height, width} + **/ +static cv::Mat plane(uint scale, uint feature, cv::Mat &host) { + assert(host.dims == 4); + assert(int(scale) < host.size[0]); + assert(int(feature) < host.size[1]); + return cv::Mat(host.size[2], host.size[3], host.type(), host.ptr(scale, feature)); +} + +/* + * Function for getting cv::Mat header referencing features, height and width of the input matrix. + * Presumes input matrix of 4 dimensions with format: {scales, features, height, width} + **/ +static cv::Mat scale(uint scale, cv::Mat &host) { + assert(host.dims == 4); + assert(int(scale) < host.size[0]); + return cv::Mat(3, std::vector({host.size[1], host.size[2], host.size[3]}).data(), host.type(), host.ptr(scale)); +} + + +/* + * Sets the source as channel number idx of target matrix. + **/ +static void set_channel(int idxFrom, int idxTo, cv::Mat &source, cv::Mat &target) +{ +// assert(idx < n_channels); +// for (uint i = 0; i < rows; ++i) { +// const std::complex *row = source.ptr< std::complex >(i); +// for (uint j = 0; j < cols; ++j) +// p_data.hostMem()[idx * rows * cols + i * cols + j] = row[j]; +// } + + + assert(idxTo < target.channels()); + assert(idxFrom < source.channels()); + int from_to[] = { idxFrom,idxTo }; + cv::mixChannels( &source, 1, &target, 1, from_to, 1 ); +} + +}; + +#endif /* MAT_UTIL_H */ + From 7515378eb09a619364e2f662b833e19d595785af Mon Sep 17 00:00:00 2001 From: oraveja1 <57142143+oraveja1@users.noreply.github.com> Date: Sun, 22 Dec 2019 19:47:07 +0100 Subject: [PATCH 017/121] Delete cvmat_func.h replaced by matutil.h --- src/cvmat_func.h | 98 ------------------------------------------------ 1 file changed, 98 deletions(-) delete mode 100644 src/cvmat_func.h diff --git a/src/cvmat_func.h b/src/cvmat_func.h deleted file mode 100644 index 5870073e..00000000 --- a/src/cvmat_func.h +++ /dev/null @@ -1,98 +0,0 @@ - -#ifndef CVMAT_FUNC_H -#define CVMAT_FUNC_H - -#include - - -//------ -//same_size() only used in complexmat.cu , ignored -//size() and channel() already implemented in cv::Mat -//------ - - -//// This computes a float value using elements in individual channels (seems unused) -//float sqr_norm(cv::Mat &host) const; -// -//// This edits given Dynmem to contain computed float value in its [1] position (why?) -//void sqr_norm(DynMem_ &result, cv::Mat &host) const; -// -//// Applies square operation to all elements in all channels -//cv::Mat sqr_mag() const; -// -//// Applies "invert imaginary number" operation to all elements in all channels -//cv::Mat conj() const; -// -//// DEFINE (=copy definition of) THIS BLOCK IN kcf.cpp -//cv::Mat sum_over_channels(cv::Mat &host) const; -// -////------ -//// to_cv_mat() and channel_to_cv_mat() unnecesary, since the data is already cv::Mat format -////------ -// -// -//// DECIDE IF THIS IS ACTUALLY NEEDED WITH CURRENT cv::Mat FORMAT -//// return a vector of 2 channels (real, imag) per one complex channel -//std::vector to_cv_mat_vector() const -//{ -// std::vector result; -// result.reserve(n_channels); -// -// for (uint i = 0; i < n_channels; ++i) -// result.push_back(channel_to_cv_mat(i)); -// -// return result; -//} -// -// -////------ -//// get_p_data() unnecessary -//// mul() and operator functions implemented in cv::Mat -////------ -// -//// READY FOR TESTING -//// convert 2 channel mat (real, imag) to vector row-by-row -//std::vector> convert(const cv::Mat &mat) -//{ -// std::vector> result; -// result.reserve(mat.cols * mat.rows); -// for (int y = 0; y < mat.rows; ++y) { -// const float *row_ptr = mat.ptr(y); -// for (int x = 0; x < 2 * mat.cols; x += 2) { -// result.push_back(std::complex(row_ptr[x], row_ptr[x + 1])); -// } -// } -// return result; -//} -// -//// DEFINE (=copy definition of) THIS BLOCK IN kcf.cpp -//// [ possibly completely replaced by cv::Mat.forEach() ] -//ComplexMat_ mat_mat_operator(void (*op)(std::complex &c_lhs, const std::complex &c_rhs), -// const ComplexMat_ &mat_rhs) const; -//ComplexMat_ matn_mat1_operator(void (*op)(std::complex &c_lhs, const std::complex &c_rhs), -// const ComplexMat_ &mat_rhs) const; -//ComplexMat_ matn_mat2_operator(void (*op)(std::complex &c_lhs, const std::complex &c_rhs), -// const ComplexMat_ &mat_rhs) const; -//ComplexMat_ mat_const_operator(const std::function &c_rhs)> &op) const; -// - -/* - * Function for getting cv::Mat header referencing height and width of the input matrix. - * Presumes input matrix of 4 dimensions with format: {scales, features, height, width} - **/ -cv::Mat plane(uint scale, uint feature, cv::Mat &host); - -/* - * Function for getting cv::Mat header referencing features, height and width of the input matrix. - * Presumes input matrix of 4 dimensions with format: {scales, features, height, width} - **/ -cv::Mat scale(uint scale, cv::Mat &host); - -/* - * Sets the source as channel number idx of target matrix. - **/ -void set_channel(uint idx, cv::Mat &source, cv::Mat &target); - - -#endif /* CVMAT_FUNC_H */ - From e73339db362639b7d90bf27d9b43036bdb1ff10a Mon Sep 17 00:00:00 2001 From: oraveja1 <57142143+oraveja1@users.noreply.github.com> Date: Sun, 22 Dec 2019 19:47:28 +0100 Subject: [PATCH 018/121] Delete cvmat_func.cpp replaced by matutil.cpp --- src/cvmat_func.cpp | 36 ------------------------------------ 1 file changed, 36 deletions(-) delete mode 100644 src/cvmat_func.cpp diff --git a/src/cvmat_func.cpp b/src/cvmat_func.cpp deleted file mode 100644 index 607865c4..00000000 --- a/src/cvmat_func.cpp +++ /dev/null @@ -1,36 +0,0 @@ -#include "cvmat_func.h" -#include - -//float sqr_norm(cv::Mat &host) const -//{ -// int n_channels_per_scale = host.channels(); -// float sum_sqr_norm = 0; -// for (int i = 0; i < n_channels_per_scale; ++i) { -// for (auto lhs = p_data.hostMem() + i * host.rows * host.cols; -// lhs != p_data.hostMem() + (i + 1) * host.rows * host.cols; ++lhs) -// // consider using cv::norm() of type NORM_L2SQR for each channel -// sum_sqr_norm += lhs->real() * lhs->real() + lhs->imag() * lhs->imag(); -// } -// sum_sqr_norm = sum_sqr_norm / (float)(host.cols * host.rows); -// return sum_sqr_norm; -//} - -cv::Mat plane(uint scale, uint feature, cv::Mat &host) { - assert(host.dims == 4); - assert(int(scale) < host.size[0]); - assert(int(feature) < host.size[1]); - return cv::Mat(host.size[2], host.size[3], host.type(), host.ptr(scale, feature)); -} - -cv::Mat scale(uint scale, cv::Mat &host) { - assert(host.dims == 4); - assert(int(scale) < host.size[0]); - return cv::Mat(3, std::vector({host.size[1], host.size[2], host.size[3]}).data(), host.type(), host.ptr(scale)); -} - -void set_channel(uint idx, cv::Mat &source, cv::Mat &target) -{ - assert(idx < target.channels()); - assert(source.channels() == 1); - cv::mixChannels( &source, 1, &target, 1, { 0,idx }, 1 ); -} \ No newline at end of file From 82de1e462dff15ad165f2a9696f4a795a8c3be15 Mon Sep 17 00:00:00 2001 From: Your Name Date: Sun, 22 Dec 2019 22:03:45 +0100 Subject: [PATCH 019/121] =?UTF-8?q?N=C3=A1hradn=C3=AD=20implementace=20pro?= =?UTF-8?q?=20ComplexMat=20ve=20funkci=20KCF=5FTracker::train.=20-=20v?= =?UTF-8?q?=C5=A1echny=20kroky=20do=20zavol=C3=A1n=C3=AD=20fft.forward=5Fw?= =?UTF-8?q?indow()=20maj=C3=AD=20p=C5=99idanou=20alternativu,=20kter=C3=A1?= =?UTF-8?q?=20zapisuje=20do=20nahrazuj=C3=ADc=C3=AD=20prom=C4=9Bnn=C3=A9?= =?UTF-8?q?=20cv::Mat=20v=20Modelu=20-=20fft.forward=5Fwindow()=20p=C5=99e?= =?UTF-8?q?db=C4=9B=C5=BEn=C4=9B=20reprezentuje=20re=C3=A1lnou=20a=20imag.?= =?UTF-8?q?=20slo=C5=BEku=20dv=C4=9Bma=20soused=C3=ADc=C3=ADmi=20kan=C3=A1?= =?UTF-8?q?ly=20-=20MatUtil::set=5Fchannel()=20pozm=C4=9Bn=C4=9Bna=20pro?= =?UTF-8?q?=20pr=C3=A1ci=20s=20form=C3=A1tem=20cv::Mat.=20-=20v=C5=A1echny?= =?UTF-8?q?=20zm=C4=9Bn=C4=9Bn=C3=A9=20kroky=20otestov=C3=A1ny?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit Pozn.: Formát cv::Mat = Každý pixel je souvislý blok hodnot kanálů ve vnitřním poli. (délka bloku = počet kanálů) Formát ComplexMat = Každý kanál je souvislý blok hodnot pixelů ve vnitřním poli. (délka bloku = plocha obrázku) --- src/fft_opencv.cpp | 12 ++++++++---- src/kcf.cpp | 17 +++++++++++++++-- src/kcf.h | 4 ++-- src/matutil.h | 15 +++++---------- 4 files changed, 30 insertions(+), 18 deletions(-) diff --git a/src/fft_opencv.cpp b/src/fft_opencv.cpp index 3e4f3a41..cc2603fb 100644 --- a/src/fft_opencv.cpp +++ b/src/fft_opencv.cpp @@ -1,5 +1,6 @@ #include "fft_opencv.h" -#include "cvmat_func.h" +#include "matutil.h" +#include "debug.h" void FftOpencv::init(unsigned width, unsigned height, unsigned num_of_feats, unsigned num_of_scales) { @@ -44,16 +45,19 @@ void FftOpencv::forward_window(MatScaleFeats &feat, ComplexMat &complex_result, } // REPLACEMENT +// Real and imag parts of complex elements from previous format are represented by 2 neighbouring channels. void FftOpencv::forward_window(cv::Mat &feat, cv::Mat &complex_result, cv::Mat &temp) { //Fft::forward_window(feat, complex_result, temp); -(void) temp; + (void) temp; for (uint i = 0; i < uint(feat.size[0]); ++i) { for (uint j = 0; j < uint(feat.size[1]); ++j) { cv::Mat complex_res; - cv::Mat channel = plane(i, j, feat); + cv::Mat channel = MatUtil::plane(i, j, feat); cv::dft(channel.mul(m_window), complex_res, cv::DFT_COMPLEX_OUTPUT); - set_channel(int(j), complex_res, complex_result); + + MatUtil::set_channel(int(0), int(2*j), complex_res, complex_result); + MatUtil::set_channel(int(1), int(2*j+1), complex_res, complex_result); } } } diff --git a/src/kcf.cpp b/src/kcf.cpp index ff434d9d..1f5db000 100644 --- a/src/kcf.cpp +++ b/src/kcf.cpp @@ -1,5 +1,6 @@ #include "kcf.h" -#include "cvmat_func.h" +#include "matutil.h" +#include #include #include #include @@ -79,7 +80,7 @@ void KCF_Tracker::train(cv::Mat input_rgb, cv::Mat input_gray, double interp_fac // REPLACEMENT get_features(input_rgb, input_gray, nullptr, p_current_center.x, p_current_center.y, p_windows_size.width, p_windows_size.height, - p_current_scale, p_current_angle).copyTo(scale(0, model->patch_feats_Test)); + p_current_scale, p_current_angle).copyTo(MatUtil::scale(0, model->patch_feats_Test)); DEBUG_PRINT(model->patch_feats); DEBUG_PRINT(model->patch_feats_Test); @@ -122,6 +123,18 @@ void KCF_Tracker::init(cv::Mat &img, const cv::Rect &bbox, int fit_size_x, int f __dbgTracer.debug = m_debug; TRACE(""); +// cv::Mat test = cv::Mat(3,2,CV_32FC3,float(4)); +// cv::Mat test2 = cv::Mat(3,2,CV_32F,float(6)); +// int from_to[] = { 0,2 }; +// cv::mixChannels(&test2,1,&test,1,from_to,1); +// +// float val1 = test.ptr(1)[0]; +// test.ptr(1)[0] = float(5); +// DEBUG_PRINTM(test); +// DEBUG_PRINTM(val1); +// +// return; +// // check boundary, enforce min size double x1 = bbox.x, x2 = bbox.x + bbox.width, y1 = bbox.y, y2 = bbox.y + bbox.height; if (x1 < 0) x1 = 0.; diff --git a/src/kcf.h b/src/kcf.h index 57951ecf..83742ff0 100644 --- a/src/kcf.h +++ b/src/kcf.h @@ -152,8 +152,8 @@ class KCF_Tracker cv::Mat model_alphaf_Test {(int) height, (int) width, CV_32FC2}; cv::Mat model_alphaf_num_Test {(int) height, (int) width, CV_32FC2}; cv::Mat model_alphaf_den_Test {(int) height, (int) width, CV_32FC2}; - cv::Mat model_xf_Test {(int) height, (int) width, CV_32FC(n_feats)}; - cv::Mat xf_Test {(int) height, (int) width, CV_32FC(n_feats)}; + cv::Mat model_xf_Test {(int) height, (int) width, CV_32FC(n_feats*2)}; + cv::Mat xf_Test {(int) height, (int) width, CV_32FC(n_feats*2)}; cv::Mat patch_feats_Test{ 4, std::vector({1, int(n_feats), feature_size.height, feature_size.width}).data(), CV_32F}; cv::Mat temp_Test{ 4, std::vector({1, int(n_feats), feature_size.height, feature_size.width}).data(), CV_32F}; diff --git a/src/matutil.h b/src/matutil.h index 6d6c5605..21e7ddb2 100644 --- a/src/matutil.h +++ b/src/matutil.h @@ -103,18 +103,13 @@ static cv::Mat scale(uint scale, cv::Mat &host) { /* - * Sets the source as channel number idx of target matrix. - **/ + * Sets channel number idxFrom of the source as channel number idxTo of target matrix. + * Uses native format of cv::Mat to store channels, meaning all channel values of each pixel + * are next to each other in the internal array (1 pixel = continuous block). + * Previous format saved all pixel values of each channel next to each other. +**/ static void set_channel(int idxFrom, int idxTo, cv::Mat &source, cv::Mat &target) { -// assert(idx < n_channels); -// for (uint i = 0; i < rows; ++i) { -// const std::complex *row = source.ptr< std::complex >(i); -// for (uint j = 0; j < cols; ++j) -// p_data.hostMem()[idx * rows * cols + i * cols + j] = row[j]; -// } - - assert(idxTo < target.channels()); assert(idxFrom < source.channels()); int from_to[] = { idxFrom,idxTo }; From 00bf57486c3ab80dc7c77b3068026b373323ebef Mon Sep 17 00:00:00 2001 From: Your Name Date: Sun, 22 Dec 2019 22:26:22 +0100 Subject: [PATCH 020/121] =?UTF-8?q?P=C5=99id=C3=A1n=20init=20prom=C4=9Bnn?= =?UTF-8?q?=C3=A9=20Model::model=5Fxf=5FTest=20ve=20funkci=20KCF=5FTracker?= =?UTF-8?q?::train=20-=20v=20podstat=C4=9B=20jen=20kopie=20Model::xf,=20ne?= =?UTF-8?q?jsp=C3=AD=C5=A1=20to=20bude=20jin=C3=A9=20pro=20dal=C5=A1=C3=AD?= =?UTF-8?q?=20vol=C3=A1n=C3=AD=20funkce=20train()=20s=20jin=C3=BDm=20param?= =?UTF-8?q?etrem?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- src/kcf.cpp | 4 +++- 1 file changed, 3 insertions(+), 1 deletion(-) diff --git a/src/kcf.cpp b/src/kcf.cpp index 1f5db000..8ce3ee5e 100644 --- a/src/kcf.cpp +++ b/src/kcf.cpp @@ -89,8 +89,10 @@ void KCF_Tracker::train(cv::Mat input_rgb, cv::Mat input_gray, double interp_fac DEBUG_PRINTM(model->xf); DEBUG_PRINTM(model->xf_Test); model->model_xf = model->model_xf * (1. - interp_factor) + model->xf * interp_factor; + model->model_xf_Test = model->model_xf_Test * (1. - interp_factor) + model->xf_Test * interp_factor; DEBUG_PRINTM(model->model_xf); - + DEBUG_PRINTM(model->model_xf_Test); + if (m_use_linearkernel) { ComplexMat xfconj = model->xf.conj(); model->model_alphaf_num = xfconj.mul(model->yf); From b04208da28e1a839daa5e72c8cdc855cfb4eca64 Mon Sep 17 00:00:00 2001 From: Your Name Date: Mon, 23 Dec 2019 20:36:52 +0100 Subject: [PATCH 021/121] =?UTF-8?q?P=C5=99id=C3=A1na=20funkce=20MatUtil::c?= =?UTF-8?q?onj()=20pro=20aplikaci=20na=20cv::Mat=20-=20funkce=20pou=C5=BEi?= =?UTF-8?q?ta=20v=20KCF=5FTracker::train()?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- src/kcf.cpp | 54 ++++++++++++++++++++++++++++++++++++++++++++------- src/matutil.h | 20 +++++++++++++++++++ 2 files changed, 67 insertions(+), 7 deletions(-) diff --git a/src/kcf.cpp b/src/kcf.cpp index 8ce3ee5e..67e43a4c 100644 --- a/src/kcf.cpp +++ b/src/kcf.cpp @@ -1,5 +1,6 @@ #include "kcf.h" #include "matutil.h" +#include "debug.h" #include #include #include @@ -97,6 +98,9 @@ void KCF_Tracker::train(cv::Mat input_rgb, cv::Mat input_gray, double interp_fac ComplexMat xfconj = model->xf.conj(); model->model_alphaf_num = xfconj.mul(model->yf); model->model_alphaf_den = (model->xf * xfconj); + + cv::Mat xfconj_Test = MatUtil::conj(model->xf_Test); + model->model_alphaf_num_Test = xfconj_Test.mul(model->yf); } else { // Kernel Ridge Regression, calculate alphas (in Fourier domain) cv::Size sz(Fft::freq_size(feature_size)); @@ -105,6 +109,11 @@ void KCF_Tracker::train(cv::Mat input_rgb, cv::Mat input_gray, double interp_fac DEBUG_PRINTM(kf); model->model_alphaf_num = model->yf * kf; model->model_alphaf_den = kf * (kf + p_lambda); + + +// cv::Mat kf_Test = cv::Mat(sz.height, sz.width, CV_32F); +// (*gaussian_correlation)(kf_Test, model->model_xf_Test, model->model_xf_Test, p_kernel_sigma, true, *this); +// DEBUG_PRINTM(kf_Test); } model->model_alphaf = model->model_alphaf_num / model->model_alphaf_den; DEBUG_PRINTM(model->model_alphaf); @@ -125,15 +134,46 @@ void KCF_Tracker::init(cv::Mat &img, const cv::Rect &bbox, int fit_size_x, int f __dbgTracer.debug = m_debug; TRACE(""); -// cv::Mat test = cv::Mat(3,2,CV_32FC3,float(4)); -// cv::Mat test2 = cv::Mat(3,2,CV_32F,float(6)); -// int from_to[] = { 0,2 }; -// cv::mixChannels(&test2,1,&test,1,from_to,1); +// cv::Mat test = cv::Mat(2,2,CV_32FC4,float(0)); +//// cv::Mat test2 = cv::Mat(3,2,CV_32F,float(6)); +//// int from_to[] = { 0,3 }; +//// cv::mixChannels(&test2,1,&test,1,from_to,1); +// +//// cv::Mat_> testComplex = cv::Mat_>(test2); +// +// test.ptr(0)[0] = float(1); +// test.ptr(0)[1] = float(2); +// test.ptr(0)[2] = float(3); +// test.ptr(0)[3] = float(4); +// test.ptr(0)[4] = float(5); +// test.ptr(0)[5] = float(6); +// test.ptr(0)[6] = float(7); +// test.ptr(0)[7] = float(8); +// test.ptr(1)[0] = float(9); +// test.ptr(1)[1] = float(10); +// test.ptr(1)[2] = float(11); +// test.ptr(1)[3] = float(12); +// test.ptr(1)[4] = float(13); +// test.ptr(1)[5] = float(14); +// test.ptr(1)[6] = float(15); +// test.ptr(1)[7] = float(16); +// +// +// assert(test.channels() % 2 == 0); +// for (uint i = 0; i < test.rows; ++i) { +// for (uint j = 0; j < test.cols; ++j){ +// for (uint k = 0; k < test.channels() / 2 ; ++k){ +// std::complex cpxVal = test.ptr>(i)[(test.channels() / 2)*j + k]; +// cpxVal.imag(- cpxVal.imag()); +// test.ptr>(i)[(test.channels() / 2)*j + k] = cpxVal; +// DEBUG_PRINTM(cpxVal); +// } +// } +// } +// // -// float val1 = test.ptr(1)[0]; -// test.ptr(1)[0] = float(5); // DEBUG_PRINTM(test); -// DEBUG_PRINTM(val1); +// // // return; // diff --git a/src/matutil.h b/src/matutil.h index 21e7ddb2..cdabfcb2 100644 --- a/src/matutil.h +++ b/src/matutil.h @@ -116,6 +116,26 @@ static void set_channel(int idxFrom, int idxTo, cv::Mat &source, cv::Mat &target cv::mixChannels( &source, 1, &target, 1, from_to, 1 ); } +static cv::Mat conj(cv::Mat &host){ + iterate_complex_mat([](std::complex &c) { c = std::complex(c.real(), -c.imag()); }, host); + return host; +} + +static void iterate_complex_mat(const std::function &)> &op, cv::Mat &host){ + assert(host.channels() % 2 == 0); + for (int i = 0; i < host.rows; ++i) { + for (int j = 0; j < host.cols; ++j){ + for (int k = 0; k < host.channels() / 2 ; ++k){ + std::complex cpxVal = host.ptr>(i)[(host.channels() / 2)*j + k]; + op(cpxVal); + host.ptr>(i)[(host.channels() / 2)*j + k] = cpxVal; + } + } + } +} + + + }; #endif /* MAT_UTIL_H */ From 050b77d51aff0c68c56f9441a38889067353286e Mon Sep 17 00:00:00 2001 From: Your Name Date: Mon, 23 Dec 2019 21:06:44 +0100 Subject: [PATCH 022/121] =?UTF-8?q?P=C5=99id=C3=A1na=20funkce=20MatUtil::m?= =?UTF-8?q?ul()=20pro=20aplikaci=20na=20cv::Mat=20-=20funkce=20pou=C5=BEit?= =?UTF-8?q?a=20v=20KCF=5FTracker::train()?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- src/kcf.cpp | 2 +- src/matutil.h | 41 +++++++++++++++++++++++++++++++++++++++-- 2 files changed, 40 insertions(+), 3 deletions(-) diff --git a/src/kcf.cpp b/src/kcf.cpp index 67e43a4c..faed1b32 100644 --- a/src/kcf.cpp +++ b/src/kcf.cpp @@ -100,7 +100,7 @@ void KCF_Tracker::train(cv::Mat input_rgb, cv::Mat input_gray, double interp_fac model->model_alphaf_den = (model->xf * xfconj); cv::Mat xfconj_Test = MatUtil::conj(model->xf_Test); - model->model_alphaf_num_Test = xfconj_Test.mul(model->yf); + model->model_alphaf_num_Test = MatUtil::mul(xfconj_Test, model->yf_Test); } else { // Kernel Ridge Regression, calculate alphas (in Fourier domain) cv::Size sz(Fft::freq_size(feature_size)); diff --git a/src/matutil.h b/src/matutil.h index cdabfcb2..b29d3065 100644 --- a/src/matutil.h +++ b/src/matutil.h @@ -117,11 +117,16 @@ static void set_channel(int idxFrom, int idxTo, cv::Mat &source, cv::Mat &target } static cv::Mat conj(cv::Mat &host){ - iterate_complex_mat([](std::complex &c) { c = std::complex(c.real(), -c.imag()); }, host); + mat_const_operator([](std::complex &c) { c = std::complex(c.real(), -c.imag()); }, host); return host; } -static void iterate_complex_mat(const std::function &)> &op, cv::Mat &host){ +static cv::Mat mul(cv::Mat &host, cv::Mat &other){ + matn_mat1_operator([](std::complex &c_lhs, const std::complex &c_rhs) { c_lhs *= c_rhs; }, host, other); + return host; +} + +static void mat_const_operator(const std::function &)> &op, cv::Mat &host){ assert(host.channels() % 2 == 0); for (int i = 0; i < host.rows; ++i) { for (int j = 0; j < host.cols; ++j){ @@ -134,6 +139,38 @@ static void iterate_complex_mat(const std::function &, const std::complex &), cv::Mat &host, cv::Mat &other){ + assert(host.channels() % 2 == 0); + assert(other.channels() == 2); + assert(other.cols == host.cols); + assert(other.rows == host.rows); + + for (int i = 0; i < host.rows; ++i) { + for (int j = 0; j < host.cols; ++j){ + std::complex cpxValOther = other.ptr>(i)[j]; + for (int k = 0; k < host.channels() / 2 ; ++k){ + std::complex cpxValHost = host.ptr>(i)[(host.channels() / 2)*j + k]; + op(cpxValHost, cpxValOther); + host.ptr>(i)[(host.channels() / 2)*j + k] = cpxValHost; + } + } + } +} + +ComplexMat_ ComplexMat_::matn_mat1_operator(void (*op)(std::complex &, const std::complex &), const ComplexMat_ &mat_rhs) const +{ + assert(mat_rhs.n_channels == 1 && mat_rhs.cols == cols && mat_rhs.rows == rows); + + ComplexMat_ result = *this; + for (uint i = 0; i < n_channels; ++i) { + 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); + } + + return result; +} }; From e5ab93a424bba857e418f1e04117fa5b43f844d5 Mon Sep 17 00:00:00 2001 From: Your Name Date: Mon, 23 Dec 2019 21:15:47 +0100 Subject: [PATCH 023/121] =?UTF-8?q?Oprava=20typu=20argumentu=20v=20MatUtil?= =?UTF-8?q?=20funkc=C3=ADch?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- src/matutil.h | 43 +++++++++++++++++++++++++++++-------------- 1 file changed, 29 insertions(+), 14 deletions(-) diff --git a/src/matutil.h b/src/matutil.h index b29d3065..dc326d4a 100644 --- a/src/matutil.h +++ b/src/matutil.h @@ -126,7 +126,7 @@ static cv::Mat mul(cv::Mat &host, cv::Mat &other){ return host; } -static void mat_const_operator(const std::function &)> &op, cv::Mat &host){ +static void mat_const_operator(const std::function &)> &op, cv::Mat &host){ assert(host.channels() % 2 == 0); for (int i = 0; i < host.rows; ++i) { for (int j = 0; j < host.cols; ++j){ @@ -139,7 +139,7 @@ static void mat_const_operator(const std::function &, const std::complex &), cv::Mat &host, cv::Mat &other){ +static void matn_mat1_operator(void (*op)(std::complex &, const std::complex &), cv::Mat &host, cv::Mat &other){ assert(host.channels() % 2 == 0); assert(other.channels() == 2); assert(other.cols == host.cols); @@ -157,19 +157,34 @@ static void matn_mat1_operator(void (*op)(std::complex &, const } } -ComplexMat_ ComplexMat_::matn_mat1_operator(void (*op)(std::complex &, const std::complex &), const ComplexMat_ &mat_rhs) const -{ - assert(mat_rhs.n_channels == 1 && mat_rhs.cols == cols && mat_rhs.rows == rows); - - ComplexMat_ result = *this; - for (uint i = 0; i < n_channels; ++i) { - 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); +static void mat_mat_operator(void (*op)(std::complex &, const std::complex &), cv::Mat &host, cv::Mat &other){ + assert(host.channels() % 2 == 0); + assert(other.channels() == 2); + assert(other.cols == host.cols); + assert(other.rows == host.rows); + + for (int i = 0; i < host.rows; ++i) { + for (int j = 0; j < host.cols; ++j){ + std::complex cpxValOther = other.ptr>(i)[j]; + for (int k = 0; k < host.channels() / 2 ; ++k){ + std::complex cpxValHost = host.ptr>(i)[(host.channels() / 2)*j + k]; + op(cpxValHost, cpxValOther); + host.ptr>(i)[(host.channels() / 2)*j + k] = cpxValHost; + } + } } - - return result; + +// assert(mat_rhs.n_channels == n_channels/n_scales && mat_rhs.cols == cols && mat_rhs.rows == rows); +// +// ComplexMat_ result = *this; +// for (uint s = 0; s < n_scales; ++s) { +// 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)); +// } +// +// return result; } From 4648f5dd6190dad781401d50de680ace4e83e903 Mon Sep 17 00:00:00 2001 From: Your Name Date: Mon, 23 Dec 2019 21:47:26 +0100 Subject: [PATCH 024/121] =?UTF-8?q?KCF=5Ftracker::train=20->=20Dokon=C4=8D?= =?UTF-8?q?ena=20alternativn=C3=AD=20implementace=20pro=20p=C5=99ep=C3=ADn?= =?UTF-8?q?a=C4=8D=20m=5Fuse=5Flinearkernel=20-=20MatUtil::mul()=20p=C5=99?= =?UTF-8?q?ejmenov=C3=A1n=20na=20mul=5Fmatn=5Fmat1()=20-=20p=C5=99id=C3=A1?= =?UTF-8?q?na=20funkce=20MatUtil::mul=5Fmatn=5Fmatn()=20-=20zat=C3=ADm=20n?= =?UTF-8?q?etestov=C3=A1no,=20mal=C3=A1=20priorita=20upraven=C3=A9=20?= =?UTF-8?q?=C4=8D=C3=A1sti?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- src/kcf.cpp | 3 ++- src/kcf.h | 2 +- src/matutil.h | 23 ++++++++--------------- 3 files changed, 11 insertions(+), 17 deletions(-) diff --git a/src/kcf.cpp b/src/kcf.cpp index faed1b32..0d7165ab 100644 --- a/src/kcf.cpp +++ b/src/kcf.cpp @@ -100,7 +100,8 @@ void KCF_Tracker::train(cv::Mat input_rgb, cv::Mat input_gray, double interp_fac model->model_alphaf_den = (model->xf * xfconj); cv::Mat xfconj_Test = MatUtil::conj(model->xf_Test); - model->model_alphaf_num_Test = MatUtil::mul(xfconj_Test, model->yf_Test); + model->model_alphaf_num_Test = MatUtil::mul_matn_mat1(xfconj_Test, model->yf_Test); + model->model_alphaf_den_Test = MatUtil::mul_matn_matn(model->xf_Test, xfconj_Test); } else { // Kernel Ridge Regression, calculate alphas (in Fourier domain) cv::Size sz(Fft::freq_size(feature_size)); diff --git a/src/kcf.h b/src/kcf.h index 83742ff0..2506a6ce 100644 --- a/src/kcf.h +++ b/src/kcf.h @@ -147,7 +147,7 @@ class KCF_Tracker // FORMER ATTRIBUTES CONVERTED TO cv::Mat - // Something about not being able to tell which kind of cv::Mat (complex matrix does not equal 2 channels !) + // Complex matrix now equals 2*k channels matrix by design cv::Mat yf_Test {(int) height, (int) width, CV_32FC2}; cv::Mat model_alphaf_Test {(int) height, (int) width, CV_32FC2}; cv::Mat model_alphaf_num_Test {(int) height, (int) width, CV_32FC2}; diff --git a/src/matutil.h b/src/matutil.h index dc326d4a..b039d8aa 100644 --- a/src/matutil.h +++ b/src/matutil.h @@ -121,11 +121,16 @@ static cv::Mat conj(cv::Mat &host){ return host; } -static cv::Mat mul(cv::Mat &host, cv::Mat &other){ +static cv::Mat mul_matn_mat1(cv::Mat &host, cv::Mat &other){ matn_mat1_operator([](std::complex &c_lhs, const std::complex &c_rhs) { c_lhs *= c_rhs; }, host, other); return host; } +static cv::Mat mul_matn_matn(cv::Mat &host, cv::Mat &other){ + mat_mat_operator([](std::complex &c_lhs, const std::complex &c_rhs) { c_lhs *= c_rhs; }, host, other); + return host; +} + static void mat_const_operator(const std::function &)> &op, cv::Mat &host){ assert(host.channels() % 2 == 0); for (int i = 0; i < host.rows; ++i) { @@ -159,32 +164,20 @@ static void matn_mat1_operator(void (*op)(std::complex &, const std::comp static void mat_mat_operator(void (*op)(std::complex &, const std::complex &), cv::Mat &host, cv::Mat &other){ assert(host.channels() % 2 == 0); - assert(other.channels() == 2); + assert(other.channels() == host.channels()); assert(other.cols == host.cols); assert(other.rows == host.rows); for (int i = 0; i < host.rows; ++i) { for (int j = 0; j < host.cols; ++j){ - std::complex cpxValOther = other.ptr>(i)[j]; for (int k = 0; k < host.channels() / 2 ; ++k){ std::complex cpxValHost = host.ptr>(i)[(host.channels() / 2)*j + k]; + std::complex cpxValOther = other.ptr>(i)[(other.channels() / 2)*j + k]; op(cpxValHost, cpxValOther); host.ptr>(i)[(host.channels() / 2)*j + k] = cpxValHost; } } } - -// assert(mat_rhs.n_channels == n_channels/n_scales && mat_rhs.cols == cols && mat_rhs.rows == rows); -// -// ComplexMat_ result = *this; -// for (uint s = 0; s < n_scales; ++s) { -// 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)); -// } -// -// return result; } From 045e6600ae60101def652db23a4c2e2d9dda59c6 Mon Sep 17 00:00:00 2001 From: Your Name Date: Mon, 23 Dec 2019 22:46:04 +0100 Subject: [PATCH 025/121] =?UTF-8?q?P=C5=99id=C3=A1na=20funkce=20MatUtil::a?= =?UTF-8?q?dd=5Fscalar=20-=20pou=C5=BEito=20v=20KCF=5Ftracker::train()?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- src/kcf.cpp | 8 +++++--- src/matutil.h | 5 +++++ 2 files changed, 10 insertions(+), 3 deletions(-) diff --git a/src/kcf.cpp b/src/kcf.cpp index 0d7165ab..067d39ee 100644 --- a/src/kcf.cpp +++ b/src/kcf.cpp @@ -112,9 +112,11 @@ void KCF_Tracker::train(cv::Mat input_rgb, cv::Mat input_gray, double interp_fac model->model_alphaf_den = kf * (kf + p_lambda); -// cv::Mat kf_Test = cv::Mat(sz.height, sz.width, CV_32F); -// (*gaussian_correlation)(kf_Test, model->model_xf_Test, model->model_xf_Test, p_kernel_sigma, true, *this); -// DEBUG_PRINTM(kf_Test); + cv::Mat kf_Test = cv::Mat(sz.height, sz.width, CV_32FC2); + (*gaussian_correlation)(kf_Test, model->model_xf_Test, model->model_xf_Test, p_kernel_sigma, true, *this); + DEBUG_PRINTM(kf_Test); + model->model_alphaf_num_Test = MatUtil::mul_matn_matn(model->yf_Test, kf_Test); + model->model_alphaf_den_Test = MatUtil::mul_matn_matn(kf_Test, MatUtil::add_scalar(kf_Test, p_lambda)); } model->model_alphaf = model->model_alphaf_num / model->model_alphaf_den; DEBUG_PRINTM(model->model_alphaf); diff --git a/src/matutil.h b/src/matutil.h index b039d8aa..93507f9f 100644 --- a/src/matutil.h +++ b/src/matutil.h @@ -131,6 +131,11 @@ static cv::Mat mul_matn_matn(cv::Mat &host, cv::Mat &other){ return host; } +static cv::Mat add_scalar(cv::Mat &host, float &val){ + mat_const_operator([&rhs](std::complex &c) { c += rhs; }, host); + return host; +} + static void mat_const_operator(const std::function &)> &op, cv::Mat &host){ assert(host.channels() % 2 == 0); for (int i = 0; i < host.rows; ++i) { From e1a1d8d6595298d218ed3354d70eaaa85224cf52 Mon Sep 17 00:00:00 2001 From: Your Name Date: Fri, 27 Dec 2019 19:52:34 +0100 Subject: [PATCH 026/121] =?UTF-8?q?P=C5=99id=C3=A1na=20funkce=20MatUtil::a?= =?UTF-8?q?dd=5Fscalar=20-=20oprava=20struktury=20lambdy?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- src/kcf.cpp | 42 +++++++++++++++++++++++++++++++++++++++++- 1 file changed, 41 insertions(+), 1 deletion(-) diff --git a/src/kcf.cpp b/src/kcf.cpp index 067d39ee..aa82695b 100644 --- a/src/kcf.cpp +++ b/src/kcf.cpp @@ -820,7 +820,7 @@ void KCF_Tracker::GaussianCorrelation::operator()(ComplexMat &result, const Comp TRACE(""); DEBUG_PRINTM(xf); DEBUG_PRINT(xf_sqr_norm.num_elem); - xf.sqr_norm(xf_sqr_norm); + xf.sqr_norm(xf_sqr_norm); for (uint s = 0; s < xf.n_scales; ++s) DEBUG_PRINT(xf_sqr_norm[s]); if (auto_correlation) { @@ -852,6 +852,46 @@ void KCF_Tracker::GaussianCorrelation::operator()(ComplexMat &result, const Comp kcf.fft.forward(ifft_res, result); } +// REPLACEMENT +void KCF_Tracker::GaussianCorrelation::operator()(cv::Mat &result, const cv::Mat &xf, const cv::Mat &yf, + double sigma, bool auto_correlation, const KCF_Tracker &kcf) +{ + TRACE(""); + DEBUG_PRINTM(xf); + DEBUG_PRINT(xf_sqr_norm_Test.total()); + MatUtil::sqr_norm(xf_sqr_norm_Test); +// +// for (uint s = 0; s < xf.n_scales; ++s) +// DEBUG_PRINT(xf_sqr_norm[s]); +// if (auto_correlation) { +// yf_sqr_norm = xf_sqr_norm; +// } else { +// DEBUG_PRINTM(yf); +// yf.sqr_norm(yf_sqr_norm); +// } +// for (uint s = 0; s < yf.n_scales; ++s) +// DEBUG_PRINTM(yf_sqr_norm[s]); +// xyf = auto_correlation ? xf.sqr_mag() : xf * yf.conj(); // xf.muln(yf.conj()); +// DEBUG_PRINTM(xyf); +// +// // ifft2 and sum over 3rd dimension, we dont care about individual channels +// ComplexMat xyf_sum = xyf.sum_over_channels(); +// DEBUG_PRINTM(xyf_sum); +// kcf.fft.inverse(xyf_sum, ifft_res); +// DEBUG_PRINTM(ifft_res); +// +// float numel_xf_inv = 1.f / (xf.cols * xf.rows * (xf.channels() / xf.n_scales)); +// for (uint i = 0; i < xf.n_scales; ++i) { +// cv::Mat plane = ifft_res.plane(i); +// DEBUG_PRINT(ifft_res.plane(i)); +// cv::exp(-1. / (sigma * sigma) * cv::max((xf_sqr_norm[i] + yf_sqr_norm[0] - 2 * ifft_res.plane(i)) +// * numel_xf_inv, 0), plane); +// DEBUG_PRINTM(plane); +// } +// +// kcf.fft.forward(ifft_res, result); +} + float get_response_circular(cv::Point2i &pt, cv::Mat &response) { int x = pt.x; From 0076543cc683c7e1d2212a65466c77923ae15329 Mon Sep 17 00:00:00 2001 From: Your Name Date: Sat, 28 Dec 2019 16:14:56 +0100 Subject: [PATCH 027/121] =?UTF-8?q?P=C5=99id=C3=A1na=20konverze=20atribut?= =?UTF-8?q?=C5=AF=20t=C5=99=C3=ADdy=20GaussianCorrelation?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- src/kcf.h | 16 +++++++++++++++- 1 file changed, 15 insertions(+), 1 deletion(-) diff --git a/src/kcf.h b/src/kcf.h index 2506a6ce..4fb41a2e 100644 --- a/src/kcf.h +++ b/src/kcf.h @@ -175,8 +175,16 @@ class KCF_Tracker , xyf(Fft::freq_size(size), num_feats, num_scales) , ifft_res(num_scales, size) , k(num_scales, size) - {} + { + xf_sqr_norm_Test.reserve(num_scales); + yf_sqr_norm_Test.reserve(1); + cv::Size temp = Fft::freq_size(size); + xyf_Test = cv::Mat(3, std::vector({(int) num_scales, temp.height, temp.width}).data(), CV_32FC(num_feats*2)); + ifft_res_Test = cv::Mat(3, std::vector({(int) num_scales, size.height, size.width}).data(), CV_32F); + k_Test = cv::Mat(3, std::vector({(int) num_scales, size.height, size.width}).data(), CV_32F); + } void operator()(ComplexMat &result, const ComplexMat &xf, const ComplexMat &yf, double sigma, bool auto_correlation, const KCF_Tracker &kcf); + void operator()(cv::Mat &result, const cv::Mat &xf, const cv::Mat &yf, double sigma, bool auto_correlation, const KCF_Tracker &kcf); private: DynMem xf_sqr_norm; @@ -184,6 +192,12 @@ class KCF_Tracker ComplexMat xyf; MatScales ifft_res; MatScales k; + + std::vector xf_sqr_norm_Test = std::vector(); + std::vector yf_sqr_norm_Test = std::vector(); + cv::Mat xyf_Test; + cv::Mat ifft_res_Test; + cv::Mat k_Test; }; //helping functions From 44dc036f90a2e772e2d8faa31cbdf4f9e44889c5 Mon Sep 17 00:00:00 2001 From: Your Name Date: Sat, 28 Dec 2019 17:05:00 +0100 Subject: [PATCH 028/121] =?UTF-8?q?P=C5=99id=C3=A1na=20p=C5=99epracovan?= =?UTF-8?q?=C3=A1=20verze=20funkce=20sqr=5Fnorm()=20do=20MatUtil?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- src/matutil.h | 27 ++++++++++++++++++++++++--- 1 file changed, 24 insertions(+), 3 deletions(-) diff --git a/src/matutil.h b/src/matutil.h index 93507f9f..0cc54234 100644 --- a/src/matutil.h +++ b/src/matutil.h @@ -101,7 +101,6 @@ static cv::Mat scale(uint scale, cv::Mat &host) { return cv::Mat(3, std::vector({host.size[1], host.size[2], host.size[3]}).data(), host.type(), host.ptr(scale)); } - /* * Sets channel number idxFrom of the source as channel number idxTo of target matrix. * Uses native format of cv::Mat to store channels, meaning all channel values of each pixel @@ -116,6 +115,28 @@ static void set_channel(int idxFrom, int idxTo, cv::Mat &source, cv::Mat &target cv::mixChannels( &source, 1, &target, 1, from_to, 1 ); } +/* + * Computes sum of results from formula ((real)^2 + (imag)^2) + * for every complex element in a scale of the matrix. + * This is repeated for every scale, and the results are appended into result vector. +**/ +static void sqr_norm(const cv::Mat &host, std::vector &result) +{ + assert(host.channels() % 2 == 0); + for (int scale = 0; scale < host.size[0]; ++scale) { + float sum_sqr_norm = 0; + + for (int row = 0; row < host.size[1]; ++row) + for (int col = 0; col < host.size[2]; ++col) + for (int ch = 0; ch < host.channels() / 2; ++ch){ + std::complex cpxVal = host.ptr>(scale,row)[(host.channels() / 2)*col + ch]; + sum_sqr_norm += cpxVal.real() * cpxVal.real() + cpxVal.imag() * cpxVal.imag(); + } + result.push_back(sum_sqr_norm / static_cast(host.size[1] * host.size[2])); + } + return; +} + static cv::Mat conj(cv::Mat &host){ mat_const_operator([](std::complex &c) { c = std::complex(c.real(), -c.imag()); }, host); return host; @@ -131,8 +152,8 @@ static cv::Mat mul_matn_matn(cv::Mat &host, cv::Mat &other){ return host; } -static cv::Mat add_scalar(cv::Mat &host, float &val){ - mat_const_operator([&rhs](std::complex &c) { c += rhs; }, host); +static cv::Mat add_scalar(cv::Mat &host, const float &val){ + mat_const_operator([&val](std::complex &c) { c += val; }, host); return host; } From d047bf8d35ad3e4c5de649f19c6d3291c6e7d4a8 Mon Sep 17 00:00:00 2001 From: Your Name Date: Sat, 28 Dec 2019 18:56:46 +0100 Subject: [PATCH 029/121] =?UTF-8?q?P=C5=99id=C3=A1na=20p=C5=99epracovan?= =?UTF-8?q?=C3=A1=20verze=20funkce=20sqr=5Fmag()=20do=20MatUtil=20-=20opra?= =?UTF-8?q?veno=20vol=C3=A1n=C3=AD=20GaussianCorrelation=20v=20KCF=5FTrack?= =?UTF-8?q?er::train()=20-=20pro=20GaussianCorrelation::operator()=20odstr?= =?UTF-8?q?an=C4=9Bny=20kvalifikatory=20const=20-=20p=C5=99epracovana=20da?= =?UTF-8?q?l=C5=A1=C3=AD=20=C4=8D=C3=A1st=20metody=20GaussianCorrelatio::o?= =?UTF-8?q?perator()?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- src/kcf.cpp | 55 +++++++++++++++++++++++++++++---------------------- src/kcf.h | 2 +- src/matutil.h | 6 +++++- 3 files changed, 37 insertions(+), 26 deletions(-) diff --git a/src/kcf.cpp b/src/kcf.cpp index aa82695b..cb86b4cd 100644 --- a/src/kcf.cpp +++ b/src/kcf.cpp @@ -116,7 +116,8 @@ void KCF_Tracker::train(cv::Mat input_rgb, cv::Mat input_gray, double interp_fac (*gaussian_correlation)(kf_Test, model->model_xf_Test, model->model_xf_Test, p_kernel_sigma, true, *this); DEBUG_PRINTM(kf_Test); model->model_alphaf_num_Test = MatUtil::mul_matn_matn(model->yf_Test, kf_Test); - model->model_alphaf_den_Test = MatUtil::mul_matn_matn(kf_Test, MatUtil::add_scalar(kf_Test, p_lambda)); + cv::Mat addedMat = MatUtil::add_scalar(kf_Test, p_lambda); + model->model_alphaf_den_Test = MatUtil::mul_matn_matn(kf_Test, addedMat); } model->model_alphaf = model->model_alphaf_num / model->model_alphaf_den; DEBUG_PRINTM(model->model_alphaf); @@ -174,12 +175,16 @@ void KCF_Tracker::init(cv::Mat &img, const cv::Rect &bbox, int fit_size_x, int f // } // } // +// cv::Mat test = cv::Mat(3, std::vector({2, 2, 2}).data(), CV_32FC2, float(5)); +// test.ptr(0)[0] = float(1); +// test.ptr(1)[0] = float(1); +// test.ptr(1,1)[0] = float(1); // // DEBUG_PRINTM(test); // // // return; -// + // check boundary, enforce min size double x1 = bbox.x, x2 = bbox.x + bbox.width, y1 = bbox.y, y2 = bbox.y + bbox.height; if (x1 < 0) x1 = 0.; @@ -853,32 +858,34 @@ void KCF_Tracker::GaussianCorrelation::operator()(ComplexMat &result, const Comp } // REPLACEMENT -void KCF_Tracker::GaussianCorrelation::operator()(cv::Mat &result, const cv::Mat &xf, const cv::Mat &yf, +void KCF_Tracker::GaussianCorrelation::operator()(cv::Mat &result, cv::Mat &xf, cv::Mat &yf, double sigma, bool auto_correlation, const KCF_Tracker &kcf) { TRACE(""); DEBUG_PRINTM(xf); - DEBUG_PRINT(xf_sqr_norm_Test.total()); - MatUtil::sqr_norm(xf_sqr_norm_Test); -// -// for (uint s = 0; s < xf.n_scales; ++s) -// DEBUG_PRINT(xf_sqr_norm[s]); -// if (auto_correlation) { -// yf_sqr_norm = xf_sqr_norm; -// } else { -// DEBUG_PRINTM(yf); -// yf.sqr_norm(yf_sqr_norm); -// } -// for (uint s = 0; s < yf.n_scales; ++s) -// DEBUG_PRINTM(yf_sqr_norm[s]); -// xyf = auto_correlation ? xf.sqr_mag() : xf * yf.conj(); // xf.muln(yf.conj()); -// DEBUG_PRINTM(xyf); -// -// // ifft2 and sum over 3rd dimension, we dont care about individual channels -// ComplexMat xyf_sum = xyf.sum_over_channels(); -// DEBUG_PRINTM(xyf_sum); -// kcf.fft.inverse(xyf_sum, ifft_res); -// DEBUG_PRINTM(ifft_res); + DEBUG_PRINT(xf_sqr_norm_Test.size()); + MatUtil::sqr_norm(xf, xf_sqr_norm_Test); + + for (uint s = 0; s < xf_sqr_norm_Test.size(); ++s) + DEBUG_PRINT(xf_sqr_norm_Test.at(s)); + if (auto_correlation) { + yf_sqr_norm_Test = xf_sqr_norm_Test; + } else { + DEBUG_PRINTM(yf); + MatUtil::sqr_norm(yf, yf_sqr_norm_Test); + } + for (uint s = 0; s < yf_sqr_norm_Test.size(); ++s) + DEBUG_PRINTM(yf_sqr_norm_Test.at(s)); + + cv::Mat conjMat = MatUtil::conj(yf); + xyf_Test = auto_correlation ? MatUtil::sqr_mag(xf) : MatUtil::mul_matn_matn(xf, conjMat); // xf.muln(yf.conj()); + DEBUG_PRINTM(xyf_Test); + + // ifft2 and sum over 3rd dimension, we dont care about individual channels + ComplexMat xyf_sum = xyf.sum_over_channels(); + DEBUG_PRINTM(xyf_sum); + kcf.fft.inverse(xyf_sum, ifft_res); + DEBUG_PRINTM(ifft_res); // // float numel_xf_inv = 1.f / (xf.cols * xf.rows * (xf.channels() / xf.n_scales)); // for (uint i = 0; i < xf.n_scales; ++i) { diff --git a/src/kcf.h b/src/kcf.h index 4fb41a2e..c00ebf3e 100644 --- a/src/kcf.h +++ b/src/kcf.h @@ -184,7 +184,7 @@ class KCF_Tracker k_Test = cv::Mat(3, std::vector({(int) num_scales, size.height, size.width}).data(), CV_32F); } void operator()(ComplexMat &result, const ComplexMat &xf, const ComplexMat &yf, double sigma, bool auto_correlation, const KCF_Tracker &kcf); - void operator()(cv::Mat &result, const cv::Mat &xf, const cv::Mat &yf, double sigma, bool auto_correlation, const KCF_Tracker &kcf); + void operator()(cv::Mat &result, cv::Mat &xf, cv::Mat &yf, double sigma, bool auto_correlation, const KCF_Tracker &kcf); private: DynMem xf_sqr_norm; diff --git a/src/matutil.h b/src/matutil.h index 0cc54234..6dbcdd67 100644 --- a/src/matutil.h +++ b/src/matutil.h @@ -134,7 +134,11 @@ static void sqr_norm(const cv::Mat &host, std::vector &result) } result.push_back(sum_sqr_norm / static_cast(host.size[1] * host.size[2])); } - return; +} + +static cv::Mat sqr_mag(cv::Mat &host){ + mat_const_operator([](std::complex &c) { c = c.real() * c.real() + c.imag() * c.imag(); }, host); + return host; } static cv::Mat conj(cv::Mat &host){ From a5ac36120d43d025ae189623d804d174322c97b2 Mon Sep 17 00:00:00 2001 From: Your Name Date: Sat, 28 Dec 2019 19:33:37 +0100 Subject: [PATCH 030/121] =?UTF-8?q?P=C5=99id=C3=A1na=20p=C5=99epracovan?= =?UTF-8?q?=C3=A1=20verze=20funkce=20sum=5Fover=5Fchannels()=20do=20MatUti?= =?UTF-8?q?l=20-=20p=C5=99eps=C3=A1no=20vol=C3=A1n=C3=AD=20v=20GaussianCor?= =?UTF-8?q?relation::operator()?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- src/kcf.cpp | 6 ++-- src/matutil.h | 91 +++++++++++---------------------------------------- 2 files changed, 22 insertions(+), 75 deletions(-) diff --git a/src/kcf.cpp b/src/kcf.cpp index cb86b4cd..57fff49c 100644 --- a/src/kcf.cpp +++ b/src/kcf.cpp @@ -882,10 +882,10 @@ void KCF_Tracker::GaussianCorrelation::operator()(cv::Mat &result, cv::Mat &xf, DEBUG_PRINTM(xyf_Test); // ifft2 and sum over 3rd dimension, we dont care about individual channels - ComplexMat xyf_sum = xyf.sum_over_channels(); + cv::Mat xyf_sum = MatUtil::sum_over_channels(xyf_Test); DEBUG_PRINTM(xyf_sum); - kcf.fft.inverse(xyf_sum, ifft_res); - DEBUG_PRINTM(ifft_res); +// kcf.fft.inverse(xyf_sum, ifft_res_Test); +// DEBUG_PRINTM(ifft_res_Test); // // float numel_xf_inv = 1.f / (xf.cols * xf.rows * (xf.channels() / xf.n_scales)); // for (uint i = 0; i < xf.n_scales; ++i) { diff --git a/src/matutil.h b/src/matutil.h index 6dbcdd67..e98f8263 100644 --- a/src/matutil.h +++ b/src/matutil.h @@ -6,78 +6,6 @@ #include - -//------ -//same_size() only used in complexmat.cu , ignored -//size() and channel() already implemented in cv::Mat -//------ - - -//// This computes a float value using elements in individual channels (seems unused) -//float sqr_norm(cv::Mat &host) const; -// -//// This edits given Dynmem to contain computed float value in its [1] position (why?) -//void sqr_norm(DynMem_ &result, cv::Mat &host) const; -// -//// Applies square operation to all elements in all channels -//cv::Mat sqr_mag() const; -// -//// Applies "invert imaginary number" operation to all elements in all channels -//cv::Mat conj() const; -// -//// DEFINE (=copy definition of) THIS BLOCK IN kcf.cpp -//cv::Mat sum_over_channels(cv::Mat &host) const; -// -////------ -//// to_cv_mat() and channel_to_cv_mat() unnecesary, since the data is already cv::Mat format -////------ -// -// -//// DECIDE IF THIS IS ACTUALLY NEEDED WITH CURRENT cv::Mat FORMAT -//// return a vector of 2 channels (real, imag) per one complex channel -//std::vector to_cv_mat_vector() const -//{ -// std::vector result; -// result.reserve(n_channels); -// -// for (uint i = 0; i < n_channels; ++i) -// result.push_back(channel_to_cv_mat(i)); -// -// return result; -//} -// -// -////------ -//// get_p_data() unnecessary -//// mul() and operator functions implemented in cv::Mat -////------ -// -//// READY FOR TESTING -//// convert 2 channel mat (real, imag) to vector row-by-row -//std::vector> convert(const cv::Mat &mat) -//{ -// std::vector> result; -// result.reserve(mat.cols * mat.rows); -// for (int y = 0; y < mat.rows; ++y) { -// const float *row_ptr = mat.ptr(y); -// for (int x = 0; x < 2 * mat.cols; x += 2) { -// result.push_back(std::complex(row_ptr[x], row_ptr[x + 1])); -// } -// } -// return result; -//} -// -//// DEFINE (=copy definition of) THIS BLOCK IN kcf.cpp -//// [ possibly completely replaced by cv::Mat.forEach() ] -//ComplexMat_ mat_mat_operator(void (*op)(std::complex &c_lhs, const std::complex &c_rhs), -// const ComplexMat_ &mat_rhs) const; -//ComplexMat_ matn_mat1_operator(void (*op)(std::complex &c_lhs, const std::complex &c_rhs), -// const ComplexMat_ &mat_rhs) const; -//ComplexMat_ matn_mat2_operator(void (*op)(std::complex &c_lhs, const std::complex &c_rhs), -// const ComplexMat_ &mat_rhs) const; -//ComplexMat_ mat_const_operator(const std::function &c_rhs)> &op) const; -// - class MatUtil{ public: /* @@ -136,6 +64,25 @@ static void sqr_norm(const cv::Mat &host, std::vector &result) } } + +static cv::Mat sum_over_channels(cv::Mat &host) +{ + assert(host.channels() % 2 == 0); + + cv::Mat result(3, std::vector({(int) host.size[0], host.size[1], host.size[2]}).data(), CV_32FC2); + for (int scale = 0; scale < host.size[0]; ++scale) { + for (int row = 0; row < host.size[1]; ++row) + for (int col = 0; col < host.size[2]; ++col){ + std::complex acc = 0; + for (int ch = 0; ch < host.channels() / 2; ++ch){ + acc += host.ptr>(scale,row)[(host.channels() / 2)*col + ch]; + } + result.ptr>(scale,row)[col] = acc; + } + } + return result; +} + static cv::Mat sqr_mag(cv::Mat &host){ mat_const_operator([](std::complex &c) { c = c.real() * c.real() + c.imag() * c.imag(); }, host); return host; From dcf10056e6ed7d161f5ff7529aa1be4f57bbb749 Mon Sep 17 00:00:00 2001 From: Your Name Date: Sat, 28 Dec 2019 20:21:07 +0100 Subject: [PATCH 031/121] =?UTF-8?q?P=C5=99id=C3=A1na=20funkce=20plane3()?= =?UTF-8?q?=20do=20MatUtil=20-=20pravd=C4=9Bpodobn=C4=9B=20nahrad=C3=AD=20?= =?UTF-8?q?funkci=20MatUtil::plane(),=20proto=C5=BEe=204.=20dimenze=20je?= =?UTF-8?q?=20po=C4=8Det=20kan=C3=A1l=C5=AF,=20co=C5=BE=20jde=20ulo=C5=BEi?= =?UTF-8?q?t=20v=20typu=20cv::Mat?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- src/matutil.h | 12 ++++++++++++ 1 file changed, 12 insertions(+) diff --git a/src/matutil.h b/src/matutil.h index e98f8263..43c5a4f1 100644 --- a/src/matutil.h +++ b/src/matutil.h @@ -19,6 +19,18 @@ static cv::Mat plane(uint scale, uint feature, cv::Mat &host) { return cv::Mat(host.size[2], host.size[3], host.type(), host.ptr(scale, feature)); } +/* + * Function for getting cv::Mat header referencing height and width of the input matrix. + * Presumes input matrix of 3 dimensions with format: {scales, height, width} + * + * This will probably replace MatUtil::plane() + **/ +static cv::Mat plane3(uint scale, cv::Mat &host) { + assert(host.dims == 3); + assert(int(scale) < host.size[0]); + return cv::Mat(host.size[1], host.size[2], host.type(), host.ptr(scale)); +} + /* * Function for getting cv::Mat header referencing features, height and width of the input matrix. * Presumes input matrix of 4 dimensions with format: {scales, features, height, width} From fa2324b2c364c8ea9d1ea895e165dc9e152d7947 Mon Sep 17 00:00:00 2001 From: Your Name Date: Sat, 28 Dec 2019 20:24:52 +0100 Subject: [PATCH 032/121] =?UTF-8?q?P=C5=99id=C3=A1na=20funkce=20plane3()?= =?UTF-8?q?=20do=20MatUtil=20(Oprava)?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- src/matutil.h | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) diff --git a/src/matutil.h b/src/matutil.h index 43c5a4f1..50545ad2 100644 --- a/src/matutil.h +++ b/src/matutil.h @@ -25,10 +25,10 @@ static cv::Mat plane(uint scale, uint feature, cv::Mat &host) { * * This will probably replace MatUtil::plane() **/ -static cv::Mat plane3(uint scale, cv::Mat &host) { +static cv::Mat plane3(uint dim0, cv::Mat &host) { assert(host.dims == 3); - assert(int(scale) < host.size[0]); - return cv::Mat(host.size[1], host.size[2], host.type(), host.ptr(scale)); + assert(int(dim0) < host.size[0]); + return cv::Mat(host.size[1], host.size[2], host.type(), host.ptr(dim0)); } /* From 9f1d1592cc5219ecc8d407c71105b18f40f48879 Mon Sep 17 00:00:00 2001 From: Your Name Date: Sun, 29 Dec 2019 17:55:57 +0100 Subject: [PATCH 033/121] plane3() prejmenovana na plane() v MatUtil --- src/matutil.h | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/matutil.h b/src/matutil.h index 50545ad2..a1a783d5 100644 --- a/src/matutil.h +++ b/src/matutil.h @@ -25,7 +25,7 @@ static cv::Mat plane(uint scale, uint feature, cv::Mat &host) { * * This will probably replace MatUtil::plane() **/ -static cv::Mat plane3(uint dim0, cv::Mat &host) { +static cv::Mat plane(uint dim0, cv::Mat &host) { assert(host.dims == 3); assert(int(dim0) < host.size[0]); return cv::Mat(host.size[1], host.size[2], host.type(), host.ptr(dim0)); From 1a2a3a9e202c7c6bc3be9676453a1c571ee97010 Mon Sep 17 00:00:00 2001 From: Your Name Date: Sun, 29 Dec 2019 18:59:51 +0100 Subject: [PATCH 034/121] =?UTF-8?q?P=C5=99id=C3=A1na=20funkce=20channel=5F?= =?UTF-8?q?to=5Fcv=5Fmat()=20do=20MatUtil=20-=20pou=C5=BE=C3=ADv=C3=A1=20n?= =?UTF-8?q?ativn=C3=AD=20cv::MixChannels=20m=C3=ADsto=20n=C4=9Bkolika=20fo?= =?UTF-8?q?r-loop=20-=20vy=C5=BEaduje=20ale=20cv::Mat=20se=20stejn=C3=BDmi?= =?UTF-8?q?=20dimenzemi?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- src/matutil.h | 20 +++++++++++++++++++- 1 file changed, 19 insertions(+), 1 deletion(-) diff --git a/src/matutil.h b/src/matutil.h index a1a783d5..f27508fc 100644 --- a/src/matutil.h +++ b/src/matutil.h @@ -76,7 +76,11 @@ static void sqr_norm(const cv::Mat &host, std::vector &result) } } - +/* + * Sum of channel values for each point of input matrix + * becomes a new point in the new matrix. + * Scales are saved separately in first dimension of new matrix. +**/ static cv::Mat sum_over_channels(cv::Mat &host) { assert(host.channels() % 2 == 0); @@ -95,6 +99,20 @@ static cv::Mat sum_over_channels(cv::Mat &host) return result; } +/* + * Extracts two channels from input, and sets them as data of resulting new matrix. + * Presumes format where two neighbouring channels of input make one complex value. +**/ +static cv::Mat channel_to_cv_mat(int channel_id, cv::Mat &host){ + cv::Mat result(host.rows, host.cols, CV_32FC2); + int from_to[] = { channel_id, 0 }; + cv::mixChannels(&host,1,&result,1,from_to,1); + int from_to2[] = { (channel_id + 1), 1 }; + cv::mixChannels(&host,1,&result,1,from_to2,1); + return result; +} + + static cv::Mat sqr_mag(cv::Mat &host){ mat_const_operator([](std::complex &c) { c = c.real() * c.real() + c.imag() * c.imag(); }, host); return host; From 1ad86b0ad9394b9f1f136a0c0cec073d7d7e44e2 Mon Sep 17 00:00:00 2001 From: Your Name Date: Sun, 29 Dec 2019 19:15:33 +0100 Subject: [PATCH 035/121] =?UTF-8?q?Implementov=C3=A1na=20alternativn=C3=AD?= =?UTF-8?q?=20verze=20fft::inverse()=20-=20dal=C5=A1=C3=AD=20postup=20v=20?= =?UTF-8?q?=C3=BAprav=C3=A1ch=20GaussianCorrelation::operator()?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- src/fft_opencv.cpp | 14 ++++++++++++++ src/fft_opencv.h | 1 + src/kcf.cpp | 29 ++++++++++++++++++++--------- 3 files changed, 35 insertions(+), 9 deletions(-) diff --git a/src/fft_opencv.cpp b/src/fft_opencv.cpp index cc2603fb..eb486dec 100644 --- a/src/fft_opencv.cpp +++ b/src/fft_opencv.cpp @@ -72,4 +72,18 @@ void FftOpencv::inverse(ComplexMat & complex_input, MatScales & real_result) } } +// REPLACEMENT +void FftOpencv::inverse(cv::Mat &complex_input, cv::Mat &real_result) +{ + //Fft::inverse(complex_input, real_result); + + assert(complex_input.channels() % 2 == 0); + cv::Mat source = MatUtil::plane(0, complex_input); // seems like only first dimension is relevant + for (uint i = 0; i < uint(source.channels() / 2); ++i) { + cv::Mat inputChannel = MatUtil::channel_to_cv_mat(i*2, source); // extract channel matrix + cv::Mat target = MatUtil::plane(i, real_result); // select output plane + cv::dft(inputChannel, target, cv::DFT_INVERSE | cv::DFT_REAL_OUTPUT | cv::DFT_SCALE); + } +} + FftOpencv::~FftOpencv() {} diff --git a/src/fft_opencv.h b/src/fft_opencv.h index 559c16f9..cdf462e4 100644 --- a/src/fft_opencv.h +++ b/src/fft_opencv.h @@ -17,6 +17,7 @@ class FftOpencv : public Fft void forward_window(cv::Mat &feat, cv::Mat &complex_result, cv::Mat &temp); void inverse(ComplexMat &complex_input, MatScales &real_result); + void inverse(cv::Mat &complex_input, cv::Mat &real_result); ~FftOpencv(); private: cv::Mat m_window; diff --git a/src/kcf.cpp b/src/kcf.cpp index 57fff49c..9155d72a 100644 --- a/src/kcf.cpp +++ b/src/kcf.cpp @@ -138,10 +138,10 @@ void KCF_Tracker::init(cv::Mat &img, const cv::Rect &bbox, int fit_size_x, int f __dbgTracer.debug = m_debug; TRACE(""); -// cv::Mat test = cv::Mat(2,2,CV_32FC4,float(0)); -//// cv::Mat test2 = cv::Mat(3,2,CV_32F,float(6)); -//// int from_to[] = { 0,3 }; -//// cv::mixChannels(&test2,1,&test,1,from_to,1); +// //cv::Mat test = cv::Mat(2,2,CV_32FC4,float(1)); +// cv::Mat test = cv::Mat(3, std::vector({2, 2, 2}).data(), CV_32FC2, float(5)); +// cv::Mat testPl = cv::Mat(test.size[1], test.size[2], test.type(), test.ptr(0)); +// cv::Mat test2 = cv::Mat(2,2,CV_32FC2,float(6)); // //// cv::Mat_> testComplex = cv::Mat_>(test2); // @@ -161,6 +161,17 @@ void KCF_Tracker::init(cv::Mat &img, const cv::Rect &bbox, int fit_size_x, int f // test.ptr(1)[5] = float(14); // test.ptr(1)[6] = float(15); // test.ptr(1)[7] = float(16); +// DEBUG_PRINTM(test); +// DEBUG_PRINTM(testPl); +// DEBUG_PRINTM(test2); +// +// int from_to[] = { 0,0 }; +// cv::mixChannels(&testPl,1,&test2,1,from_to,1); +// int from_to2[] = { 1,1 }; +// cv::mixChannels(&testPl,1,&test2,1,from_to2,1); +// +// DEBUG_PRINTM(test2); +// return; // // // assert(test.channels() % 2 == 0); @@ -884,10 +895,10 @@ void KCF_Tracker::GaussianCorrelation::operator()(cv::Mat &result, cv::Mat &xf, // ifft2 and sum over 3rd dimension, we dont care about individual channels cv::Mat xyf_sum = MatUtil::sum_over_channels(xyf_Test); DEBUG_PRINTM(xyf_sum); -// kcf.fft.inverse(xyf_sum, ifft_res_Test); -// DEBUG_PRINTM(ifft_res_Test); -// -// float numel_xf_inv = 1.f / (xf.cols * xf.rows * (xf.channels() / xf.n_scales)); + kcf.fft.inverse(xyf_sum, ifft_res_Test); + DEBUG_PRINTM(ifft_res_Test); + + float numel_xf_inv = 1.f / (xf.cols * xf.rows * (xf.channels() / 2)); // for (uint i = 0; i < xf.n_scales; ++i) { // cv::Mat plane = ifft_res.plane(i); // DEBUG_PRINT(ifft_res.plane(i)); @@ -896,7 +907,7 @@ void KCF_Tracker::GaussianCorrelation::operator()(cv::Mat &result, cv::Mat &xf, // DEBUG_PRINTM(plane); // } // -// kcf.fft.forward(ifft_res, result); + kcf.fft.forward(ifft_res_Test, result); } float get_response_circular(cv::Point2i &pt, cv::Mat &response) From 5d45612e288c40c822cdaccef9885903fea62680 Mon Sep 17 00:00:00 2001 From: Your Name Date: Sun, 29 Dec 2019 19:34:11 +0100 Subject: [PATCH 036/121] =?UTF-8?q?Dokon=C4=8Deny=20=C3=BApravy=20na=20alt?= =?UTF-8?q?ernativn=C3=AD=20verz=20GaussianCorrelation::operator()=20-=20f?= =?UTF-8?q?or=20loop=20bude=20je=C5=A1t=C4=9B=20p=C5=99id=C3=A1n,=20a?= =?UTF-8?q?=C5=BE=20zjist=C3=ADm=20kdy=20se=20v=20Model::model=5Fxf=20m?= =?UTF-8?q?=C4=9Bly=20objevit=20funguj=C3=ADc=C3=AD=20scale?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- src/kcf.cpp | 12 ++++++------ 1 file changed, 6 insertions(+), 6 deletions(-) diff --git a/src/kcf.cpp b/src/kcf.cpp index 9155d72a..798a389b 100644 --- a/src/kcf.cpp +++ b/src/kcf.cpp @@ -900,13 +900,13 @@ void KCF_Tracker::GaussianCorrelation::operator()(cv::Mat &result, cv::Mat &xf, float numel_xf_inv = 1.f / (xf.cols * xf.rows * (xf.channels() / 2)); // for (uint i = 0; i < xf.n_scales; ++i) { -// cv::Mat plane = ifft_res.plane(i); -// DEBUG_PRINT(ifft_res.plane(i)); -// cv::exp(-1. / (sigma * sigma) * cv::max((xf_sqr_norm[i] + yf_sqr_norm[0] - 2 * ifft_res.plane(i)) -// * numel_xf_inv, 0), plane); -// DEBUG_PRINTM(plane); + cv::Mat plane = MatUtil::plane(0,ifft_res_Test); + DEBUG_PRINTM(plane); + cv::exp(-1. / (sigma * sigma) * cv::max((xf_sqr_norm[0] + yf_sqr_norm[0] - 2 * MatUtil::plane(0,ifft_res_Test)) + * numel_xf_inv, 0), plane); + DEBUG_PRINTM(plane); // } -// + kcf.fft.forward(ifft_res_Test, result); } From cc5ebae2514c5f10e9aca5d444e9bbd51bce09eb Mon Sep 17 00:00:00 2001 From: Your Name Date: Sun, 29 Dec 2019 20:41:23 +0100 Subject: [PATCH 037/121] =?UTF-8?q?Opravena=20chyba=20sqr=5Fnorm()=20-=20v?= =?UTF-8?q?stup=20ComplexMat=20funkce=20podle=20v=C3=BDpisu=20pou=C5=BEit?= =?UTF-8?q?=C3=AD=20nikdy=20nem=C4=9Bl=20m=C3=ADt=20v=C3=ADce=20ne=C5=BE?= =?UTF-8?q?=201=20scale,=20pro=C4=8D=20se=20s=20n=C3=ADm=20po=C4=8D=C3=ADt?= =?UTF-8?q?alo=20v=20origin=C3=A1lu=20funkce=3F=20-=20m=C5=AFj=20vstup=20(?= =?UTF-8?q?Model::model=5Fxf=5FTest)=20z=C5=AFst=C3=A1v=C3=A1=20jak=20je?= =?UTF-8?q?=20ve=20form=C3=A1tu=202=20dimenzov=C3=A9ho=20a=20n-kan=C3=A1lo?= =?UTF-8?q?v=C3=A9ho=20cv::Mat=20-=20xf=5Fsqr=5Fnorm=5FTest=20a=20yf=5Fsqr?= =?UTF-8?q?=5Fnorm=5FTest=20t=C5=99=C3=ADdy=20GaussianCorrelation=20jsou?= =?UTF-8?q?=20od=20te=C4=8F=20float,=20na=20m=C3=ADsto=20std::vector?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- src/kcf.cpp | 27 ++++++++++++--------------- src/kcf.h | 6 ++---- src/matutil.h | 26 ++++++++++++-------------- 3 files changed, 26 insertions(+), 33 deletions(-) diff --git a/src/kcf.cpp b/src/kcf.cpp index 798a389b..0cebefdb 100644 --- a/src/kcf.cpp +++ b/src/kcf.cpp @@ -874,19 +874,16 @@ void KCF_Tracker::GaussianCorrelation::operator()(cv::Mat &result, cv::Mat &xf, { TRACE(""); DEBUG_PRINTM(xf); - DEBUG_PRINT(xf_sqr_norm_Test.size()); MatUtil::sqr_norm(xf, xf_sqr_norm_Test); + DEBUG_PRINT(xf_sqr_norm_Test); - for (uint s = 0; s < xf_sqr_norm_Test.size(); ++s) - DEBUG_PRINT(xf_sqr_norm_Test.at(s)); if (auto_correlation) { yf_sqr_norm_Test = xf_sqr_norm_Test; } else { DEBUG_PRINTM(yf); MatUtil::sqr_norm(yf, yf_sqr_norm_Test); } - for (uint s = 0; s < yf_sqr_norm_Test.size(); ++s) - DEBUG_PRINTM(yf_sqr_norm_Test.at(s)); + DEBUG_PRINT(yf_sqr_norm_Test); cv::Mat conjMat = MatUtil::conj(yf); xyf_Test = auto_correlation ? MatUtil::sqr_mag(xf) : MatUtil::mul_matn_matn(xf, conjMat); // xf.muln(yf.conj()); @@ -898,16 +895,16 @@ void KCF_Tracker::GaussianCorrelation::operator()(cv::Mat &result, cv::Mat &xf, kcf.fft.inverse(xyf_sum, ifft_res_Test); DEBUG_PRINTM(ifft_res_Test); - float numel_xf_inv = 1.f / (xf.cols * xf.rows * (xf.channels() / 2)); -// for (uint i = 0; i < xf.n_scales; ++i) { - cv::Mat plane = MatUtil::plane(0,ifft_res_Test); - DEBUG_PRINTM(plane); - cv::exp(-1. / (sigma * sigma) * cv::max((xf_sqr_norm[0] + yf_sqr_norm[0] - 2 * MatUtil::plane(0,ifft_res_Test)) - * numel_xf_inv, 0), plane); - DEBUG_PRINTM(plane); -// } - - kcf.fft.forward(ifft_res_Test, result); +// float numel_xf_inv = 1.f / (xf.cols * xf.rows * (xf.channels() / 2)); +//// for (uint i = 0; i < xf.n_scales; ++i) { +// cv::Mat plane = MatUtil::plane(0,ifft_res_Test); +// DEBUG_PRINTM(plane); +// cv::exp(-1. / (sigma * sigma) * cv::max((xf_sqr_norm[0] + yf_sqr_norm[0] - 2 * MatUtil::plane(0,ifft_res_Test)) +// * numel_xf_inv, 0), plane); +// DEBUG_PRINTM(plane); +//// } +// +// kcf.fft.forward(ifft_res_Test, result); } float get_response_circular(cv::Point2i &pt, cv::Mat &response) diff --git a/src/kcf.h b/src/kcf.h index c00ebf3e..127da834 100644 --- a/src/kcf.h +++ b/src/kcf.h @@ -176,8 +176,6 @@ class KCF_Tracker , ifft_res(num_scales, size) , k(num_scales, size) { - xf_sqr_norm_Test.reserve(num_scales); - yf_sqr_norm_Test.reserve(1); cv::Size temp = Fft::freq_size(size); xyf_Test = cv::Mat(3, std::vector({(int) num_scales, temp.height, temp.width}).data(), CV_32FC(num_feats*2)); ifft_res_Test = cv::Mat(3, std::vector({(int) num_scales, size.height, size.width}).data(), CV_32F); @@ -193,8 +191,8 @@ class KCF_Tracker MatScales ifft_res; MatScales k; - std::vector xf_sqr_norm_Test = std::vector(); - std::vector yf_sqr_norm_Test = std::vector(); + float xf_sqr_norm_Test; + float yf_sqr_norm_Test; cv::Mat xyf_Test; cv::Mat ifft_res_Test; cv::Mat k_Test; diff --git a/src/matutil.h b/src/matutil.h index f27508fc..40ee84aa 100644 --- a/src/matutil.h +++ b/src/matutil.h @@ -4,7 +4,7 @@ #include #include - +#include "debug.h" class MatUtil{ public: @@ -57,23 +57,21 @@ static void set_channel(int idxFrom, int idxTo, cv::Mat &source, cv::Mat &target /* * Computes sum of results from formula ((real)^2 + (imag)^2) - * for every complex element in a scale of the matrix. + * for every complex element of the input matrix. * This is repeated for every scale, and the results are appended into result vector. **/ -static void sqr_norm(const cv::Mat &host, std::vector &result) +static void sqr_norm(const cv::Mat &host, float &result) { assert(host.channels() % 2 == 0); - for (int scale = 0; scale < host.size[0]; ++scale) { - float sum_sqr_norm = 0; - - for (int row = 0; row < host.size[1]; ++row) - for (int col = 0; col < host.size[2]; ++col) - for (int ch = 0; ch < host.channels() / 2; ++ch){ - std::complex cpxVal = host.ptr>(scale,row)[(host.channels() / 2)*col + ch]; - sum_sqr_norm += cpxVal.real() * cpxVal.real() + cpxVal.imag() * cpxVal.imag(); - } - result.push_back(sum_sqr_norm / static_cast(host.size[1] * host.size[2])); - } + float sum_sqr_norm = 0; + + for (int row = 0; row < host.rows; ++row) + for (int col = 0; col < host.cols; ++col) + for (int ch = 0; ch < host.channels() / 2; ++ch){ + std::complex cpxVal = host.ptr>(row)[(host.channels() / 2)*col + ch]; + sum_sqr_norm += cpxVal.real() * cpxVal.real() + cpxVal.imag() * cpxVal.imag(); + } + result = sum_sqr_norm / static_cast(host.rows * host.cols); } /* From 1fdc34c645bef8f544ce160d045117c45fe1d9ce Mon Sep 17 00:00:00 2001 From: Your Name Date: Sun, 29 Dec 2019 20:53:19 +0100 Subject: [PATCH 038/121] =?UTF-8?q?Opravena=20chyba=20sum=5Fover=5Fchannel?= =?UTF-8?q?s()=20-=20podobn=C3=A1=20chyba=20jako=20u=20sqr=5Fnorm(),=20vst?= =?UTF-8?q?up=20nikdy=20nem=C4=9Bl=20obsahovat=20scale=20-=20v=20tomto=20p?= =?UTF-8?q?=C5=99=C3=ADpad=C4=9B=20sta=C4=8Dilo=20upravit=20funkci?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- src/fft_opencv.cpp | 7 +++---- src/matutil.h | 19 ++++++++----------- 2 files changed, 11 insertions(+), 15 deletions(-) diff --git a/src/fft_opencv.cpp b/src/fft_opencv.cpp index eb486dec..2f637201 100644 --- a/src/fft_opencv.cpp +++ b/src/fft_opencv.cpp @@ -78,10 +78,9 @@ void FftOpencv::inverse(cv::Mat &complex_input, cv::Mat &real_result) //Fft::inverse(complex_input, real_result); assert(complex_input.channels() % 2 == 0); - cv::Mat source = MatUtil::plane(0, complex_input); // seems like only first dimension is relevant - for (uint i = 0; i < uint(source.channels() / 2); ++i) { - cv::Mat inputChannel = MatUtil::channel_to_cv_mat(i*2, source); // extract channel matrix - cv::Mat target = MatUtil::plane(i, real_result); // select output plane + for (uint i = 0; i < uint(complex_input.channels() / 2); ++i) { + cv::Mat inputChannel = MatUtil::channel_to_cv_mat(i*2, complex_input); // extract input channel matrix + cv::Mat target = MatUtil::plane(i, real_result); // select output plane cv::dft(inputChannel, target, cv::DFT_INVERSE | cv::DFT_REAL_OUTPUT | cv::DFT_SCALE); } } diff --git a/src/matutil.h b/src/matutil.h index 40ee84aa..8ef6cdd7 100644 --- a/src/matutil.h +++ b/src/matutil.h @@ -82,18 +82,15 @@ static void sqr_norm(const cv::Mat &host, float &result) static cv::Mat sum_over_channels(cv::Mat &host) { assert(host.channels() % 2 == 0); - - cv::Mat result(3, std::vector({(int) host.size[0], host.size[1], host.size[2]}).data(), CV_32FC2); - for (int scale = 0; scale < host.size[0]; ++scale) { - for (int row = 0; row < host.size[1]; ++row) - for (int col = 0; col < host.size[2]; ++col){ - std::complex acc = 0; - for (int ch = 0; ch < host.channels() / 2; ++ch){ - acc += host.ptr>(scale,row)[(host.channels() / 2)*col + ch]; - } - result.ptr>(scale,row)[col] = acc; + cv::Mat result(host.rows, host.cols, CV_32FC2); + for (int row = 0; row < host.rows; ++row) + for (int col = 0; col < host.cols; ++col){ + std::complex acc = 0; + for (int ch = 0; ch < host.channels() / 2; ++ch){ + acc += host.ptr>(row)[(host.channels() / 2)*col + ch]; } - } + result.ptr>(row)[col] = acc; + } return result; } From b503664f5bc08d43f60e824f264f8ae486d245db Mon Sep 17 00:00:00 2001 From: Your Name Date: Sun, 29 Dec 2019 21:59:59 +0100 Subject: [PATCH 039/121] =?UTF-8?q?Opravena=20chyba=20GaussianCorrelation:?= =?UTF-8?q?:operator()=20-=20jako=20vstup=20fft::forward=20byla=20po=C5=BE?= =?UTF-8?q?adov=C3=A1n=203=20dimenzion=C3=A1ln=C3=AD=20matice,=20co=C5=BE?= =?UTF-8?q?=20bylo=20u=20nov=C3=A9=20funkce=20smaz=C3=A1no=20-=20nov=C3=A1?= =?UTF-8?q?=20verze=20GaussianCorrelation::operator()=20je=20v=20tuto=20ch?= =?UTF-8?q?v=C3=ADli=20spustiteln=C3=A1,=20ale=20jen=20nap=C5=AFl=20funk?= =?UTF-8?q?=C4=8Dn=C3=AD=20(je=20t=C5=99eba=20je=C5=A1t=C4=9B=20doladit)?= =?UTF-8?q?=20-=20sqr=5Fnorm()=20vrac=C3=AD=20z=20n=C4=9Bjak=C3=A9ho=20d?= =?UTF-8?q?=C5=AFvodu=20NaN=20po=20dokon=C4=8Den=C3=AD=20n=C4=9Bkolika=20f?= =?UTF-8?q?or-loop,=20je=20t=C5=99eba=20zjistit=20pro=C4=8D=20(ale=20od=20?= =?UTF-8?q?origin=C3=A1lu=20se=20moc=20neli=C5=A1=C3=AD)?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- src/kcf.cpp | 24 ++++++++++++------------ src/matutil.h | 11 +++++++---- 2 files changed, 19 insertions(+), 16 deletions(-) diff --git a/src/kcf.cpp b/src/kcf.cpp index 0cebefdb..6bdc992f 100644 --- a/src/kcf.cpp +++ b/src/kcf.cpp @@ -874,14 +874,14 @@ void KCF_Tracker::GaussianCorrelation::operator()(cv::Mat &result, cv::Mat &xf, { TRACE(""); DEBUG_PRINTM(xf); - MatUtil::sqr_norm(xf, xf_sqr_norm_Test); + xf_sqr_norm_Test = MatUtil::sqr_norm(xf); DEBUG_PRINT(xf_sqr_norm_Test); if (auto_correlation) { yf_sqr_norm_Test = xf_sqr_norm_Test; } else { DEBUG_PRINTM(yf); - MatUtil::sqr_norm(yf, yf_sqr_norm_Test); + yf_sqr_norm_Test = MatUtil::sqr_norm(yf); } DEBUG_PRINT(yf_sqr_norm_Test); @@ -895,16 +895,16 @@ void KCF_Tracker::GaussianCorrelation::operator()(cv::Mat &result, cv::Mat &xf, kcf.fft.inverse(xyf_sum, ifft_res_Test); DEBUG_PRINTM(ifft_res_Test); -// float numel_xf_inv = 1.f / (xf.cols * xf.rows * (xf.channels() / 2)); -//// for (uint i = 0; i < xf.n_scales; ++i) { -// cv::Mat plane = MatUtil::plane(0,ifft_res_Test); -// DEBUG_PRINTM(plane); -// cv::exp(-1. / (sigma * sigma) * cv::max((xf_sqr_norm[0] + yf_sqr_norm[0] - 2 * MatUtil::plane(0,ifft_res_Test)) -// * numel_xf_inv, 0), plane); -// DEBUG_PRINTM(plane); -//// } -// -// kcf.fft.forward(ifft_res_Test, result); + float numel_xf_inv = 1.f / (xf.cols * xf.rows * (xf.channels() / 2)); +// for (uint i = 0; i < xf.n_scales; ++i) { + cv::Mat plane = MatUtil::plane(0,ifft_res_Test); + DEBUG_PRINTM(plane); + cv::exp(-1. / (sigma * sigma) * cv::max((xf_sqr_norm[0] + yf_sqr_norm[0] - 2 * MatUtil::plane(0,ifft_res_Test)) + * numel_xf_inv, 0), plane); + DEBUG_PRINTM(plane); +// } + + kcf.fft.forward(MatUtil::plane(0,ifft_res_Test), result); } float get_response_circular(cv::Point2i &pt, cv::Mat &response) diff --git a/src/matutil.h b/src/matutil.h index 8ef6cdd7..6b491651 100644 --- a/src/matutil.h +++ b/src/matutil.h @@ -60,18 +60,21 @@ static void set_channel(int idxFrom, int idxTo, cv::Mat &source, cv::Mat &target * for every complex element of the input matrix. * This is repeated for every scale, and the results are appended into result vector. **/ -static void sqr_norm(const cv::Mat &host, float &result) +static float sqr_norm(const cv::Mat &host) { assert(host.channels() % 2 == 0); float sum_sqr_norm = 0; - for (int row = 0; row < host.rows; ++row) - for (int col = 0; col < host.cols; ++col) + for (int row = 0; row < host.rows; ++row){ + for (int col = 0; col < host.cols; ++col){ for (int ch = 0; ch < host.channels() / 2; ++ch){ std::complex cpxVal = host.ptr>(row)[(host.channels() / 2)*col + ch]; sum_sqr_norm += cpxVal.real() * cpxVal.real() + cpxVal.imag() * cpxVal.imag(); } - result = sum_sqr_norm / static_cast(host.rows * host.cols); + } + } + sum_sqr_norm = sum_sqr_norm / static_cast(host.rows * host.cols); + return sum_sqr_norm; } /* From 058ceea9283e61395a4c4283236a530c95bf7677 Mon Sep 17 00:00:00 2001 From: Your Name Date: Mon, 30 Dec 2019 21:26:13 +0100 Subject: [PATCH 040/121] =?UTF-8?q?Opravena=20chyba=20referenc=C3=AD=20v?= =?UTF-8?q?=20MatUtil=20-=20Maticov=C3=A9=20operace=20pracovaly=20p=C5=99?= =?UTF-8?q?=C3=ADmo=20s=20daty=20zdroje,=20m=C3=ADsto=20aby=20vytvo=C5=99i?= =?UTF-8?q?ly=20klon=20dat?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- src/matutil.h | 59 ++++++++++++++++++++++++++------------------------- 1 file changed, 30 insertions(+), 29 deletions(-) diff --git a/src/matutil.h b/src/matutil.h index 6b491651..9f34809e 100644 --- a/src/matutil.h +++ b/src/matutil.h @@ -112,77 +112,78 @@ static cv::Mat channel_to_cv_mat(int channel_id, cv::Mat &host){ static cv::Mat sqr_mag(cv::Mat &host){ - mat_const_operator([](std::complex &c) { c = c.real() * c.real() + c.imag() * c.imag(); }, host); - return host; + return mat_const_operator([](std::complex &c) { c = c.real() * c.real() + c.imag() * c.imag(); }, host); } static cv::Mat conj(cv::Mat &host){ - mat_const_operator([](std::complex &c) { c = std::complex(c.real(), -c.imag()); }, host); - return host; + return mat_const_operator([](std::complex &c) { c = std::complex(c.real(), -c.imag()); }, host); } static cv::Mat mul_matn_mat1(cv::Mat &host, cv::Mat &other){ - matn_mat1_operator([](std::complex &c_lhs, const std::complex &c_rhs) { c_lhs *= c_rhs; }, host, other); - return host; + return matn_mat1_operator([](std::complex &c_lhs, const std::complex &c_rhs) { c_lhs *= c_rhs; }, host, other); } static cv::Mat mul_matn_matn(cv::Mat &host, cv::Mat &other){ - mat_mat_operator([](std::complex &c_lhs, const std::complex &c_rhs) { c_lhs *= c_rhs; }, host, other); - return host; + return mat_mat_operator([](std::complex &c_lhs, const std::complex &c_rhs) { c_lhs *= c_rhs; }, host, other); } static cv::Mat add_scalar(cv::Mat &host, const float &val){ - mat_const_operator([&val](std::complex &c) { c += val; }, host); - return host; + return mat_const_operator([&val](std::complex &c) { c += val; }, host); } -static void mat_const_operator(const std::function &)> &op, cv::Mat &host){ +static cv::Mat mat_const_operator(const std::function &)> &op, cv::Mat &host){ assert(host.channels() % 2 == 0); - for (int i = 0; i < host.rows; ++i) { - for (int j = 0; j < host.cols; ++j){ - for (int k = 0; k < host.channels() / 2 ; ++k){ - std::complex cpxVal = host.ptr>(i)[(host.channels() / 2)*j + k]; + cv::Mat result = host.clone(); + for (int i = 0; i < result.rows; ++i) { + for (int j = 0; j < result.cols; ++j){ + for (int k = 0; k < result.channels() / 2 ; ++k){ + std::complex cpxVal = result.ptr>(i)[(result.channels() / 2)*j + k]; op(cpxVal); - host.ptr>(i)[(host.channels() / 2)*j + k] = cpxVal; + result.ptr>(i)[(result.channels() / 2)*j + k] = cpxVal; } } } + return result; } -static void matn_mat1_operator(void (*op)(std::complex &, const std::complex &), cv::Mat &host, cv::Mat &other){ +static cv::Mat matn_mat1_operator(void (*op)(std::complex &, const std::complex &), cv::Mat &host, cv::Mat &other){ assert(host.channels() % 2 == 0); assert(other.channels() == 2); assert(other.cols == host.cols); assert(other.rows == host.rows); - for (int i = 0; i < host.rows; ++i) { - for (int j = 0; j < host.cols; ++j){ - std::complex cpxValOther = other.ptr>(i)[j]; - for (int k = 0; k < host.channels() / 2 ; ++k){ - std::complex cpxValHost = host.ptr>(i)[(host.channels() / 2)*j + k]; + cv::Mat result = host.clone(); + for (int i = 0; i < result.rows; ++i) { + for (int j = 0; j < result.cols; ++j){ + for (int k = 0; k < result.channels() / 2 ; ++k){ + std::complex cpxValOther = other.ptr>(i)[j]; + std::complex cpxValHost = result.ptr>(i)[(result.channels() / 2)*j + k]; op(cpxValHost, cpxValOther); - host.ptr>(i)[(host.channels() / 2)*j + k] = cpxValHost; + result.ptr>(i)[(result.channels() / 2)*j + k] = cpxValHost; } } } + return result; } -static void mat_mat_operator(void (*op)(std::complex &, const std::complex &), cv::Mat &host, cv::Mat &other){ +static cv::Mat mat_mat_operator(void (*op)(std::complex &, const std::complex &), cv::Mat &host, cv::Mat &other){ assert(host.channels() % 2 == 0); assert(other.channels() == host.channels()); assert(other.cols == host.cols); assert(other.rows == host.rows); - for (int i = 0; i < host.rows; ++i) { - for (int j = 0; j < host.cols; ++j){ - for (int k = 0; k < host.channels() / 2 ; ++k){ - std::complex cpxValHost = host.ptr>(i)[(host.channels() / 2)*j + k]; + cv::Mat result = host.clone(); + for (int i = 0; i < result.rows; ++i) { + for (int j = 0; j < result.cols; ++j){ + for (int k = 0; k < result.channels() / 2 ; ++k){ + std::complex cpxValHost = result.ptr>(i)[(result.channels() / 2)*j + k]; std::complex cpxValOther = other.ptr>(i)[(other.channels() / 2)*j + k]; op(cpxValHost, cpxValOther); - host.ptr>(i)[(host.channels() / 2)*j + k] = cpxValHost; + result.ptr>(i)[(result.channels() / 2)*j + k] = cpxValHost; } } } + return result; } From 890dfb754eadfe06c2f86ce9aaaaf8162e88ec35 Mon Sep 17 00:00:00 2001 From: Your Name Date: Mon, 30 Dec 2019 21:38:40 +0100 Subject: [PATCH 041/121] =?UTF-8?q?Dolad=C4=9Bna=20=C3=BAprava=20pro=20p?= =?UTF-8?q?=C5=99ep=C3=ADna=C4=8D=20m=5Fuse=5Flinearkernel=20ve=20funkci?= =?UTF-8?q?=20train()=20-=20sou=C4=8D=C3=A1st=C3=AD=20toho=20byl=20p=C5=99?= =?UTF-8?q?edchoz=C3=AD=20commit=20pro=20opravu=20referenc=C3=AD=20v=20Mat?= =?UTF-8?q?Util?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit - originální kód v tomto přepínači způsobuje chybu, neprochází assert na počet num_elem ve funkci void DynMem::operator=(DynMem_ &&rhs) - chyba způsoba rozdílným počtem kanálů mezi proměnnou model_alfaf_num a výsledkem xf.conj() - chybový kód byl zakomentován --- src/kcf.cpp | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) diff --git a/src/kcf.cpp b/src/kcf.cpp index 6bdc992f..c4ee73cb 100644 --- a/src/kcf.cpp +++ b/src/kcf.cpp @@ -95,9 +95,9 @@ void KCF_Tracker::train(cv::Mat input_rgb, cv::Mat input_gray, double interp_fac DEBUG_PRINTM(model->model_xf_Test); if (m_use_linearkernel) { - ComplexMat xfconj = model->xf.conj(); - model->model_alphaf_num = xfconj.mul(model->yf); - model->model_alphaf_den = (model->xf * xfconj); +// ComplexMat xfconj = model->xf.conj(); +// model->model_alphaf_num = xfconj.mul(model->yf); +// model->model_alphaf_den = (model->xf * xfconj); cv::Mat xfconj_Test = MatUtil::conj(model->xf_Test); model->model_alphaf_num_Test = MatUtil::mul_matn_mat1(xfconj_Test, model->yf_Test); From a229062312d0c048d84a45308e584824b88f1892 Mon Sep 17 00:00:00 2001 From: Your Name Date: Mon, 30 Dec 2019 21:52:03 +0100 Subject: [PATCH 042/121] =?UTF-8?q?P=C5=99id=C3=A1na=20funkce=20divide=5Fm?= =?UTF-8?q?atn=5Fmatn()=20pro=20d=C4=9Blen=C3=AD=20mezi=20maticemi=20do=20?= =?UTF-8?q?MatUtil?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- src/matutil.h | 4 ++++ 1 file changed, 4 insertions(+) diff --git a/src/matutil.h b/src/matutil.h index 9f34809e..97157a29 100644 --- a/src/matutil.h +++ b/src/matutil.h @@ -131,6 +131,10 @@ static cv::Mat add_scalar(cv::Mat &host, const float &val){ return mat_const_operator([&val](std::complex &c) { c += val; }, host); } +static cv::Mat divide_matn_matn(cv::Mat &host, cv::Mat &other){ + return mat_mat_operator([](std::complex &c_lhs, const std::complex &c_rhs) { c_lhs /= c_rhs; }, host, other); +} + static cv::Mat mat_const_operator(const std::function &)> &op, cv::Mat &host){ assert(host.channels() % 2 == 0); cv::Mat result = host.clone(); From 372f50553565d9e52c7eab1180b04e6a5ec7bf23 Mon Sep 17 00:00:00 2001 From: Your Name Date: Mon, 30 Dec 2019 22:27:07 +0100 Subject: [PATCH 043/121] =?UTF-8?q?Dolad=C4=9Bna=20funkce=20train()=20-=20?= =?UTF-8?q?v=C5=A1e=20otestov=C3=A1no,=20pouze=20se=20vyskytuje=20chyba=20?= =?UTF-8?q?ve=20funkci=20sqr=5Fnorm()=20-=20sqr=5Fnorm()=20vyd=C3=A1v?= =?UTF-8?q?=C3=A1=20jako=20v=C3=BDsledek=20NaN,=20ale=20po=20restartu=20po?= =?UTF-8?q?=C4=8D=C3=ADta=C4=8De=20vydal=20stejnou=20hodnotu=20jako=20orig?= =?UTF-8?q?in=C3=A1ln=C3=AD=20k=C3=B3d?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit - pokud sqr_norm() zrovna funguje, všechen průběh až do konce train() je otestován jak shodný s originálem - následujcím a posledním krokem pro dokončení konverze na cv::Mat je upravení obou funkcí track() --- src/kcf.cpp | 2 ++ 1 file changed, 2 insertions(+) diff --git a/src/kcf.cpp b/src/kcf.cpp index c4ee73cb..2da4dd63 100644 --- a/src/kcf.cpp +++ b/src/kcf.cpp @@ -120,7 +120,9 @@ void KCF_Tracker::train(cv::Mat input_rgb, cv::Mat input_gray, double interp_fac model->model_alphaf_den_Test = MatUtil::mul_matn_matn(kf_Test, addedMat); } model->model_alphaf = model->model_alphaf_num / model->model_alphaf_den; + model->model_alphaf_Test = MatUtil::divide_matn_matn(model->model_alphaf_num_Test, model->model_alphaf_den_Test); DEBUG_PRINTM(model->model_alphaf); + DEBUG_PRINTM(model->model_alphaf_Test); // p_model_alphaf = p_yf / (kf + p_lambda); //equation for fast training } From 26220e73769b7af20a65dadc12487733adff9918 Mon Sep 17 00:00:00 2001 From: Your Name Date: Thu, 2 Jan 2020 19:34:59 +0100 Subject: [PATCH 044/121] =?UTF-8?q?Vy=C5=99e=C5=A1ena=20chyba=20sqr=5Fnorm?= =?UTF-8?q?()=20-=20ve=20skute=C4=8Dnosti=20chyba=20inicializace=20cv::Mat?= =?UTF-8?q?=20prom=C4=9Bnn=C3=BDch,=20v=C3=BDchoz=C3=AD=20stav=20obsahoval?= =?UTF-8?q?=20drobn=C3=A9=20n=C3=A1hodn=C3=A9=20hodnoty=20-=20cv::Mat=20js?= =?UTF-8?q?ou=20te=C4=8F=20explicitn=C4=9B=20inicializov=C3=A1ny=20v=20nul?= =?UTF-8?q?ov=C3=A9m=20stavu?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- src/kcf.h | 12 ++++++------ 1 file changed, 6 insertions(+), 6 deletions(-) diff --git a/src/kcf.h b/src/kcf.h index 127da834..397a27e5 100644 --- a/src/kcf.h +++ b/src/kcf.h @@ -148,12 +148,12 @@ class KCF_Tracker // FORMER ATTRIBUTES CONVERTED TO cv::Mat // Complex matrix now equals 2*k channels matrix by design - cv::Mat yf_Test {(int) height, (int) width, CV_32FC2}; - cv::Mat model_alphaf_Test {(int) height, (int) width, CV_32FC2}; - cv::Mat model_alphaf_num_Test {(int) height, (int) width, CV_32FC2}; - cv::Mat model_alphaf_den_Test {(int) height, (int) width, CV_32FC2}; - cv::Mat model_xf_Test {(int) height, (int) width, CV_32FC(n_feats*2)}; - cv::Mat xf_Test {(int) height, (int) width, CV_32FC(n_feats*2)}; + cv::Mat yf_Test = cv::Mat::zeros((int) height, (int) width, CV_32FC2); + cv::Mat model_alphaf_Test = cv::Mat::zeros((int) height, (int) width, CV_32FC2); + cv::Mat model_alphaf_num_Test = cv::Mat::zeros((int) height, (int) width, CV_32FC2); + cv::Mat model_alphaf_den_Test = cv::Mat::zeros((int) height, (int) width, CV_32FC2); + cv::Mat model_xf_Test = cv::Mat::zeros((int) height, (int) width, CV_32FC(n_feats*2)); + cv::Mat xf_Test = cv::Mat::zeros((int) height, (int) width, CV_32FC(n_feats*2)); cv::Mat patch_feats_Test{ 4, std::vector({1, int(n_feats), feature_size.height, feature_size.width}).data(), CV_32F}; cv::Mat temp_Test{ 4, std::vector({1, int(n_feats), feature_size.height, feature_size.width}).data(), CV_32F}; From 20185cecf63053ea02bb2ff998fb08d44a6a3032 Mon Sep 17 00:00:00 2001 From: Your Name Date: Thu, 2 Jan 2020 19:57:53 +0100 Subject: [PATCH 045/121] =?UTF-8?q?P=C5=99id=C3=A1ny=20placeholdery=20pro?= =?UTF-8?q?=20fft=5Ffftw=20metody?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- src/fft_fftw.cpp | 59 ++++++++++++++++++++++++++++++++++++++++++++++++ src/fft_fftw.h | 3 +++ 2 files changed, 62 insertions(+) diff --git a/src/fft_fftw.cpp b/src/fft_fftw.cpp index 1d26269b..5f49c711 100644 --- a/src/fft_fftw.cpp +++ b/src/fft_fftw.cpp @@ -91,6 +91,21 @@ void Fftw::forward(const MatScales &real_input, ComplexMat &complex_result) #endif } +// REPLACEMENT +void Fftw::forward(cv::Mat &real_input, cv::Mat &complex_result) +{ +// Fft::forward(real_input, complex_result); +// +// if (real_input.size[0] == 1) +// fftwf_execute_dft_r2c(plan_f, reinterpret_cast(real_input.data), +// reinterpret_cast(complex_result.get_p_data())); +//#ifdef BIG_BATCH +// else +// fftwf_execute_dft_r2c(plan_f_all_scales, reinterpret_cast(real_input.data), +// reinterpret_cast(complex_result.get_p_data())); +//#endif +} + void Fftw::forward_window(MatScaleFeats &feat, ComplexMat & complex_result, MatScaleFeats &temp) { Fft::forward_window(feat, complex_result, temp); @@ -115,6 +130,32 @@ void Fftw::forward_window(MatScaleFeats &feat, ComplexMat & complex_result, Mat #endif } +// REPLACEMENT +void Fftw::forward_window(cv::Mat &feat, cv::Mat & complex_result, cv::Mat &temp) +{ +// Fft::forward_window(feat, complex_result, temp); +// +// uint n_scales = feat.size[0]; +// for (uint s = 0; s < n_scales; ++s) { +// for (uint ch = 0; ch < uint(feat.size[1]); ++ch) { +// cv::Mat feat_plane = feat.plane(s, ch); +// cv::Mat temp_plane = temp.plane(s, ch); +// temp_plane = feat_plane.mul(m_window); +// } +// } +// +// float *in = temp.ptr(); +// fftwf_complex *out = reinterpret_cast(complex_result.get_p_data()); +// +// if (n_scales == 1) +// fftwf_execute_dft_r2c(plan_fw, in, out); +//#ifdef BIG_BATCH +// else +// fftwf_execute_dft_r2c(plan_fw_all_scales, in, out); +//#endif +} + + void Fftw::inverse(ComplexMat &complex_input, MatScales &real_result) { Fft::inverse(complex_input, real_result); @@ -132,6 +173,24 @@ void Fftw::inverse(ComplexMat &complex_input, MatScales &real_result) real_result *= 1.0 / (m_width * m_height); } +// REPLACEMENT +void Fftw::inverse(cv::Mat &complex_input, cv::Mat &real_result) +{ +// Fft::inverse(complex_input, real_result); +// +// int n_channels = complex_input.n_channels; +// fftwf_complex *in = reinterpret_cast(complex_input.get_p_data()); +// float *out = real_result.ptr(); +// +// if (n_channels == 1) +// fftwf_execute_dft_c2r(plan_i_1ch, in, out); +//#ifdef BIG_BATCH +// else +// fftwf_execute_dft_c2r(plan_i_all_scales, in, out); +//#endif +// real_result *= 1.0 / (m_width * m_height); +} + Fftw::~Fftw() { if (plan_f) fftwf_destroy_plan(plan_f); diff --git a/src/fft_fftw.h b/src/fft_fftw.h index 1137c6f9..f943830e 100644 --- a/src/fft_fftw.h +++ b/src/fft_fftw.h @@ -16,8 +16,11 @@ class Fftw : public Fft void init(unsigned width, unsigned height, unsigned num_of_feats, unsigned num_of_scales); void set_window(const MatDynMem &window); void forward(const MatScales &real_input, ComplexMat &complex_result); + void forward(cv::Mat &real_input, cv::Mat &complex_result); void forward_window(MatScaleFeats &patch_feats_in, ComplexMat &complex_result, MatScaleFeats &tmp); + void forward_window(cv::Mat &feat, cv::Mat & complex_result, cv::Mat &temp); void inverse(ComplexMat &complex_input, MatScales &real_result); + void inverse(cv::Mat &complex_input, cv::Mat &real_result); ~Fftw(); protected: From a0aae9f96d2c6f149fc356d1dd0b879a0b2c682e Mon Sep 17 00:00:00 2001 From: Your Name Date: Thu, 2 Jan 2020 20:42:24 +0100 Subject: [PATCH 046/121] =?UTF-8?q?P=C5=99id=C3=A1ny=20placeholdery=20pro?= =?UTF-8?q?=20fft=5Fcufft=20metody=20-=20opravena=20hlavi=C4=8Dka=20funkce?= =?UTF-8?q?=20forward()?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- src/fft_cufft.cpp | 60 +++++++++++++++++++++++++++++++++++++++++++++++ src/fft_cufft.h | 3 +++ src/fft_fftw.cpp | 2 +- src/fft_fftw.h | 2 +- 4 files changed, 65 insertions(+), 2 deletions(-) diff --git a/src/fft_cufft.cpp b/src/fft_cufft.cpp index 5c0da667..2993772c 100644 --- a/src/fft_cufft.cpp +++ b/src/fft_cufft.cpp @@ -72,6 +72,20 @@ void cuFFT::forward(const MatScales &real_input, ComplexMat &complex_result) #endif } +// REPLACEMENT +void cuFFT::forward(const cv::Mat &real_input, cv::Mat &complex_result) +{ +// Fft::forward(real_input, complex_result); +// auto in = static_cast(const_cast(real_input).deviceMem()); +// +// if (real_input.size[0] == 1) +// cudaErrorCheck(cufftExecR2C(plan_f, in, complex_result.get_dev_data())); +//#ifdef BIG_BATCH +// else +// cudaErrorCheck(cufftExecR2C(plan_f_all_scales, in, complex_result.get_dev_data())); +//#endif +} + void cuFFT::forward_window(MatScaleFeats &feat, ComplexMat &complex_result, MatScaleFeats &temp) { Fft::forward_window(feat, complex_result, temp); @@ -95,6 +109,30 @@ void cuFFT::forward_window(MatScaleFeats &feat, ComplexMat &complex_result, MatS #endif } +// REPLACEMENT +void cuFFT::forward_window(cv::Mat &feat, cv::Mat &complex_result, cv::Mat &temp) +{ +// Fft::forward_window(feat, complex_result, temp); +// +// cufftReal *temp_data = temp.deviceMem(); +// uint n_scales = feat.size[0]; +// +// for (uint s = 0; s < n_scales; ++s) { +// for (uint ch = 0; ch < uint(feat.size[1]); ++ch) { +// cv::Mat feat_plane = feat.plane(s, ch); +// cv::Mat temp_plane = temp.plane(s, ch); +// temp_plane = feat_plane.mul(m_window); +// } +// } +// +// if (n_scales == 1) +// cudaErrorCheck(cufftExecR2C(plan_fw, temp_data, complex_result.get_dev_data())); +//#ifdef BIG_BATCH +// else +// cudaErrorCheck(cufftExecR2C(plan_fw_all_scales, temp_data, complex_result.get_dev_data())); +//#endif +} + void cuFFT::inverse(ComplexMat &complex_input, MatScales &real_result) { Fft::inverse(complex_input, real_result); @@ -116,6 +154,28 @@ void cuFFT::inverse(ComplexMat &complex_input, MatScales &real_result) CudaSafeCall(cudaStreamSynchronize(cudaStreamPerThread)); } +// REPLACEMENT +void cuFFT::inverse(cv::Mat &complex_input, cv::Mat &real_result) +{ +// Fft::inverse(complex_input, real_result); +// +// uint n_channels = complex_input.n_channels; +// cufftComplex *in = reinterpret_cast(complex_input.get_dev_data()); +// cufftReal *out = real_result.deviceMem(); +// float alpha = 1.0 / (m_width * m_height); +// +// if (n_channels == 1) +// cudaErrorCheck(cufftExecC2R(plan_i_1ch, in, out)); +//#ifdef BIG_BATCH +// else +// cudaErrorCheck(cufftExecC2R(plan_i_all_scales, in, out)); +//#endif +// cudaErrorCheck(cublasSscal(cublas, real_result.total(), &alpha, out, 1)); +// // The result is a cv::Mat, which will be accesses by CPU, so we +// // must synchronize with the GPU here +// CudaSafeCall(cudaStreamSynchronize(cudaStreamPerThread)); +} + cuFFT::~cuFFT() { cudaErrorCheck(cublasDestroy(cublas)); diff --git a/src/fft_cufft.h b/src/fft_cufft.h index 4241c066..e194f11e 100644 --- a/src/fft_cufft.h +++ b/src/fft_cufft.h @@ -18,8 +18,11 @@ class cuFFT : public Fft void init(unsigned width, unsigned height, unsigned num_of_feats, unsigned num_of_scales); void set_window(const MatDynMem &window); void forward(const MatScales &real_input, ComplexMat &complex_result); + void forward(const cv::Mat &real_input, cv::Mat &complex_result); void forward_window(MatScaleFeats &patch_feats_in, ComplexMat &complex_result, MatScaleFeats &tmp); + void forward_window(cv::Mat &feat, cv::Mat &complex_result, cv::Mat &temp); void inverse(ComplexMat &complex_input, MatScales &real_result); + void inverse(cv::Mat &complex_input, cv::Mat &real_result); ~cuFFT(); protected: diff --git a/src/fft_fftw.cpp b/src/fft_fftw.cpp index 5f49c711..ad069ebe 100644 --- a/src/fft_fftw.cpp +++ b/src/fft_fftw.cpp @@ -92,7 +92,7 @@ void Fftw::forward(const MatScales &real_input, ComplexMat &complex_result) } // REPLACEMENT -void Fftw::forward(cv::Mat &real_input, cv::Mat &complex_result) +void Fftw::forward(const cv::Mat &real_input, cv::Mat &complex_result) { // Fft::forward(real_input, complex_result); // diff --git a/src/fft_fftw.h b/src/fft_fftw.h index f943830e..448989a2 100644 --- a/src/fft_fftw.h +++ b/src/fft_fftw.h @@ -16,7 +16,7 @@ class Fftw : public Fft void init(unsigned width, unsigned height, unsigned num_of_feats, unsigned num_of_scales); void set_window(const MatDynMem &window); void forward(const MatScales &real_input, ComplexMat &complex_result); - void forward(cv::Mat &real_input, cv::Mat &complex_result); + void forward(const cv::Mat &real_input, cv::Mat &complex_result); void forward_window(MatScaleFeats &patch_feats_in, ComplexMat &complex_result, MatScaleFeats &tmp); void forward_window(cv::Mat &feat, cv::Mat & complex_result, cv::Mat &temp); void inverse(ComplexMat &complex_input, MatScales &real_result); From cf8acaa6877f3e6a0fbd62035aa3a280f593db97 Mon Sep 17 00:00:00 2001 From: Your Name Date: Thu, 2 Jan 2020 21:35:05 +0100 Subject: [PATCH 047/121] =?UTF-8?q?Implementov=C3=A1ny=20fft=20funkce=20pr?= =?UTF-8?q?o=20fft=5Ffftw.cpp=20-=20uml=C4=8Deny=20warning=20v=20placehold?= =?UTF-8?q?eru=20cufft?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- src/fft_cufft.cpp | 7 +++++++ src/fft_fftw.cpp | 44 ++++++++++++++++++++++---------------------- 2 files changed, 29 insertions(+), 22 deletions(-) diff --git a/src/fft_cufft.cpp b/src/fft_cufft.cpp index 2993772c..fcf93f0e 100644 --- a/src/fft_cufft.cpp +++ b/src/fft_cufft.cpp @@ -75,6 +75,8 @@ void cuFFT::forward(const MatScales &real_input, ComplexMat &complex_result) // REPLACEMENT void cuFFT::forward(const cv::Mat &real_input, cv::Mat &complex_result) { + (void)real_input; + (void)complex_result; // Fft::forward(real_input, complex_result); // auto in = static_cast(const_cast(real_input).deviceMem()); // @@ -112,6 +114,9 @@ void cuFFT::forward_window(MatScaleFeats &feat, ComplexMat &complex_result, MatS // REPLACEMENT void cuFFT::forward_window(cv::Mat &feat, cv::Mat &complex_result, cv::Mat &temp) { + (void)feat; + (void)complex_result; + (void)temp; // Fft::forward_window(feat, complex_result, temp); // // cufftReal *temp_data = temp.deviceMem(); @@ -157,6 +162,8 @@ void cuFFT::inverse(ComplexMat &complex_input, MatScales &real_result) // REPLACEMENT void cuFFT::inverse(cv::Mat &complex_input, cv::Mat &real_result) { + (void)complex_input; + (void)real_result; // Fft::inverse(complex_input, real_result); // // uint n_channels = complex_input.n_channels; diff --git a/src/fft_fftw.cpp b/src/fft_fftw.cpp index ad069ebe..6dc71003 100644 --- a/src/fft_fftw.cpp +++ b/src/fft_fftw.cpp @@ -1,4 +1,5 @@ #include "fft_fftw.h" +#include "matutil.h" #include #ifdef OPENMP @@ -80,7 +81,7 @@ void Fftw::set_window(const MatDynMem &window) void Fftw::forward(const MatScales &real_input, ComplexMat &complex_result) { Fft::forward(real_input, complex_result); - + if (real_input.size[0] == 1) fftwf_execute_dft_r2c(plan_f, reinterpret_cast(real_input.data), reinterpret_cast(complex_result.get_p_data())); @@ -97,8 +98,8 @@ void Fftw::forward(const cv::Mat &real_input, cv::Mat &complex_result) // Fft::forward(real_input, complex_result); // // if (real_input.size[0] == 1) -// fftwf_execute_dft_r2c(plan_f, reinterpret_cast(real_input.data), -// reinterpret_cast(complex_result.get_p_data())); + fftwf_execute_dft_r2c(plan_f, reinterpret_cast(real_input.data), + reinterpret_cast(complex_result.ptr(0))); //#ifdef BIG_BATCH // else // fftwf_execute_dft_r2c(plan_f_all_scales, reinterpret_cast(real_input.data), @@ -134,21 +135,20 @@ void Fftw::forward_window(MatScaleFeats &feat, ComplexMat & complex_result, Mat void Fftw::forward_window(cv::Mat &feat, cv::Mat & complex_result, cv::Mat &temp) { // Fft::forward_window(feat, complex_result, temp); -// -// uint n_scales = feat.size[0]; -// for (uint s = 0; s < n_scales; ++s) { -// for (uint ch = 0; ch < uint(feat.size[1]); ++ch) { -// cv::Mat feat_plane = feat.plane(s, ch); -// cv::Mat temp_plane = temp.plane(s, ch); -// temp_plane = feat_plane.mul(m_window); -// } -// } -// -// float *in = temp.ptr(); -// fftwf_complex *out = reinterpret_cast(complex_result.get_p_data()); -// + + for (uint i = 0; i < uint(feat.size[0]); ++i) { + for (uint j = 0; j < uint(feat.size[1]); ++j) { + cv::Mat feat_plane = MatUtil::plane(i,j,feat); + cv::Mat temp_plane = MatUtil::plane(i,j,temp); + temp_plane = feat_plane.mul(m_window); + } + } + + float *in = temp.ptr(); + fftwf_complex *out = reinterpret_cast(complex_result.ptr(0)); + // if (n_scales == 1) -// fftwf_execute_dft_r2c(plan_fw, in, out); + fftwf_execute_dft_r2c(plan_fw, in, out); //#ifdef BIG_BATCH // else // fftwf_execute_dft_r2c(plan_fw_all_scales, in, out); @@ -179,16 +179,16 @@ void Fftw::inverse(cv::Mat &complex_input, cv::Mat &real_result) // Fft::inverse(complex_input, real_result); // // int n_channels = complex_input.n_channels; -// fftwf_complex *in = reinterpret_cast(complex_input.get_p_data()); -// float *out = real_result.ptr(); -// + fftwf_complex *in = reinterpret_cast(complex_result.ptr(0)); + float *out = real_result.ptr(); + // if (n_channels == 1) -// fftwf_execute_dft_c2r(plan_i_1ch, in, out); + fftwf_execute_dft_c2r(plan_i_1ch, in, out); //#ifdef BIG_BATCH // else // fftwf_execute_dft_c2r(plan_i_all_scales, in, out); //#endif -// real_result *= 1.0 / (m_width * m_height); + real_result *= 1.0 / (m_width * m_height); } Fftw::~Fftw() From a0a797907f81e16770a2a820d305f31393726282 Mon Sep 17 00:00:00 2001 From: Your Name Date: Thu, 2 Jan 2020 22:02:41 +0100 Subject: [PATCH 048/121] Opraven popisek funkce sum_over_channels --- src/matutil.h | 1 - 1 file changed, 1 deletion(-) diff --git a/src/matutil.h b/src/matutil.h index 97157a29..bb64349a 100644 --- a/src/matutil.h +++ b/src/matutil.h @@ -80,7 +80,6 @@ static float sqr_norm(const cv::Mat &host) /* * Sum of channel values for each point of input matrix * becomes a new point in the new matrix. - * Scales are saved separately in first dimension of new matrix. **/ static cv::Mat sum_over_channels(cv::Mat &host) { From fcf578d4dba33ce968f6549712e76689a68cac1c Mon Sep 17 00:00:00 2001 From: Your Name Date: Thu, 2 Jan 2020 22:04:18 +0100 Subject: [PATCH 049/121] Opraven popisek funkce sqr_norm --- src/matutil.h | 1 - 1 file changed, 1 deletion(-) diff --git a/src/matutil.h b/src/matutil.h index bb64349a..df31f836 100644 --- a/src/matutil.h +++ b/src/matutil.h @@ -58,7 +58,6 @@ static void set_channel(int idxFrom, int idxTo, cv::Mat &source, cv::Mat &target /* * Computes sum of results from formula ((real)^2 + (imag)^2) * for every complex element of the input matrix. - * This is repeated for every scale, and the results are appended into result vector. **/ static float sqr_norm(const cv::Mat &host) { From 0d50e87b59d0e63cc1a11f06f3e301594f1f518e Mon Sep 17 00:00:00 2001 From: Your Name Date: Thu, 2 Jan 2020 22:09:40 +0100 Subject: [PATCH 050/121] =?UTF-8?q?Opravena=20implementace=20fft=5Ffftw.cp?= =?UTF-8?q?p=20pro=20p=C5=99ep=C3=ADna=C4=8D=20BIG=5FBATCH=20-=20V=20tuto?= =?UTF-8?q?=20chv=C3=ADli=20by=20m=C4=9Bly=20b=C3=BDt=20v=C5=A1echny=20?= =?UTF-8?q?=C3=BApravy=20na=20tomto=20souboru=20hotov=C3=A9?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- src/fft_fftw.cpp | 35 +++++++++++++++++------------------ 1 file changed, 17 insertions(+), 18 deletions(-) diff --git a/src/fft_fftw.cpp b/src/fft_fftw.cpp index 6dc71003..86c306bb 100644 --- a/src/fft_fftw.cpp +++ b/src/fft_fftw.cpp @@ -97,14 +97,14 @@ void Fftw::forward(const cv::Mat &real_input, cv::Mat &complex_result) { // Fft::forward(real_input, complex_result); // -// if (real_input.size[0] == 1) + if (real_input.dims == 2) fftwf_execute_dft_r2c(plan_f, reinterpret_cast(real_input.data), reinterpret_cast(complex_result.ptr(0))); -//#ifdef BIG_BATCH -// else -// fftwf_execute_dft_r2c(plan_f_all_scales, reinterpret_cast(real_input.data), -// reinterpret_cast(complex_result.get_p_data())); -//#endif +#ifdef BIG_BATCH + else + fftwf_execute_dft_r2c(plan_f_all_scales, reinterpret_cast(real_input.data), + reinterpret_cast(complex_result.ptr(0))); +#endif } void Fftw::forward_window(MatScaleFeats &feat, ComplexMat & complex_result, MatScaleFeats &temp) @@ -147,12 +147,12 @@ void Fftw::forward_window(cv::Mat &feat, cv::Mat & complex_result, cv::Mat &temp float *in = temp.ptr(); fftwf_complex *out = reinterpret_cast(complex_result.ptr(0)); -// if (n_scales == 1) + if (feat.size[0] == 1) fftwf_execute_dft_r2c(plan_fw, in, out); -//#ifdef BIG_BATCH -// else -// fftwf_execute_dft_r2c(plan_fw_all_scales, in, out); -//#endif +#ifdef BIG_BATCH + else + fftwf_execute_dft_r2c(plan_fw_all_scales, in, out); +#endif } @@ -177,17 +177,16 @@ void Fftw::inverse(ComplexMat &complex_input, MatScales &real_result) void Fftw::inverse(cv::Mat &complex_input, cv::Mat &real_result) { // Fft::inverse(complex_input, real_result); -// -// int n_channels = complex_input.n_channels; + fftwf_complex *in = reinterpret_cast(complex_result.ptr(0)); float *out = real_result.ptr(); -// if (n_channels == 1) + if (complex_input.channels() == 2) fftwf_execute_dft_c2r(plan_i_1ch, in, out); -//#ifdef BIG_BATCH -// else -// fftwf_execute_dft_c2r(plan_i_all_scales, in, out); -//#endif +#ifdef BIG_BATCH + else + fftwf_execute_dft_c2r(plan_i_all_scales, in, out); +#endif real_result *= 1.0 / (m_width * m_height); } From 7582baf614e1c2a4e143e06287852ef527197951 Mon Sep 17 00:00:00 2001 From: Your Name Date: Thu, 2 Jan 2020 22:34:24 +0100 Subject: [PATCH 051/121] Opravena implementace fft_fftw.cpp (syntax) --- src/fft_fftw.cpp | 8 ++++---- 1 file changed, 4 insertions(+), 4 deletions(-) diff --git a/src/fft_fftw.cpp b/src/fft_fftw.cpp index 86c306bb..bb912ded 100644 --- a/src/fft_fftw.cpp +++ b/src/fft_fftw.cpp @@ -99,11 +99,11 @@ void Fftw::forward(const cv::Mat &real_input, cv::Mat &complex_result) // if (real_input.dims == 2) fftwf_execute_dft_r2c(plan_f, reinterpret_cast(real_input.data), - reinterpret_cast(complex_result.ptr(0))); + reinterpret_cast(complex_result.ptr>(0))); #ifdef BIG_BATCH else fftwf_execute_dft_r2c(plan_f_all_scales, reinterpret_cast(real_input.data), - reinterpret_cast(complex_result.ptr(0))); + reinterpret_cast(complex_result.ptr>(0))); #endif } @@ -145,7 +145,7 @@ void Fftw::forward_window(cv::Mat &feat, cv::Mat & complex_result, cv::Mat &temp } float *in = temp.ptr(); - fftwf_complex *out = reinterpret_cast(complex_result.ptr(0)); + fftwf_complex *out = reinterpret_cast(complex_result.ptr>(0)); if (feat.size[0] == 1) fftwf_execute_dft_r2c(plan_fw, in, out); @@ -178,7 +178,7 @@ void Fftw::inverse(cv::Mat &complex_input, cv::Mat &real_result) { // Fft::inverse(complex_input, real_result); - fftwf_complex *in = reinterpret_cast(complex_result.ptr(0)); + fftwf_complex *in = reinterpret_cast(complex_result.ptr>(0)); float *out = real_result.ptr(); if (complex_input.channels() == 2) From ec4ce2f095677c22080536456e69319c6d88e0ba Mon Sep 17 00:00:00 2001 From: Your Name Date: Thu, 2 Jan 2020 23:08:04 +0100 Subject: [PATCH 052/121] =?UTF-8?q?Opravena=20implementace=20fft=5Ffftw.cp?= =?UTF-8?q?p=20(prom=C4=9Bnn=C3=A1)?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- src/fft_fftw.cpp | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/fft_fftw.cpp b/src/fft_fftw.cpp index bb912ded..e945dcde 100644 --- a/src/fft_fftw.cpp +++ b/src/fft_fftw.cpp @@ -178,7 +178,7 @@ void Fftw::inverse(cv::Mat &complex_input, cv::Mat &real_result) { // Fft::inverse(complex_input, real_result); - fftwf_complex *in = reinterpret_cast(complex_result.ptr>(0)); + fftwf_complex *in = reinterpret_cast(complex_input.ptr>(0)); float *out = real_result.ptr(); if (complex_input.channels() == 2) From c0fe2b22439a4b080ca4e4d98899623afc31b312 Mon Sep 17 00:00:00 2001 From: Your Name Date: Mon, 6 Jan 2020 16:59:12 +0100 Subject: [PATCH 053/121] =?UTF-8?q?P=C5=99id=C3=A1ny=20koment=C3=A1=C5=99e?= =?UTF-8?q?=20k=20funkc=C3=ADm=20MatUtil?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- src/matutil.h | 34 +++++++++++++++++++++++++++++++++- 1 file changed, 33 insertions(+), 1 deletion(-) diff --git a/src/matutil.h b/src/matutil.h index df31f836..6bb521b3 100644 --- a/src/matutil.h +++ b/src/matutil.h @@ -108,31 +108,52 @@ static cv::Mat channel_to_cv_mat(int channel_id, cv::Mat &host){ return result; } - +/* + * Returns complex matrix, where every element is result of formula (hostElem.real() )^2 + (hostElem.imag() )^2 +**/ static cv::Mat sqr_mag(cv::Mat &host){ return mat_const_operator([](std::complex &c) { c = c.real() * c.real() + c.imag() * c.imag(); }, host); } +/* + * Returns copy of input complex matrix, where every imaginary value is inverted +**/ static cv::Mat conj(cv::Mat &host){ return mat_const_operator([](std::complex &c) { c = std::complex(c.real(), -c.imag()); }, host); } +/* + * Returns result of element wise multiplication between n-channeled and single-channeled complex matrixes +**/ static cv::Mat mul_matn_mat1(cv::Mat &host, cv::Mat &other){ return matn_mat1_operator([](std::complex &c_lhs, const std::complex &c_rhs) { c_lhs *= c_rhs; }, host, other); } +/* + * Returns result of element wise multiplication between two n-channeled complex matrixes +**/ static cv::Mat mul_matn_matn(cv::Mat &host, cv::Mat &other){ return mat_mat_operator([](std::complex &c_lhs, const std::complex &c_rhs) { c_lhs *= c_rhs; }, host, other); } +/* + * Returns result of element wise addition to complex matrix +**/ static cv::Mat add_scalar(cv::Mat &host, const float &val){ return mat_const_operator([&val](std::complex &c) { c += val; }, host); } +/* + * Returns result of element wise division between two n-channeled complex matrixes +**/ static cv::Mat divide_matn_matn(cv::Mat &host, cv::Mat &other){ return mat_mat_operator([](std::complex &c_lhs, const std::complex &c_rhs) { c_lhs /= c_rhs; }, host, other); } +/* + * Helper function to iterate through an input complex matrix. + * Creates copy of the matrix, executes supplied function on each element, then returns the copy. +**/ static cv::Mat mat_const_operator(const std::function &)> &op, cv::Mat &host){ assert(host.channels() % 2 == 0); cv::Mat result = host.clone(); @@ -148,6 +169,11 @@ static cv::Mat mat_const_operator(const std::function return result; } +/* + * Helper function to iterate through n-channeled and single-channeled complex matrixes. + * Creates copy of the n-channeled matrix, executes supplied function on each element of it, then returns the copy. + * No matter which channel, each point of the n-channeled copy will be processed by its corresponding point in the other matrix. +**/ static cv::Mat matn_mat1_operator(void (*op)(std::complex &, const std::complex &), cv::Mat &host, cv::Mat &other){ assert(host.channels() % 2 == 0); assert(other.channels() == 2); @@ -168,6 +194,12 @@ static cv::Mat matn_mat1_operator(void (*op)(std::complex &, const std::c return result; } +/* + * Helper function to iterate through n-channeled and single-channeled complex matrixes. + * Creates copy of the first n-channeled matrix, executes supplied function on each element of it, then returns the copy. + * Every value in the first matrix will be processed with its corresponding value in the other matrix, + * both channel and coordinate wise. +**/ static cv::Mat mat_mat_operator(void (*op)(std::complex &, const std::complex &), cv::Mat &host, cv::Mat &other){ assert(host.channels() % 2 == 0); assert(other.channels() == host.channels()); From 01cd7e813d6fa7876292e8630774096e4cc12610 Mon Sep 17 00:00:00 2001 From: oraveja1 <57142143+oraveja1@users.noreply.github.com> Date: Mon, 6 Jan 2020 17:01:16 +0100 Subject: [PATCH 054/121] Delete matutil.cpp No longer necessary, as all the definitions are in the header --- src/matutil.cpp | 32 -------------------------------- 1 file changed, 32 deletions(-) delete mode 100644 src/matutil.cpp diff --git a/src/matutil.cpp b/src/matutil.cpp deleted file mode 100644 index 679c4bc9..00000000 --- a/src/matutil.cpp +++ /dev/null @@ -1,32 +0,0 @@ -//#include "matutil.h" -//#include -//#include -// -//cv::Mat MatUtil::plane(uint scale, uint feature, cv::Mat &host) { -// assert(host.dims == 4); -// assert(int(scale) < host.size[0]); -// assert(int(feature) < host.size[1]); -// return cv::Mat(host.size[2], host.size[3], host.type(), host.ptr(scale, feature)); -//} -// -///* -// * Function for getting cv::Mat header referencing features, height and width of the input matrix. -// * Presumes input matrix of 4 dimensions with format: {scales, features, height, width} -// **/ -//cv::Mat MatUtil::scale(uint scale, cv::Mat &host) { -// assert(host.dims == 4); -// assert(int(scale) < host.size[0]); -// return cv::Mat(3, std::vector({host.size[1], host.size[2], host.size[3]}).data(), host.type(), host.ptr(scale)); -//} -// -// -///* -// * Sets the source as channel number idx of target matrix. -// **/ -//void MatUtil::set_channel(int idx, cv::Mat &source, cv::Mat &target) -//{ -// assert(idx < target.channels()); -// assert(source.channels() == 1); -// int from_to[] = { 0,idx }; -// cv::mixChannels( &source, 1, &target, 1, from_to, 1 ); -//} \ No newline at end of file From 194df559bf10da84b95aaa08f4cf153a2fce4787 Mon Sep 17 00:00:00 2001 From: Your Name Date: Tue, 7 Jan 2020 19:41:32 +0100 Subject: [PATCH 055/121] =?UTF-8?q?Upravena=20a=20otestov=C3=A1na=20prvn?= =?UTF-8?q?=C3=AD=20=C4=8D=C3=A1st=20ThreadCtx::track()=20-=20opraven=20ko?= =?UTF-8?q?ment=C3=A1=C5=99=20funkc=C3=AD=20Matutil=20-=20do=C4=8Dasn?= =?UTF-8?q?=C4=9B=20p=C5=99id=C3=A1n=20p=C5=99=C3=ADkaz=20return;=20za=20t?= =?UTF-8?q?estovanou=20=C4=8D=C3=A1st=20programu?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- src/kcf.cpp | 11 +++++++++++ src/matutil.h | 7 +++---- 2 files changed, 14 insertions(+), 4 deletions(-) diff --git a/src/kcf.cpp b/src/kcf.cpp index 2da4dd63..3e07ab9f 100644 --- a/src/kcf.cpp +++ b/src/kcf.cpp @@ -505,11 +505,14 @@ void KCF_Tracker::track(cv::Mat &img) it.async_res.wait(); #else // !ASYNC + + // Usually tracks 15 scale/angle combinations NORMAL_OMP_PARALLEL_FOR for (uint i = 0; i < d->threadctxs.size(); ++i) d->threadctxs[i].track(*this, input_rgb, input_gray); #endif + return; cv::Point2d new_location; uint max_idx; max_response = findMaxReponse(max_idx, new_location); @@ -557,6 +560,14 @@ void ThreadCtx::track(const KCF_Tracker &kcf, cv::Mat &input_rgb, cv::Mat &input kcf.p_current_angle + IF_BIG_BATCH(max.angle(i), angle)) .copyTo(patch_feats.scale(i)); DEBUG_PRINT(patch_feats.scale(i)); + + kcf.get_features(input_rgb, input_gray, &dbg_patch IF_BIG_BATCH([i],), + kcf.p_current_center.x, kcf.p_current_center.y, + kcf.p_windows_size.width, kcf.p_windows_size.height, + kcf.p_current_scale * IF_BIG_BATCH(max.scale(i), scale), + kcf.p_current_angle + IF_BIG_BATCH(max.angle(i), angle)) + .copyTo(MatUtil::scale(i, patch_feats_Test)); + DEBUG_PRINT(MatUtil::scale(i, patch_feats_Test)); } kcf.fft.forward_window(patch_feats, zf, temp); diff --git a/src/matutil.h b/src/matutil.h index 6bb521b3..9d09535e 100644 --- a/src/matutil.h +++ b/src/matutil.h @@ -21,9 +21,7 @@ static cv::Mat plane(uint scale, uint feature, cv::Mat &host) { /* * Function for getting cv::Mat header referencing height and width of the input matrix. - * Presumes input matrix of 3 dimensions with format: {scales, height, width} - * - * This will probably replace MatUtil::plane() + * Presumes input matrix of 3 dimensions with format: {features, height, width} **/ static cv::Mat plane(uint dim0, cv::Mat &host) { assert(host.dims == 3); @@ -32,7 +30,8 @@ static cv::Mat plane(uint dim0, cv::Mat &host) { } /* - * Function for getting cv::Mat header referencing features, height and width of the input matrix. + * Function for getting cv::Mat header referencing last three dimensions of the input matrix. + * Usually used for getting specific scale of a matrix. * Presumes input matrix of 4 dimensions with format: {scales, features, height, width} **/ static cv::Mat scale(uint scale, cv::Mat &host) { From 7dbcceb42636482238c45cb6b870ac959e3a0c94 Mon Sep 17 00:00:00 2001 From: Your Name Date: Tue, 7 Jan 2020 20:20:42 +0100 Subject: [PATCH 056/121] =?UTF-8?q?Upravena=20a=20otestov=C3=A1na=20druh?= =?UTF-8?q?=C3=A1=20=C4=8D=C3=A1st=20ThreadCtx::track()=20-=20Konvertov?= =?UTF-8?q?=C3=A1ny=20n=C4=9Bkter=C3=A9=20prom=C4=9Bnn=C3=A9=20v=20t=C5=99?= =?UTF-8?q?=C3=ADd=C4=9B=20ThreadCtx?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- src/kcf.cpp | 13 ++++++++++++- src/threadctx.hpp | 16 ++++++++++------ 2 files changed, 22 insertions(+), 7 deletions(-) diff --git a/src/kcf.cpp b/src/kcf.cpp index 3e07ab9f..eb43bcad 100644 --- a/src/kcf.cpp +++ b/src/kcf.cpp @@ -571,15 +571,26 @@ void ThreadCtx::track(const KCF_Tracker &kcf, cv::Mat &input_rgb, cv::Mat &input } kcf.fft.forward_window(patch_feats, zf, temp); + kcf.fft.forward_window(patch_feats_Test, zf_Test, temp_Test); DEBUG_PRINTM(zf); - + DEBUG_PRINTM(zf_Test); + if (kcf.m_use_linearkernel) { + // Unused feature kzf = zf.mul(kcf.model->model_alphaf).sum_over_channels(); } else { gaussian_correlation(kzf, zf, kcf.model->model_xf, kcf.p_kernel_sigma, false, kcf); DEBUG_PRINTM(kzf); kzf = kzf.mul(kcf.model->model_alphaf); + + gaussian_correlation(kzf_Test, zf_Test, kcf.model->model_xf_Test, kcf.p_kernel_sigma, false, kcf); + DEBUG_PRINTM(kzf_Test); + kzf_Test = MatUtil::mul_matn_mat1(kzf_Test, kcf.model->model_alphaf_Test); } + DEBUG_PRINTM(kzf); + DEBUG_PRINTM(kzf_Test); + return; + kcf.fft.inverse(kzf, response); DEBUG_PRINTM(response); diff --git a/src/threadctx.hpp b/src/threadctx.hpp index 333a3248..da846900 100644 --- a/src/threadctx.hpp +++ b/src/threadctx.hpp @@ -68,18 +68,22 @@ struct ThreadCtx { MatScaleFeats patch_feats{num_scales * num_angles, num_features, roi}; MatScaleFeats temp{num_scales * num_angles, num_features, roi}; - - // REPLACEMENT - cv::Mat patch_feats_Test{ 4, std::vector({ int(num_scales * num_angles), int(num_features), roi.height, roi.width}).data(), CV_32F}; - cv::Mat temp_Test{ 4, std::vector({ int(num_scales * num_angles), int(num_features), roi.height, roi.width}).data(), CV_32F}; - - KCF_Tracker::GaussianCorrelation gaussian_correlation{num_scales * num_angles, num_features, roi}; MatScales ifft2_res{num_scales * num_angles, roi}; ComplexMat zf{uint(freq_size.height), uint(freq_size.width), num_features, num_scales * num_angles}; ComplexMat kzf{uint(freq_size.height), uint(freq_size.width), 1, num_scales * num_angles}; + // REPLACEMENT + cv::Mat patch_feats_Test{ 4, std::vector({ int(num_scales * num_angles), int(num_features), roi.height, roi.width}).data(), CV_32F}; + cv::Mat temp_Test{ 4, std::vector({ int(num_scales * num_angles), int(num_features), roi.height, roi.width}).data(), CV_32F}; + + cv::Mat zf_Test = cv::Mat::zeros((int) freq_size.height, (int) freq_size.width, CV_32FC(num_features*2)); + cv::Mat kzf_Test = cv::Mat::zeros((int) freq_size.height, (int) freq_size.width, CV_32FC2); + + KCF_Tracker::GaussianCorrelation gaussian_correlation{num_scales * num_angles, num_features, roi}; + + public: #ifdef ASYNC std::future async_res; From 059491ee9970adfbada7e5f023ea15a9ee3ecd0a Mon Sep 17 00:00:00 2001 From: Your Name Date: Tue, 7 Jan 2020 20:42:57 +0100 Subject: [PATCH 057/121] =?UTF-8?q?ThreadCtx::track()=20je=20kompletn?= =?UTF-8?q?=C4=9B=20upravena=20a=20otestov=C3=A1na=20-=20Konvertov=C3=A1ny?= =?UTF-8?q?=20v=C5=A1echny=20relevantn=C3=AD=20prom=C4=9Bnn=C3=A9=20v=20t?= =?UTF-8?q?=C5=99=C3=ADd=C4=9B=20ThreadCtx=20-=20Odstran=C4=9Bn=20vlo?= =?UTF-8?q?=C5=BEen=C3=BD=20return;=20za=20testovan=C3=BDm=20k=C3=B3dem?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- src/kcf.cpp | 16 +++++++++++----- src/threadctx.hpp | 3 +++ 2 files changed, 14 insertions(+), 5 deletions(-) diff --git a/src/kcf.cpp b/src/kcf.cpp index eb43bcad..b39d67f6 100644 --- a/src/kcf.cpp +++ b/src/kcf.cpp @@ -512,7 +512,6 @@ void KCF_Tracker::track(cv::Mat &img) d->threadctxs[i].track(*this, input_rgb, input_gray); #endif - return; cv::Point2d new_location; uint max_idx; max_response = findMaxReponse(max_idx, new_location); @@ -589,18 +588,22 @@ void ThreadCtx::track(const KCF_Tracker &kcf, cv::Mat &input_rgb, cv::Mat &input } DEBUG_PRINTM(kzf); DEBUG_PRINTM(kzf_Test); - return; kcf.fft.inverse(kzf, response); + kcf.fft.inverse(kzf_Test, response_Test); DEBUG_PRINTM(response); - + DEBUG_PRINTM(response_Test); + /* target location is at the maximum response. we must take into account the fact that, if the target doesn't move, the peak will appear at the top-left corner, not at the center (this is discussed in the paper). the responses wrap around cyclically. */ double min_val, max_val; cv::Point2i min_loc, max_loc; + + double min_val_Test, max_val_Test; + cv::Point2i min_loc_Test, max_loc_Test; #ifdef BIG_BATCH for (size_t i = 0; i < max.size(); ++i) { cv::minMaxLoc(response.plane(i), &min_val, &max_val, &min_loc, &max_loc); @@ -611,10 +614,13 @@ void ThreadCtx::track(const KCF_Tracker &kcf, cv::Mat &input_rgb, cv::Mat &input } #else cv::minMaxLoc(response.plane(0), &min_val, &max_val, &min_loc, &max_loc); - DEBUG_PRINT(max_loc); DEBUG_PRINT(max_val); - + + cv::minMaxLoc(MatUtil::plane(0, response_Test), &min_val_Test, &max_val_Test, &min_loc_Test, &max_loc_Test); + DEBUG_PRINT(max_loc_Test); + DEBUG_PRINT(max_val_Test); + double weight = scale < 1. ? scale : 1. / scale; max.response = max_val * weight; max.loc = max_loc; diff --git a/src/threadctx.hpp b/src/threadctx.hpp index da846900..62bbb327 100644 --- a/src/threadctx.hpp +++ b/src/threadctx.hpp @@ -78,6 +78,8 @@ struct ThreadCtx { cv::Mat patch_feats_Test{ 4, std::vector({ int(num_scales * num_angles), int(num_features), roi.height, roi.width}).data(), CV_32F}; cv::Mat temp_Test{ 4, std::vector({ int(num_scales * num_angles), int(num_features), roi.height, roi.width}).data(), CV_32F}; + cv::Mat ifft2_res_Test = cv::Mat(3, std::vector({int(num_scales * num_angles), (int) roi.height, (int) roi.width}).data(), CV_32F); + cv::Mat zf_Test = cv::Mat::zeros((int) freq_size.height, (int) freq_size.width, CV_32FC(num_features*2)); cv::Mat kzf_Test = cv::Mat::zeros((int) freq_size.height, (int) freq_size.width, CV_32FC2); @@ -90,6 +92,7 @@ struct ThreadCtx { #endif MatScales response{num_scales * num_angles, roi}; + cv::Mat response_Test = cv::Mat(3, std::vector({int(num_scales * num_angles), (int) roi.height, (int) roi.width}).data(), CV_32F); struct Max { cv::Point2i loc; From f7b63db511b3c527ea7aba0a08c983f37da16160 Mon Sep 17 00:00:00 2001 From: Your Name Date: Tue, 7 Jan 2020 20:47:25 +0100 Subject: [PATCH 058/121] =?UTF-8?q?Prom=C4=9Bnn=C3=A1=20ThreadCtx::ifft2?= =?UTF-8?q?=5Fres=20byla=20odstran=C4=9Bna,=20proto=C5=BEe=20nen=C3=AD=20p?= =?UTF-8?q?ou=C5=BEita=20nikde=20v=20cel=C3=A9m=20k=C3=B3du?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- src/threadctx.hpp | 6 +----- 1 file changed, 1 insertion(+), 5 deletions(-) diff --git a/src/threadctx.hpp b/src/threadctx.hpp index 62bbb327..1576d50f 100644 --- a/src/threadctx.hpp +++ b/src/threadctx.hpp @@ -69,17 +69,13 @@ struct ThreadCtx { MatScaleFeats patch_feats{num_scales * num_angles, num_features, roi}; MatScaleFeats temp{num_scales * num_angles, num_features, roi}; - MatScales ifft2_res{num_scales * num_angles, roi}; - ComplexMat zf{uint(freq_size.height), uint(freq_size.width), num_features, num_scales * num_angles}; ComplexMat kzf{uint(freq_size.height), uint(freq_size.width), 1, num_scales * num_angles}; // REPLACEMENT cv::Mat patch_feats_Test{ 4, std::vector({ int(num_scales * num_angles), int(num_features), roi.height, roi.width}).data(), CV_32F}; cv::Mat temp_Test{ 4, std::vector({ int(num_scales * num_angles), int(num_features), roi.height, roi.width}).data(), CV_32F}; - - cv::Mat ifft2_res_Test = cv::Mat(3, std::vector({int(num_scales * num_angles), (int) roi.height, (int) roi.width}).data(), CV_32F); - + cv::Mat zf_Test = cv::Mat::zeros((int) freq_size.height, (int) freq_size.width, CV_32FC(num_features*2)); cv::Mat kzf_Test = cv::Mat::zeros((int) freq_size.height, (int) freq_size.width, CV_32FC2); From 4d5a4fadafc639ada885a84b216fa3de1b6d11c5 Mon Sep 17 00:00:00 2001 From: Your Name Date: Tue, 7 Jan 2020 21:17:23 +0100 Subject: [PATCH 059/121] =?UTF-8?q?Zv=C3=BDrazn=C4=9Bna=20m=C3=ADsta=20pro?= =?UTF-8?q?=20edit=20v=20KCF=5FTracker::findMaxReponse=20-=20z=20v=C4=9Bt?= =?UTF-8?q?=C5=A1=C3=AD=20=C4=8D=C3=A1sti=20nen=C3=AD=20t=C5=99eba=20funkc?= =?UTF-8?q?i=20upravovat,=20a=20pot=C5=99ebn=C3=A1=20m=C3=ADsta=20nem?= =?UTF-8?q?=C3=A1=20smysl=20upravovat=20v=20tuto=20chv=C3=ADli?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- src/kcf.cpp | 2 ++ 1 file changed, 2 insertions(+) diff --git a/src/kcf.cpp b/src/kcf.cpp index b39d67f6..4a55e7aa 100644 --- a/src/kcf.cpp +++ b/src/kcf.cpp @@ -418,6 +418,7 @@ double KCF_Tracker::findMaxReponse(uint &max_idx, cv::Point2d &new_location) con max_idx = std::distance(vec.begin(), max_it); cv::Point2i max_response_pt = IF_BIG_BATCH(max_it->loc, max_it->max.loc); + // EDIT: Use MatUtil::plane() here (part of _Test conversion) cv::Mat max_response_map = IF_BIG_BATCH(d->threadctxs[0].response.plane(max_idx), max_it->response.plane(0)); @@ -452,6 +453,7 @@ double KCF_Tracker::findMaxReponse(uint &max_idx, cv::Point2d &new_location) con cross.x = cross.x / fit_size.width * tmp.cols + tmp.cols / 2; cross.y = cross.y / fit_size.height * tmp.rows + tmp.rows / 2; } else { + // EDIT: Use MatUtil::plane() here (part of _Test conversion) cv::cvtColor(threadctx.response.plane(IF_BIG_BATCH(threadctx.max.getIdx(i, j), 0)), tmp, cv::COLOR_GRAY2BGR); tmp /= max; // Normalize to 1 From 9f4a1b5fc8ce71dd8fb279448398193b32d9e3ed Mon Sep 17 00:00:00 2001 From: Your Name Date: Tue, 7 Jan 2020 21:45:29 +0100 Subject: [PATCH 060/121] =?UTF-8?q?KONVERTOV=C3=81N=20POSLEDN=C3=8D=20V?= =?UTF-8?q?=C3=9DSKYT=20COMPLEXMAT=20A=20DYNMEM=20-=20dokon=C4=8Dena=20a?= =?UTF-8?q?=20otestov=C3=A1na=20posledn=C3=AD=20funkce=20track()=20-=20v?= =?UTF-8?q?=20tuto=20chv=C3=ADli=20zb=C3=BDv=C3=A1=20otestovat=20chov?= =?UTF-8?q?=C3=A1n=C3=AD=20programu=20po=20p=C5=99ipojen=C3=AD=20testovac?= =?UTF-8?q?=C3=ADch=20prom=C4=9Bnn=C3=BDch=20(tzn,=20zm=C4=9Bna=20vstupu?= =?UTF-8?q?=20do=20prom=C4=9Bnn=C3=BDch=20response=20a=20max=20t=C5=99?= =?UTF-8?q?=C3=ADdy=20ThreadCtx)?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit Další plánované úpravy: - oprava assertů ve souboru fft.cpp - odstranění osobních komentářů - původní proměnné odstraněny, a třídy ComplexMat + DynMem smazány - prozkoumání použití cv::mulSpectrums --- src/kcf.cpp | 9 ++++++--- 1 file changed, 6 insertions(+), 3 deletions(-) diff --git a/src/kcf.cpp b/src/kcf.cpp index 4a55e7aa..35a7ea44 100644 --- a/src/kcf.cpp +++ b/src/kcf.cpp @@ -418,11 +418,13 @@ double KCF_Tracker::findMaxReponse(uint &max_idx, cv::Point2d &new_location) con max_idx = std::distance(vec.begin(), max_it); cv::Point2i max_response_pt = IF_BIG_BATCH(max_it->loc, max_it->max.loc); - // EDIT: Use MatUtil::plane() here (part of _Test conversion) cv::Mat max_response_map = IF_BIG_BATCH(d->threadctxs[0].response.plane(max_idx), max_it->response.plane(0)); - + cv::Mat max_response_map_Test = IF_BIG_BATCH(MatUtil::plane(max_idx, d->threadctxs[0].response), + MatUtil::plane(0, max_it->response)); + DEBUG_PRINTM(max_response_map); + DEBUG_PRINTM(max_response_map_Test); DEBUG_PRINT(max_response_pt); max_response_pt = wrapAroundFreq(max_response_pt, max_response_map); @@ -453,9 +455,10 @@ double KCF_Tracker::findMaxReponse(uint &max_idx, cv::Point2d &new_location) con cross.x = cross.x / fit_size.width * tmp.cols + tmp.cols / 2; cross.y = cross.y / fit_size.height * tmp.rows + tmp.rows / 2; } else { - // EDIT: Use MatUtil::plane() here (part of _Test conversion) cv::cvtColor(threadctx.response.plane(IF_BIG_BATCH(threadctx.max.getIdx(i, j), 0)), tmp, cv::COLOR_GRAY2BGR); + cv::cvtColor(MatUtil::plane(IF_BIG_BATCH(threadctx.max.getIdx(i, j), 0), threadctx.response), + tmp, cv::COLOR_GRAY2BGR); tmp /= max; // Normalize to 1 cross += cv::Point2d(tmp.size())/2; tmp = circshift(tmp, -tmp.cols/2, -tmp.rows/2); From 881293d963eed7758c123c7145ef7b71141c9bed Mon Sep 17 00:00:00 2001 From: Your Name Date: Tue, 7 Jan 2020 21:55:52 +0100 Subject: [PATCH 061/121] =?UTF-8?q?Opraveno=20nespr=C3=A1vn=C3=A9=20vol?= =?UTF-8?q?=C3=A1n=C3=AD=20ve=20funkci=20findMaxReponse()?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- src/kcf.cpp | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/src/kcf.cpp b/src/kcf.cpp index 35a7ea44..ea804f14 100644 --- a/src/kcf.cpp +++ b/src/kcf.cpp @@ -420,8 +420,8 @@ double KCF_Tracker::findMaxReponse(uint &max_idx, cv::Point2d &new_location) con cv::Point2i max_response_pt = IF_BIG_BATCH(max_it->loc, max_it->max.loc); cv::Mat max_response_map = IF_BIG_BATCH(d->threadctxs[0].response.plane(max_idx), max_it->response.plane(0)); - cv::Mat max_response_map_Test = IF_BIG_BATCH(MatUtil::plane(max_idx, d->threadctxs[0].response), - MatUtil::plane(0, max_it->response)); + cv::Mat max_response_map_Test = IF_BIG_BATCH(MatUtil::plane(max_idx, d->threadctxs[0].response_Test), + MatUtil::plane(0, max_it->response_Test)); DEBUG_PRINTM(max_response_map); DEBUG_PRINTM(max_response_map_Test); From bd0f12b35e7e24292272883895c142db275c90d6 Mon Sep 17 00:00:00 2001 From: Your Name Date: Tue, 7 Jan 2020 22:08:20 +0100 Subject: [PATCH 062/121] =?UTF-8?q?Opraveno=20nespr=C3=A1vn=C3=A9=20vol?= =?UTF-8?q?=C3=A1n=C3=AD=20ve=20funkci=20findMaxReponse()=20(oprava=202)?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- src/kcf.cpp | 5 +++-- 1 file changed, 3 insertions(+), 2 deletions(-) diff --git a/src/kcf.cpp b/src/kcf.cpp index ea804f14..8762a2f0 100644 --- a/src/kcf.cpp +++ b/src/kcf.cpp @@ -420,8 +420,9 @@ double KCF_Tracker::findMaxReponse(uint &max_idx, cv::Point2d &new_location) con cv::Point2i max_response_pt = IF_BIG_BATCH(max_it->loc, max_it->max.loc); cv::Mat max_response_map = IF_BIG_BATCH(d->threadctxs[0].response.plane(max_idx), max_it->response.plane(0)); + cv::Mat tempResponse = max_it->response_Test; cv::Mat max_response_map_Test = IF_BIG_BATCH(MatUtil::plane(max_idx, d->threadctxs[0].response_Test), - MatUtil::plane(0, max_it->response_Test)); + MatUtil::plane(0, tempResponse)); DEBUG_PRINTM(max_response_map); DEBUG_PRINTM(max_response_map_Test); @@ -520,7 +521,7 @@ void KCF_Tracker::track(cv::Mat &img) cv::Point2d new_location; uint max_idx; max_response = findMaxReponse(max_idx, new_location); - + return; double angle_change = m_use_subgrid_angle ? sub_grid_angle(max_idx) : d->IF_BIG_BATCH(threadctxs[0].max, threadctxs).angle(max_idx); p_current_angle += angle_change; From 6725e433e25587ec8e23c20a01b766bc18f4b199 Mon Sep 17 00:00:00 2001 From: Your Name Date: Tue, 7 Jan 2020 22:09:28 +0100 Subject: [PATCH 063/121] =?UTF-8?q?Opraveno=20nespr=C3=A1vn=C3=A9=20vol?= =?UTF-8?q?=C3=A1n=C3=AD=20ve=20funkci=20findMaxReponse()=20(oprava=203)?= =?UTF-8?q?=20-=20odstran=C4=9Bn=20testovac=C3=AD=20return.?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- src/kcf.cpp | 1 - 1 file changed, 1 deletion(-) diff --git a/src/kcf.cpp b/src/kcf.cpp index 8762a2f0..13b2b520 100644 --- a/src/kcf.cpp +++ b/src/kcf.cpp @@ -521,7 +521,6 @@ void KCF_Tracker::track(cv::Mat &img) cv::Point2d new_location; uint max_idx; max_response = findMaxReponse(max_idx, new_location); - return; double angle_change = m_use_subgrid_angle ? sub_grid_angle(max_idx) : d->IF_BIG_BATCH(threadctxs[0].max, threadctxs).angle(max_idx); p_current_angle += angle_change; From 3bf539255b79953b3944830339495f533282d14d Mon Sep 17 00:00:00 2001 From: Your Name Date: Tue, 7 Jan 2020 22:18:01 +0100 Subject: [PATCH 064/121] =?UTF-8?q?Opraveno=20nespr=C3=A1vn=C3=A9=20vol?= =?UTF-8?q?=C3=A1n=C3=AD=20ve=20funkci=20findMaxReponse()=20(oprava=203)?= =?UTF-8?q?=20-=20build-specifick=C3=A9=20vol=C3=A1n=C3=AD?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- src/kcf.cpp | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/kcf.cpp b/src/kcf.cpp index 13b2b520..d3f72ed5 100644 --- a/src/kcf.cpp +++ b/src/kcf.cpp @@ -420,7 +420,7 @@ double KCF_Tracker::findMaxReponse(uint &max_idx, cv::Point2d &new_location) con cv::Point2i max_response_pt = IF_BIG_BATCH(max_it->loc, max_it->max.loc); cv::Mat max_response_map = IF_BIG_BATCH(d->threadctxs[0].response.plane(max_idx), max_it->response.plane(0)); - cv::Mat tempResponse = max_it->response_Test; + cv::Mat tempResponse = IF_BIG_BATCH(,max_it->response_Test); cv::Mat max_response_map_Test = IF_BIG_BATCH(MatUtil::plane(max_idx, d->threadctxs[0].response_Test), MatUtil::plane(0, tempResponse)); From f4e8e4f3d90f6ca4db3945dd27558a3f100d626a Mon Sep 17 00:00:00 2001 From: Your Name Date: Wed, 8 Jan 2020 19:48:08 +0100 Subject: [PATCH 065/121] =?UTF-8?q?Zprovozn=C4=9Bny=20fft=20asserty=20pro?= =?UTF-8?q?=20cv::Mat=20form=C3=A1t?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- src/fft.cpp | 69 ++++++++++++++++++++++++++++++++++++++++++++++ src/fft.h | 4 +++ src/fft_fftw.cpp | 8 +++--- src/fft_opencv.cpp | 6 ++-- 4 files changed, 80 insertions(+), 7 deletions(-) diff --git a/src/fft.cpp b/src/fft.cpp index e6be0931..7c31ac0c 100644 --- a/src/fft.cpp +++ b/src/fft.cpp @@ -44,6 +44,25 @@ void Fft::forward(const MatScales &real_input, ComplexMat &complex_result) (void)complex_result; } +// REPLACEMENT +void Fft::forward(const cv::Mat &real_input, cv::Mat &complex_result) +{ + TRACE(""); + DEBUG_PRINT(real_input); + assert(real_input.dims == 2); + + assert(real_input.rows == int(m_height)); + assert(real_input.cols == int(m_width)); + + assert(int(complex_result.cols) == freq_size(cv::Size(m_width, m_height)).width); + assert(int(complex_result.rows) == freq_size(cv::Size(m_width, m_height)).height); + assert(real_input.channels() == 1); + assert(complex_result.channels() == 2); + + (void)real_input; + (void)complex_result; +} + void Fft::forward_window(MatScaleFeats &patch_feats, ComplexMat &complex_result, MatScaleFeats &tmp) { assert(patch_feats.dims == 4); @@ -71,6 +90,34 @@ void Fft::forward_window(MatScaleFeats &patch_feats, ComplexMat &complex_result, (void)tmp; } +// REPLACEMENT +void Fft::forward_window(cv::Mat &patch_feats, cv::Mat &complex_result, cv::Mat &tmp) +{ + assert(patch_feats.dims == 4); +#ifdef BIG_BATCH + assert(patch_feats.size[0] == 1 || patch_feats.size[0] == int(m_num_of_scales)); +#else + assert(patch_feats.size[0] == 1); +#endif + 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]); + + assert(int(complex_result.cols) == freq_size(cv::Size(m_width, m_height)).width); + assert(int(complex_result.rows) == freq_size(cv::Size(m_width, m_height)).height); + assert(complex_result.channels() == (2 * patch_feats.size[0] * patch_feats.size[1])); + + (void)patch_feats; + (void)complex_result; + (void)tmp; +} + void Fft::inverse(ComplexMat &complex_input, MatScales &real_result) { TRACE(""); @@ -91,3 +138,25 @@ void Fft::inverse(ComplexMat &complex_input, MatScales &real_result) (void)complex_input; (void)real_result; } + +// REPLACEMENT +void Fft::inverse(cv::Mat &complex_input, cv::Mat &real_result) +{ + TRACE(""); + DEBUG_PRINT(complex_input); + assert(real_result.dims == 3); +#ifdef BIG_BATCH + assert(real_result.size[0] == 1 || real_result.size[0] == int(m_num_of_scales)); +#else + assert(real_result.size[0] == 1); +#endif + assert(real_result.size[1] == int(m_height)); + assert(real_result.size[2] == int(m_width)); + + assert(int(complex_input.cols) == freq_size(cv::Size(m_width, m_height)).width); + assert(int(complex_input.rows) == freq_size(cv::Size(m_width, m_height)).height); + assert(complex_input.channels() == real_result.size[0] * 2); + + (void)complex_input; + (void)real_result; +} \ No newline at end of file diff --git a/src/fft.h b/src/fft.h index 9f74de38..d80b7668 100644 --- a/src/fft.h +++ b/src/fft.h @@ -23,6 +23,10 @@ class Fft void forward(const MatScales &real_input, ComplexMat &complex_result); void forward_window(MatScaleFeats &patch_feats_in, ComplexMat &complex_result, MatScaleFeats &tmp); void inverse(ComplexMat &complex_input, MatScales &real_result); + + void forward(const cv::Mat &real_input, cv::Mat &complex_result); + void forward_window(cv::Mat &patch_feats, cv::Mat &complex_result, cv::Mat &tmp); + void inverse(cv::Mat &complex_input, cv::Mat &real_result); static cv::Size freq_size(cv::Size space_size) { diff --git a/src/fft_fftw.cpp b/src/fft_fftw.cpp index e945dcde..7300fe7d 100644 --- a/src/fft_fftw.cpp +++ b/src/fft_fftw.cpp @@ -95,8 +95,8 @@ void Fftw::forward(const MatScales &real_input, ComplexMat &complex_result) // REPLACEMENT void Fftw::forward(const cv::Mat &real_input, cv::Mat &complex_result) { -// Fft::forward(real_input, complex_result); -// + Fft::forward(real_input, complex_result); + if (real_input.dims == 2) fftwf_execute_dft_r2c(plan_f, reinterpret_cast(real_input.data), reinterpret_cast(complex_result.ptr>(0))); @@ -134,7 +134,7 @@ void Fftw::forward_window(MatScaleFeats &feat, ComplexMat & complex_result, Mat // REPLACEMENT void Fftw::forward_window(cv::Mat &feat, cv::Mat & complex_result, cv::Mat &temp) { -// Fft::forward_window(feat, complex_result, temp); + Fft::forward_window(feat, complex_result, temp); for (uint i = 0; i < uint(feat.size[0]); ++i) { for (uint j = 0; j < uint(feat.size[1]); ++j) { @@ -176,7 +176,7 @@ void Fftw::inverse(ComplexMat &complex_input, MatScales &real_result) // REPLACEMENT void Fftw::inverse(cv::Mat &complex_input, cv::Mat &real_result) { -// Fft::inverse(complex_input, real_result); + Fft::inverse(complex_input, real_result); fftwf_complex *in = reinterpret_cast(complex_input.ptr>(0)); float *out = real_result.ptr(); diff --git a/src/fft_opencv.cpp b/src/fft_opencv.cpp index 2f637201..83cb6720 100644 --- a/src/fft_opencv.cpp +++ b/src/fft_opencv.cpp @@ -25,7 +25,7 @@ void FftOpencv::forward(const MatScales &real_input, ComplexMat &complex_result) // REPLACEMENT void FftOpencv::forward(const cv::Mat &real_input, cv::Mat &complex_result) { -// Fft::forward(real_input, complex_result); + Fft::forward(real_input, complex_result); cv::dft(real_input, complex_result, cv::DFT_COMPLEX_OUTPUT); } @@ -48,7 +48,7 @@ void FftOpencv::forward_window(MatScaleFeats &feat, ComplexMat &complex_result, // Real and imag parts of complex elements from previous format are represented by 2 neighbouring channels. void FftOpencv::forward_window(cv::Mat &feat, cv::Mat &complex_result, cv::Mat &temp) { - //Fft::forward_window(feat, complex_result, temp); + Fft::forward_window(feat, complex_result, temp); (void) temp; for (uint i = 0; i < uint(feat.size[0]); ++i) { for (uint j = 0; j < uint(feat.size[1]); ++j) { @@ -75,7 +75,7 @@ void FftOpencv::inverse(ComplexMat & complex_input, MatScales & real_result) // REPLACEMENT void FftOpencv::inverse(cv::Mat &complex_input, cv::Mat &real_result) { - //Fft::inverse(complex_input, real_result); + Fft::inverse(complex_input, real_result); assert(complex_input.channels() % 2 == 0); for (uint i = 0; i < uint(complex_input.channels() / 2); ++i) { From efd392cf86147881f74a9f3b5559c5bb14cf36da Mon Sep 17 00:00:00 2001 From: Your Name Date: Wed, 8 Jan 2020 19:53:25 +0100 Subject: [PATCH 066/121] =?UTF-8?q?Odstran=C4=9Bny=20koment=C3=A1=C5=99e?= =?UTF-8?q?=20a=20osobn=C3=AD=20pozn=C3=A1mky?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- src/kcf.cpp | 69 +---------------------------------------------------- 1 file changed, 1 insertion(+), 68 deletions(-) diff --git a/src/kcf.cpp b/src/kcf.cpp index d3f72ed5..b17fa30f 100644 --- a/src/kcf.cpp +++ b/src/kcf.cpp @@ -94,11 +94,7 @@ void KCF_Tracker::train(cv::Mat input_rgb, cv::Mat input_gray, double interp_fac DEBUG_PRINTM(model->model_xf); DEBUG_PRINTM(model->model_xf_Test); - if (m_use_linearkernel) { -// ComplexMat xfconj = model->xf.conj(); -// model->model_alphaf_num = xfconj.mul(model->yf); -// model->model_alphaf_den = (model->xf * xfconj); - + if (m_use_linearkernel) { cv::Mat xfconj_Test = MatUtil::conj(model->xf_Test); model->model_alphaf_num_Test = MatUtil::mul_matn_mat1(xfconj_Test, model->yf_Test); model->model_alphaf_den_Test = MatUtil::mul_matn_matn(model->xf_Test, xfconj_Test); @@ -140,64 +136,6 @@ void KCF_Tracker::init(cv::Mat &img, const cv::Rect &bbox, int fit_size_x, int f __dbgTracer.debug = m_debug; TRACE(""); -// //cv::Mat test = cv::Mat(2,2,CV_32FC4,float(1)); -// cv::Mat test = cv::Mat(3, std::vector({2, 2, 2}).data(), CV_32FC2, float(5)); -// cv::Mat testPl = cv::Mat(test.size[1], test.size[2], test.type(), test.ptr(0)); -// cv::Mat test2 = cv::Mat(2,2,CV_32FC2,float(6)); -// -//// cv::Mat_> testComplex = cv::Mat_>(test2); -// -// test.ptr(0)[0] = float(1); -// test.ptr(0)[1] = float(2); -// test.ptr(0)[2] = float(3); -// test.ptr(0)[3] = float(4); -// test.ptr(0)[4] = float(5); -// test.ptr(0)[5] = float(6); -// test.ptr(0)[6] = float(7); -// test.ptr(0)[7] = float(8); -// test.ptr(1)[0] = float(9); -// test.ptr(1)[1] = float(10); -// test.ptr(1)[2] = float(11); -// test.ptr(1)[3] = float(12); -// test.ptr(1)[4] = float(13); -// test.ptr(1)[5] = float(14); -// test.ptr(1)[6] = float(15); -// test.ptr(1)[7] = float(16); -// DEBUG_PRINTM(test); -// DEBUG_PRINTM(testPl); -// DEBUG_PRINTM(test2); -// -// int from_to[] = { 0,0 }; -// cv::mixChannels(&testPl,1,&test2,1,from_to,1); -// int from_to2[] = { 1,1 }; -// cv::mixChannels(&testPl,1,&test2,1,from_to2,1); -// -// DEBUG_PRINTM(test2); -// return; -// -// -// assert(test.channels() % 2 == 0); -// for (uint i = 0; i < test.rows; ++i) { -// for (uint j = 0; j < test.cols; ++j){ -// for (uint k = 0; k < test.channels() / 2 ; ++k){ -// std::complex cpxVal = test.ptr>(i)[(test.channels() / 2)*j + k]; -// cpxVal.imag(- cpxVal.imag()); -// test.ptr>(i)[(test.channels() / 2)*j + k] = cpxVal; -// DEBUG_PRINTM(cpxVal); -// } -// } -// } -// -// cv::Mat test = cv::Mat(3, std::vector({2, 2, 2}).data(), CV_32FC2, float(5)); -// test.ptr(0)[0] = float(1); -// test.ptr(1)[0] = float(1); -// test.ptr(1,1)[0] = float(1); -// -// DEBUG_PRINTM(test); -// -// -// return; - // check boundary, enforce min size double x1 = bbox.x, x2 = bbox.x + bbox.width, y1 = bbox.y, y2 = bbox.y + bbox.height; if (x1 < 0) x1 = 0.; @@ -330,11 +268,6 @@ void KCF_Tracker::init(cv::Mat &img, const cv::Rect &bbox, int fit_size_x, int f DEBUG_PRINTM(model->yf); DEBUG_PRINTM(model->yf_Test); - -// Accessing cv::Mat real/imag channels -// std::complex* f1 = model->yf_Test.ptr< std::complex >(0); -// float f2 = (*f1).real(); -// float f3 = (*f1).imag(); // train initial model train(input_rgb, input_gray, 1.0); From 169e86420f56eefe4033947b6e25914832305173 Mon Sep 17 00:00:00 2001 From: Your Name Date: Wed, 8 Jan 2020 20:51:35 +0100 Subject: [PATCH 067/121] =?UTF-8?q?Odstran=C4=9Bny=20k=C3=B3d=20ComplexMat?= =?UTF-8?q?=20a=20DynMem=20ze=20soubor=C5=AF=20fft=20(krom=C4=9B=20cufft)?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- src/fft.cpp | 74 +--------------------------------------------- src/fft.h | 6 +--- src/fft_fftw.cpp | 61 +------------------------------------- src/fft_fftw.h | 5 +--- src/fft_opencv.cpp | 38 +----------------------- src/fft_opencv.h | 8 +---- 6 files changed, 6 insertions(+), 186 deletions(-) diff --git a/src/fft.cpp b/src/fft.cpp index 7c31ac0c..09eec58a 100644 --- a/src/fft.cpp +++ b/src/fft.cpp @@ -15,7 +15,7 @@ void Fft::init(unsigned width, unsigned height, unsigned num_of_feats, unsigned #endif } -void Fft::set_window(const MatDynMem &window) +void Fft::set_window(const cv::Mat &window) { assert(window.dims == 2); assert(window.size().width == int(m_width)); @@ -23,28 +23,6 @@ void Fft::set_window(const MatDynMem &window) (void)window; } -void Fft::forward(const MatScales &real_input, ComplexMat &complex_result) -{ - TRACE(""); - DEBUG_PRINT(real_input); - assert(real_input.dims == 3); -#ifdef BIG_BATCH - assert(real_input.size[0] == 1 || real_input.size[0] == int(m_num_of_scales)); -#else - assert(real_input.size[0] == 1); -#endif - assert(real_input.size[1] == int(m_height)); - assert(real_input.size[2] == int(m_width)); - - assert(int(complex_result.cols) == freq_size(cv::Size(m_width, m_height)).width); - assert(int(complex_result.rows) == freq_size(cv::Size(m_width, m_height)).height); - assert(complex_result.channels() == uint(real_input.size[0])); - - (void)real_input; - (void)complex_result; -} - -// REPLACEMENT void Fft::forward(const cv::Mat &real_input, cv::Mat &complex_result) { TRACE(""); @@ -63,34 +41,6 @@ void Fft::forward(const cv::Mat &real_input, cv::Mat &complex_result) (void)complex_result; } -void Fft::forward_window(MatScaleFeats &patch_feats, ComplexMat &complex_result, MatScaleFeats &tmp) -{ - assert(patch_feats.dims == 4); -#ifdef BIG_BATCH - assert(patch_feats.size[0] == 1 || patch_feats.size[0] == int(m_num_of_scales)); -#else - assert(patch_feats.size[0] == 1); -#endif - 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]); - - assert(int(complex_result.cols) == freq_size(cv::Size(m_width, m_height)).width); - assert(int(complex_result.rows) == freq_size(cv::Size(m_width, m_height)).height); - assert(complex_result.channels() == uint(patch_feats.size[0] * patch_feats.size[1])); - - (void)patch_feats; - (void)complex_result; - (void)tmp; -} - -// REPLACEMENT void Fft::forward_window(cv::Mat &patch_feats, cv::Mat &complex_result, cv::Mat &tmp) { assert(patch_feats.dims == 4); @@ -118,28 +68,6 @@ void Fft::forward_window(cv::Mat &patch_feats, cv::Mat &complex_result, cv::Mat (void)tmp; } -void Fft::inverse(ComplexMat &complex_input, MatScales &real_result) -{ - TRACE(""); - DEBUG_PRINT(complex_input); - assert(real_result.dims == 3); -#ifdef BIG_BATCH - assert(real_result.size[0] == 1 || real_result.size[0] == int(m_num_of_scales)); -#else - assert(real_result.size[0] == 1); -#endif - assert(real_result.size[1] == int(m_height)); - assert(real_result.size[2] == int(m_width)); - - assert(int(complex_input.cols) == freq_size(cv::Size(m_width, m_height)).width); - assert(int(complex_input.rows) == freq_size(cv::Size(m_width, m_height)).height); - assert(complex_input.channels() == uint(real_result.size[0])); - - (void)complex_input; - (void)real_result; -} - -// REPLACEMENT void Fft::inverse(cv::Mat &complex_input, cv::Mat &real_result) { TRACE(""); diff --git a/src/fft.h b/src/fft.h index d80b7668..dfe9650d 100644 --- a/src/fft.h +++ b/src/fft.h @@ -19,11 +19,7 @@ class Fft { public: void init(unsigned width, unsigned height, unsigned num_of_feats, unsigned num_of_scales); - void set_window(const MatDynMem &window); - void forward(const MatScales &real_input, ComplexMat &complex_result); - void forward_window(MatScaleFeats &patch_feats_in, ComplexMat &complex_result, MatScaleFeats &tmp); - void inverse(ComplexMat &complex_input, MatScales &real_result); - + void set_window(const cv::Mat &window); void forward(const cv::Mat &real_input, cv::Mat &complex_result); void forward_window(cv::Mat &patch_feats, cv::Mat &complex_result, cv::Mat &tmp); void inverse(cv::Mat &complex_input, cv::Mat &real_result); diff --git a/src/fft_fftw.cpp b/src/fft_fftw.cpp index 7300fe7d..211500d5 100644 --- a/src/fft_fftw.cpp +++ b/src/fft_fftw.cpp @@ -72,27 +72,12 @@ void Fftw::init(unsigned width, unsigned height, unsigned num_of_feats, unsigned #endif } -void Fftw::set_window(const MatDynMem &window) +void Fftw::set_window(const cv::Mat &window) { Fft::set_window(window); m_window = window; } -void Fftw::forward(const MatScales &real_input, ComplexMat &complex_result) -{ - Fft::forward(real_input, complex_result); - - if (real_input.size[0] == 1) - fftwf_execute_dft_r2c(plan_f, reinterpret_cast(real_input.data), - reinterpret_cast(complex_result.get_p_data())); -#ifdef BIG_BATCH - else - fftwf_execute_dft_r2c(plan_f_all_scales, reinterpret_cast(real_input.data), - reinterpret_cast(complex_result.get_p_data())); -#endif -} - -// REPLACEMENT void Fftw::forward(const cv::Mat &real_input, cv::Mat &complex_result) { Fft::forward(real_input, complex_result); @@ -107,31 +92,6 @@ void Fftw::forward(const cv::Mat &real_input, cv::Mat &complex_result) #endif } -void Fftw::forward_window(MatScaleFeats &feat, ComplexMat & complex_result, MatScaleFeats &temp) -{ - Fft::forward_window(feat, complex_result, temp); - - uint n_scales = feat.size[0]; - for (uint s = 0; s < n_scales; ++s) { - for (uint ch = 0; ch < uint(feat.size[1]); ++ch) { - cv::Mat feat_plane = feat.plane(s, ch); - cv::Mat temp_plane = temp.plane(s, ch); - temp_plane = feat_plane.mul(m_window); - } - } - - float *in = temp.ptr(); - fftwf_complex *out = reinterpret_cast(complex_result.get_p_data()); - - if (n_scales == 1) - fftwf_execute_dft_r2c(plan_fw, in, out); -#ifdef BIG_BATCH - else - fftwf_execute_dft_r2c(plan_fw_all_scales, in, out); -#endif -} - -// REPLACEMENT void Fftw::forward_window(cv::Mat &feat, cv::Mat & complex_result, cv::Mat &temp) { Fft::forward_window(feat, complex_result, temp); @@ -155,25 +115,6 @@ void Fftw::forward_window(cv::Mat &feat, cv::Mat & complex_result, cv::Mat &temp #endif } - -void Fftw::inverse(ComplexMat &complex_input, MatScales &real_result) -{ - Fft::inverse(complex_input, real_result); - - int n_channels = complex_input.n_channels; - fftwf_complex *in = reinterpret_cast(complex_input.get_p_data()); - float *out = real_result.ptr(); - - if (n_channels == 1) - fftwf_execute_dft_c2r(plan_i_1ch, in, out); -#ifdef BIG_BATCH - else - fftwf_execute_dft_c2r(plan_i_all_scales, in, out); -#endif - real_result *= 1.0 / (m_width * m_height); -} - -// REPLACEMENT void Fftw::inverse(cv::Mat &complex_input, cv::Mat &real_result) { Fft::inverse(complex_input, real_result); diff --git a/src/fft_fftw.h b/src/fft_fftw.h index 448989a2..2db51aaf 100644 --- a/src/fft_fftw.h +++ b/src/fft_fftw.h @@ -14,12 +14,9 @@ class Fftw : public Fft public: Fftw(); void init(unsigned width, unsigned height, unsigned num_of_feats, unsigned num_of_scales); - void set_window(const MatDynMem &window); - void forward(const MatScales &real_input, ComplexMat &complex_result); + void set_window(const cv::Mat &window); void forward(const cv::Mat &real_input, cv::Mat &complex_result); - void forward_window(MatScaleFeats &patch_feats_in, ComplexMat &complex_result, MatScaleFeats &tmp); void forward_window(cv::Mat &feat, cv::Mat & complex_result, cv::Mat &temp); - void inverse(ComplexMat &complex_input, MatScales &real_result); void inverse(cv::Mat &complex_input, cv::Mat &real_result); ~Fftw(); diff --git a/src/fft_opencv.cpp b/src/fft_opencv.cpp index 83cb6720..6a3ab1b4 100644 --- a/src/fft_opencv.cpp +++ b/src/fft_opencv.cpp @@ -8,21 +8,11 @@ void FftOpencv::init(unsigned width, unsigned height, unsigned num_of_feats, uns std::cout << "FFT: OpenCV" << std::endl; } -void FftOpencv::set_window(const MatDynMem &window) +void FftOpencv::set_window(const cv::Mat &window) { m_window = window; } -void FftOpencv::forward(const MatScales &real_input, ComplexMat &complex_result) -{ - Fft::forward(real_input, complex_result); - - cv::Mat tmp; - cv::dft(real_input.plane(0), tmp, cv::DFT_COMPLEX_OUTPUT); - complex_result = ComplexMat(tmp); -} - -// REPLACEMENT void FftOpencv::forward(const cv::Mat &real_input, cv::Mat &complex_result) { Fft::forward(real_input, complex_result); @@ -30,21 +20,6 @@ void FftOpencv::forward(const cv::Mat &real_input, cv::Mat &complex_result) cv::dft(real_input, complex_result, cv::DFT_COMPLEX_OUTPUT); } -void FftOpencv::forward_window(MatScaleFeats &feat, ComplexMat &complex_result, MatScaleFeats &temp) -{ - Fft::forward_window(feat, complex_result, temp); - - for (uint i = 0; i < uint(feat.size[0]); ++i) { - 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(j), complex_res); - } - } -} - -// REPLACEMENT // Real and imag parts of complex elements from previous format are represented by 2 neighbouring channels. void FftOpencv::forward_window(cv::Mat &feat, cv::Mat &complex_result, cv::Mat &temp) { @@ -62,17 +37,6 @@ void FftOpencv::forward_window(cv::Mat &feat, cv::Mat &complex_result, cv::Mat & } } -void FftOpencv::inverse(ComplexMat & complex_input, MatScales & real_result) -{ - Fft::inverse(complex_input, real_result); - - std::vector mat_channels = complex_input.to_cv_mat_vector(); - for (uint i = 0; i < uint(complex_input.n_channels); ++i) { - cv::dft(mat_channels[i], real_result.plane(i), cv::DFT_INVERSE | cv::DFT_REAL_OUTPUT | cv::DFT_SCALE); - } -} - -// REPLACEMENT void FftOpencv::inverse(cv::Mat &complex_input, cv::Mat &real_result) { Fft::inverse(complex_input, real_result); diff --git a/src/fft_opencv.h b/src/fft_opencv.h index cdf462e4..7e50c10a 100644 --- a/src/fft_opencv.h +++ b/src/fft_opencv.h @@ -8,15 +8,9 @@ class FftOpencv : public Fft { public: void init(unsigned width, unsigned height, unsigned num_of_feats, unsigned num_of_scales); - void set_window(const MatDynMem &window); - void forward(const MatScales &real_input, ComplexMat &complex_result); - void forward_window(MatScaleFeats &patch_feats_in, ComplexMat &complex_result, MatScaleFeats &tmp); - - //REPLACEMENT + void set_window(const cv::Mat &window); void forward(const cv::Mat &real_input, cv::Mat &complex_result); void forward_window(cv::Mat &feat, cv::Mat &complex_result, cv::Mat &temp); - - void inverse(ComplexMat &complex_input, MatScales &real_result); void inverse(cv::Mat &complex_input, cv::Mat &real_result); ~FftOpencv(); private: From e114a4870b47862b90d2680ebc0f3ff1b296ddd6 Mon Sep 17 00:00:00 2001 From: Your Name Date: Wed, 8 Jan 2020 20:52:47 +0100 Subject: [PATCH 068/121] =?UTF-8?q?Odstran=C4=9Bn=20k=C3=B3d=20ComplexMat?= =?UTF-8?q?=20a=20DynMem=20ze=20souboru=20ThreadCtx?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- src/threadctx.hpp | 8 -------- 1 file changed, 8 deletions(-) diff --git a/src/threadctx.hpp b/src/threadctx.hpp index 1576d50f..3db300a9 100644 --- a/src/threadctx.hpp +++ b/src/threadctx.hpp @@ -66,13 +66,6 @@ struct ThreadCtx { uint num_angles; cv::Size freq_size = Fft::freq_size(roi); - MatScaleFeats patch_feats{num_scales * num_angles, num_features, roi}; - MatScaleFeats temp{num_scales * num_angles, num_features, roi}; - - ComplexMat zf{uint(freq_size.height), uint(freq_size.width), num_features, num_scales * num_angles}; - ComplexMat kzf{uint(freq_size.height), uint(freq_size.width), 1, num_scales * num_angles}; - - // REPLACEMENT cv::Mat patch_feats_Test{ 4, std::vector({ int(num_scales * num_angles), int(num_features), roi.height, roi.width}).data(), CV_32F}; cv::Mat temp_Test{ 4, std::vector({ int(num_scales * num_angles), int(num_features), roi.height, roi.width}).data(), CV_32F}; @@ -87,7 +80,6 @@ struct ThreadCtx { std::future async_res; #endif - MatScales response{num_scales * num_angles, roi}; cv::Mat response_Test = cv::Mat(3, std::vector({int(num_scales * num_angles), (int) roi.height, (int) roi.width}).data(), CV_32F); struct Max { From 8b48ae8d9eacb8c3d3a43040ceb441ea53ac4a77 Mon Sep 17 00:00:00 2001 From: Your Name Date: Wed, 8 Jan 2020 21:30:29 +0100 Subject: [PATCH 069/121] =?UTF-8?q?Odstran=C4=9Bn=20k=C3=B3d=20ComplexMat?= =?UTF-8?q?=20a=20DynMem=20ze=20souboru=20fft=5Ffftw.cpp?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- src/fft_fftw.cpp | 8 ++++---- 1 file changed, 4 insertions(+), 4 deletions(-) diff --git a/src/fft_fftw.cpp b/src/fft_fftw.cpp index 211500d5..fa1ad374 100644 --- a/src/fft_fftw.cpp +++ b/src/fft_fftw.cpp @@ -11,9 +11,9 @@ Fftw::Fftw(){} fftwf_plan Fftw::create_plan_fwd(uint howmany) const { cv::Mat mat_in = cv::Mat::zeros(howmany * m_height, m_width, CV_32F); - ComplexMat mat_out(m_height, m_width / 2 + 1, howmany); + cv::Mat mat_out = cv::Mat::zeros(m_height, m_width / 2 + 1, CV_32FC(howmany * 2)); float *in = reinterpret_cast(mat_in.data); - fftwf_complex *out = reinterpret_cast(mat_out.get_p_data()); + fftwf_complex *out = reinterpret_cast(mat_out.ptr>(0)); int rank = 2; int n[] = {(int)m_height, (int)m_width}; @@ -26,9 +26,9 @@ fftwf_plan Fftw::create_plan_fwd(uint howmany) const fftwf_plan Fftw::create_plan_inv(uint howmany) const { - ComplexMat mat_in(m_height, m_width / 2 + 1, howmany); + cv::Mat mat_in = cv::Mat::zeros(m_height, m_width / 2 + 1, CV_32FC(howmany * 2)); cv::Mat mat_out = cv::Mat::zeros(howmany * m_height, m_width, CV_32F); - fftwf_complex *in = reinterpret_cast(mat_in.get_p_data()); + fftwf_complex *in = reinterpret_cast(mat_in.ptr>(0)); float *out = reinterpret_cast(mat_out.data); int rank = 2; From 09a9074a0124bef897253bede0b71324f9d9adc5 Mon Sep 17 00:00:00 2001 From: Your Name Date: Wed, 8 Jan 2020 21:36:26 +0100 Subject: [PATCH 070/121] =?UTF-8?q?Odstran=C4=9Bn=20k=C3=B3d=20ComplexMat?= =?UTF-8?q?=20a=20DynMem=20z=20cel=C3=A9ho=20projektu,=20v=C4=8Detn=C4=9B?= =?UTF-8?q?=20referenc=C3=AD.=20-=20v=20tuto=20chv=C3=ADli=20je=20bezpe?= =?UTF-8?q?=C4=8Dn=C3=A9=20smazat=20soubory=20complexmat.cpp,=20complexmat?= =?UTF-8?q?.hpp=20a=20dynmem.hpp?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- src/complexmat.cpp | 298 ++++++++++++++++---------------- src/complexmat.hpp | 362 +++++++++++++++++++------------------- src/debug.cpp | 15 -- src/debug.h | 7 - src/dynmem.hpp | 420 ++++++++++++++++++++++----------------------- src/fft.h | 1 - src/fft_cufft.cpp | 104 +++-------- src/fft_cufft.h | 5 +- src/kcf.cpp | 139 +++------------ src/kcf.h | 25 --- src/matutil.h | 1 + src/threadctx.hpp | 2 - 12 files changed, 588 insertions(+), 791 deletions(-) diff --git a/src/complexmat.cpp b/src/complexmat.cpp index 97e1ca78..5ce178fc 100644 --- a/src/complexmat.cpp +++ b/src/complexmat.cpp @@ -1,149 +1,149 @@ -#include "complexmat.hpp" - -ComplexMat_::T ComplexMat_::sqr_norm() const -{ - assert(n_scales == 1); - - int n_channels_per_scale = n_channels / n_scales; - T sum_sqr_norm = 0; - for (int i = 0; i < n_channels_per_scale; ++i) { - for (auto lhs = p_data.hostMem() + i * rows * cols; lhs != p_data.hostMem() + (i + 1) * rows * cols; ++lhs) - sum_sqr_norm += lhs->real() * lhs->real() + lhs->imag() * lhs->imag(); - } - sum_sqr_norm = sum_sqr_norm / static_cast(cols * rows); - return sum_sqr_norm; -} - -void ComplexMat_::sqr_norm(DynMem_ &result) const -{ - int n_channels_per_scale = n_channels / n_scales; - int scale_offset = n_channels_per_scale * rows * cols; - 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.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(cols * rows); - } - return; -} - -ComplexMat_ ComplexMat_::sqr_mag() const -{ - return mat_const_operator([](std::complex &c) { c = c.real() * c.real() + c.imag() * c.imag(); }); -} - -ComplexMat_ ComplexMat_::conj() const -{ - return mat_const_operator([](std::complex &c) { c = std::complex(c.real(), -c.imag()); }); -} - -ComplexMat_ ComplexMat_::sum_over_channels() const -{ - 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; - - ComplexMat_ result(this->rows, this->cols, 1, n_scales); - for (uint scale = 0; scale < n_scales; ++scale) { - for (uint i = 0; i < rows * cols; ++i) { - std::complex 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.hostMem()[scale * rows * cols + i] = acc; - } - } - return result; -} - -ComplexMat_ ComplexMat_::operator/(const ComplexMat_ &rhs) const -{ - return mat_mat_operator([](std::complex &c_lhs, const std::complex &c_rhs) { c_lhs /= c_rhs; }, rhs); -} - -ComplexMat_ ComplexMat_::operator+(const ComplexMat_ &rhs) const -{ - return mat_mat_operator([](std::complex &c_lhs, const std::complex &c_rhs) { c_lhs += c_rhs; }, rhs); -} - -ComplexMat_ ComplexMat_::operator*(const ComplexMat_::T &rhs) const -{ - return mat_const_operator([&rhs](std::complex &c) { c *= rhs; }); -} - -ComplexMat_ ComplexMat_::mul(const ComplexMat_ &rhs) const -{ - return matn_mat1_operator([](std::complex &c_lhs, const std::complex &c_rhs) { c_lhs *= c_rhs; }, rhs); -} - -ComplexMat_ ComplexMat_::operator+(const ComplexMat_::T &rhs) const -{ - return mat_const_operator([&rhs](std::complex &c) { c += rhs; }); -} - -ComplexMat_ ComplexMat_::operator*(const ComplexMat_ &rhs) const -{ - return mat_mat_operator([](std::complex &c_lhs, const std::complex &c_rhs) { c_lhs *= c_rhs; }, rhs); -} - -ComplexMat_ ComplexMat_::mat_mat_operator(void (*op)(std::complex &, const std::complex &), const ComplexMat_ &mat_rhs) const -{ - assert(mat_rhs.n_channels == n_channels/n_scales && mat_rhs.cols == cols && mat_rhs.rows == rows); - - ComplexMat_ result = *this; - for (uint s = 0; s < n_scales; ++s) { - 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)); - } - - return result; -} - -ComplexMat_ ComplexMat_::matn_mat1_operator(void (*op)(std::complex &, const std::complex &), const ComplexMat_ &mat_rhs) const -{ - assert(mat_rhs.n_channels == 1 && mat_rhs.cols == cols && mat_rhs.rows == rows); - - ComplexMat_ result = *this; - for (uint i = 0; i < n_channels; ++i) { - 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); - } - - return result; -} - -ComplexMat_ ComplexMat_::matn_mat2_operator(void (*op)(std::complex &, const std::complex &), const ComplexMat_ &mat_rhs) const -{ - assert(mat_rhs.n_channels == n_channels / n_scales && mat_rhs.cols == cols && mat_rhs.rows == rows); - - int n_channels_per_scale = n_channels / n_scales; - int scale_offset = n_channels_per_scale * rows * cols; - ComplexMat_ result = *this; - for (uint i = 0; i < n_scales; ++i) { - for (int j = 0; j < n_channels_per_scale; ++j) { - auto lhs = result.p_data.hostMem() + (j * rows * cols) + (i * scale_offset); - auto rhs = mat_rhs.p_data.hostMem() + (j * rows * cols); - for (; lhs != result.p_data.hostMem() + ((j + 1) * rows * cols) + (i * scale_offset); ++lhs, ++rhs) - op(*lhs, *rhs); - } - } - - return result; -} - -ComplexMat_ ComplexMat_::mat_const_operator(const std::function &)> &op) const -{ - ComplexMat_ result = *this; - for (uint i = 0; i < n_channels; ++i) { - for (auto lhs = result.p_data.hostMem() + i * rows * cols; - lhs != result.p_data.hostMem() + (i + 1) * rows * cols; ++lhs) - op(*lhs); - } - return result; -} +//#include "complexmat.hpp" +// +//ComplexMat_::T ComplexMat_::sqr_norm() const +//{ +// assert(n_scales == 1); +// +// int n_channels_per_scale = n_channels / n_scales; +// T sum_sqr_norm = 0; +// for (int i = 0; i < n_channels_per_scale; ++i) { +// for (auto lhs = p_data.hostMem() + i * rows * cols; lhs != p_data.hostMem() + (i + 1) * rows * cols; ++lhs) +// sum_sqr_norm += lhs->real() * lhs->real() + lhs->imag() * lhs->imag(); +// } +// sum_sqr_norm = sum_sqr_norm / static_cast(cols * rows); +// return sum_sqr_norm; +//} +// +//void ComplexMat_::sqr_norm(DynMem_ &result) const +//{ +// int n_channels_per_scale = n_channels / n_scales; +// int scale_offset = n_channels_per_scale * rows * cols; +// 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.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(cols * rows); +// } +// return; +//} +// +//ComplexMat_ ComplexMat_::sqr_mag() const +//{ +// return mat_const_operator([](std::complex &c) { c = c.real() * c.real() + c.imag() * c.imag(); }); +//} +// +//ComplexMat_ ComplexMat_::conj() const +//{ +// return mat_const_operator([](std::complex &c) { c = std::complex(c.real(), -c.imag()); }); +//} +// +//ComplexMat_ ComplexMat_::sum_over_channels() const +//{ +// 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; +// +// ComplexMat_ result(this->rows, this->cols, 1, n_scales); +// for (uint scale = 0; scale < n_scales; ++scale) { +// for (uint i = 0; i < rows * cols; ++i) { +// std::complex 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.hostMem()[scale * rows * cols + i] = acc; +// } +// } +// return result; +//} +// +//ComplexMat_ ComplexMat_::operator/(const ComplexMat_ &rhs) const +//{ +// return mat_mat_operator([](std::complex &c_lhs, const std::complex &c_rhs) { c_lhs /= c_rhs; }, rhs); +//} +// +//ComplexMat_ ComplexMat_::operator+(const ComplexMat_ &rhs) const +//{ +// return mat_mat_operator([](std::complex &c_lhs, const std::complex &c_rhs) { c_lhs += c_rhs; }, rhs); +//} +// +//ComplexMat_ ComplexMat_::operator*(const ComplexMat_::T &rhs) const +//{ +// return mat_const_operator([&rhs](std::complex &c) { c *= rhs; }); +//} +// +//ComplexMat_ ComplexMat_::mul(const ComplexMat_ &rhs) const +//{ +// return matn_mat1_operator([](std::complex &c_lhs, const std::complex &c_rhs) { c_lhs *= c_rhs; }, rhs); +//} +// +//ComplexMat_ ComplexMat_::operator+(const ComplexMat_::T &rhs) const +//{ +// return mat_const_operator([&rhs](std::complex &c) { c += rhs; }); +//} +// +//ComplexMat_ ComplexMat_::operator*(const ComplexMat_ &rhs) const +//{ +// return mat_mat_operator([](std::complex &c_lhs, const std::complex &c_rhs) { c_lhs *= c_rhs; }, rhs); +//} +// +//ComplexMat_ ComplexMat_::mat_mat_operator(void (*op)(std::complex &, const std::complex &), const ComplexMat_ &mat_rhs) const +//{ +// assert(mat_rhs.n_channels == n_channels/n_scales && mat_rhs.cols == cols && mat_rhs.rows == rows); +// +// ComplexMat_ result = *this; +// for (uint s = 0; s < n_scales; ++s) { +// 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)); +// } +// +// return result; +//} +// +//ComplexMat_ ComplexMat_::matn_mat1_operator(void (*op)(std::complex &, const std::complex &), const ComplexMat_ &mat_rhs) const +//{ +// assert(mat_rhs.n_channels == 1 && mat_rhs.cols == cols && mat_rhs.rows == rows); +// +// ComplexMat_ result = *this; +// for (uint i = 0; i < n_channels; ++i) { +// 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); +// } +// +// return result; +//} +// +//ComplexMat_ ComplexMat_::matn_mat2_operator(void (*op)(std::complex &, const std::complex &), const ComplexMat_ &mat_rhs) const +//{ +// assert(mat_rhs.n_channels == n_channels / n_scales && mat_rhs.cols == cols && mat_rhs.rows == rows); +// +// int n_channels_per_scale = n_channels / n_scales; +// int scale_offset = n_channels_per_scale * rows * cols; +// ComplexMat_ result = *this; +// for (uint i = 0; i < n_scales; ++i) { +// for (int j = 0; j < n_channels_per_scale; ++j) { +// auto lhs = result.p_data.hostMem() + (j * rows * cols) + (i * scale_offset); +// auto rhs = mat_rhs.p_data.hostMem() + (j * rows * cols); +// for (; lhs != result.p_data.hostMem() + ((j + 1) * rows * cols) + (i * scale_offset); ++lhs, ++rhs) +// op(*lhs, *rhs); +// } +// } +// +// return result; +//} +// +//ComplexMat_ ComplexMat_::mat_const_operator(const std::function &)> &op) const +//{ +// ComplexMat_ result = *this; +// for (uint i = 0; i < n_channels; ++i) { +// for (auto lhs = result.p_data.hostMem() + i * rows * cols; +// lhs != result.p_data.hostMem() + (i + 1) * rows * cols; ++lhs) +// op(*lhs); +// } +// return result; +//} diff --git a/src/complexmat.hpp b/src/complexmat.hpp index f6aaef26..0d5e69f9 100644 --- a/src/complexmat.hpp +++ b/src/complexmat.hpp @@ -1,181 +1,181 @@ -#ifndef COMPLEX_MAT_HPP_213123048309482094 -#define COMPLEX_MAT_HPP_213123048309482094 - -#include -#include -#include -#include -#include "dynmem.hpp" -#include "pragmas.h" - -#ifdef CUFFT -#include -#endif - -class ComplexMat_ { - public: - typedef float T; - - uint cols; - uint rows; - uint n_channels; - 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(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(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) - { - cudaSync(); - memcpy(p_data.hostMem(), mat.ptr>(), mat.total() * mat.elemSize()); - } - - static ComplexMat_ same_size(const ComplexMat_ &o) - { - return ComplexMat_(o.rows, o.cols, o.n_channels / o.n_scales, o.n_scales); - } - - // cv::Mat API compatibility - cv::Size size() const { return cv::Size(cols, rows); } - uint channels() const { return n_channels; } - - // assuming that mat has 2 channels (real, imag) - void set_channel(uint idx, const cv::Mat &mat) - { - assert(idx < n_channels); - cudaSync(); - for (uint i = 0; i < rows; ++i) { - const std::complex *row = mat.ptr>(i); - for (uint j = 0; j < cols; ++j) - p_data.hostMem()[idx * rows * cols + i * cols + j] = row[j]; - } - } - - T sqr_norm() const; - - void sqr_norm(DynMem_ &result) const; - - ComplexMat_ sqr_mag() const; - - ComplexMat_ conj() const; - - ComplexMat_ sum_over_channels() const; - - // return 2 channels (real, imag) for first complex channel - cv::Mat to_cv_mat() const - { - assert(p_data.num_elem >= 1); - return channel_to_cv_mat(0); - } - // return a vector of 2 channels (real, imag) per one complex channel - std::vector to_cv_mat_vector() const - { - std::vector result; - result.reserve(n_channels); - - for (uint i = 0; i < n_channels; ++i) - result.push_back(channel_to_cv_mat(i)); - - return result; - } - - std::complex *get_p_data() { - cudaSync(); - return p_data.hostMem(); - } - const std::complex *get_p_data() const { - cudaSync(); - return p_data.hostMem(); - } - -#ifdef CUFFT - cufftComplex *get_dev_data() { return (cufftComplex*)p_data.deviceMem(); } - const cufftComplex *get_dev_data() const { return (cufftComplex*)p_data.deviceMem(); } -#endif - - // element-wise per channel multiplication, division and addition - ComplexMat_ operator*(const ComplexMat_ &rhs) const; - ComplexMat_ operator/(const ComplexMat_ &rhs) const; - ComplexMat_ operator+(const ComplexMat_ &rhs) const; - - // multiplying or adding constant - ComplexMat_ operator*(const T &rhs) const; - ComplexMat_ operator+(const T &rhs) const; - - // multiplying element-wise multichannel by one channel mats (rhs mat is with one channel) - ComplexMat_ mul(const ComplexMat_ &rhs) const; - - // multiplying element-wise multichannel mats - same as operator*(ComplexMat), but without allocating memory for the result - ComplexMat_ muln(const ComplexMat_ &rhs) const - { - return mat_mat_operator([](std::complex &c_lhs, const std::complex &c_rhs) { c_lhs *= c_rhs; }, rhs); - } - - // text output - friend std::ostream &operator<<(std::ostream &os, const ComplexMat_ &mat) - { - // for (int i = 0; i < mat.n_channels; ++i){ - for (int i = 0; i < 1; ++i) { - os << "Channel " << i << std::endl; - for (uint j = 0; j < mat.rows; ++j) { - for (uint k = 0; k < mat.cols - 1; ++k) - os << mat.p_data[j * mat.cols + k] << ", "; - os << mat.p_data[j * mat.cols + mat.cols - 1] << std::endl; - } - } - return os; - } - - private: - DynMem_> p_data; - - // convert 2 channel mat (real, imag) to vector row-by-row - std::vector> convert(const cv::Mat &mat) - { - std::vector> result; - result.reserve(mat.cols * mat.rows); - for (int y = 0; y < mat.rows; ++y) { - const T *row_ptr = mat.ptr(y); - for (int x = 0; x < 2 * mat.cols; x += 2) { - result.push_back(std::complex(row_ptr[x], row_ptr[x + 1])); - } - } - return result; - } - - ComplexMat_ mat_mat_operator(void (*op)(std::complex &c_lhs, const std::complex &c_rhs), - const ComplexMat_ &mat_rhs) const; - ComplexMat_ matn_mat1_operator(void (*op)(std::complex &c_lhs, const std::complex &c_rhs), - const ComplexMat_ &mat_rhs) const; - ComplexMat_ matn_mat2_operator(void (*op)(std::complex &c_lhs, const std::complex &c_rhs), - const ComplexMat_ &mat_rhs) const; - ComplexMat_ mat_const_operator(const std::function &c_rhs)> &op) const; - - cv::Mat channel_to_cv_mat(int channel_id) const - { - cv::Mat result(rows, cols, CV_32FC2); - for (uint y = 0; y < rows; ++y) { - std::complex *row_ptr = result.ptr>(y); - for (uint x = 0; x < cols; ++x) { - row_ptr[x] = p_data[channel_id * rows * cols + y * cols + x]; - } - } - return result; - } - -#ifdef CUFFT - void cudaSync() const; -#else - void cudaSync() const {} -#endif -}; - -typedef ComplexMat_ ComplexMat; - -#endif // COMPLEX_MAT_HPP_213123048309482094 +//#ifndef COMPLEX_MAT_HPP_213123048309482094 +//#define COMPLEX_MAT_HPP_213123048309482094 +// +//#include +//#include +//#include +//#include +//#include "dynmem.hpp" +//#include "pragmas.h" +// +//#ifdef CUFFT +//#include +//#endif +// +//class ComplexMat_ { +// public: +// typedef float T; +// +// uint cols; +// uint rows; +// uint n_channels; +// 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(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(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) +// { +// cudaSync(); +// memcpy(p_data.hostMem(), mat.ptr>(), mat.total() * mat.elemSize()); +// } +// +// static ComplexMat_ same_size(const ComplexMat_ &o) +// { +// return ComplexMat_(o.rows, o.cols, o.n_channels / o.n_scales, o.n_scales); +// } +// +// // cv::Mat API compatibility +// cv::Size size() const { return cv::Size(cols, rows); } +// uint channels() const { return n_channels; } +// +// // assuming that mat has 2 channels (real, imag) +// void set_channel(uint idx, const cv::Mat &mat) +// { +// assert(idx < n_channels); +// cudaSync(); +// for (uint i = 0; i < rows; ++i) { +// const std::complex *row = mat.ptr>(i); +// for (uint j = 0; j < cols; ++j) +// p_data.hostMem()[idx * rows * cols + i * cols + j] = row[j]; +// } +// } +// +// T sqr_norm() const; +// +// void sqr_norm(DynMem_ &result) const; +// +// ComplexMat_ sqr_mag() const; +// +// ComplexMat_ conj() const; +// +// ComplexMat_ sum_over_channels() const; +// +// // return 2 channels (real, imag) for first complex channel +// cv::Mat to_cv_mat() const +// { +// assert(p_data.num_elem >= 1); +// return channel_to_cv_mat(0); +// } +// // return a vector of 2 channels (real, imag) per one complex channel +// std::vector to_cv_mat_vector() const +// { +// std::vector result; +// result.reserve(n_channels); +// +// for (uint i = 0; i < n_channels; ++i) +// result.push_back(channel_to_cv_mat(i)); +// +// return result; +// } +// +// std::complex *get_p_data() { +// cudaSync(); +// return p_data.hostMem(); +// } +// const std::complex *get_p_data() const { +// cudaSync(); +// return p_data.hostMem(); +// } +// +//#ifdef CUFFT +// cufftComplex *get_dev_data() { return (cufftComplex*)p_data.deviceMem(); } +// const cufftComplex *get_dev_data() const { return (cufftComplex*)p_data.deviceMem(); } +//#endif +// +// // element-wise per channel multiplication, division and addition +// ComplexMat_ operator*(const ComplexMat_ &rhs) const; +// ComplexMat_ operator/(const ComplexMat_ &rhs) const; +// ComplexMat_ operator+(const ComplexMat_ &rhs) const; +// +// // multiplying or adding constant +// ComplexMat_ operator*(const T &rhs) const; +// ComplexMat_ operator+(const T &rhs) const; +// +// // multiplying element-wise multichannel by one channel mats (rhs mat is with one channel) +// ComplexMat_ mul(const ComplexMat_ &rhs) const; +// +// // multiplying element-wise multichannel mats - same as operator*(ComplexMat), but without allocating memory for the result +// ComplexMat_ muln(const ComplexMat_ &rhs) const +// { +// return mat_mat_operator([](std::complex &c_lhs, const std::complex &c_rhs) { c_lhs *= c_rhs; }, rhs); +// } +// +// // text output +// friend std::ostream &operator<<(std::ostream &os, const ComplexMat_ &mat) +// { +// // for (int i = 0; i < mat.n_channels; ++i){ +// for (int i = 0; i < 1; ++i) { +// os << "Channel " << i << std::endl; +// for (uint j = 0; j < mat.rows; ++j) { +// for (uint k = 0; k < mat.cols - 1; ++k) +// os << mat.p_data[j * mat.cols + k] << ", "; +// os << mat.p_data[j * mat.cols + mat.cols - 1] << std::endl; +// } +// } +// return os; +// } +// +// private: +// DynMem_> p_data; +// +// // convert 2 channel mat (real, imag) to vector row-by-row +// std::vector> convert(const cv::Mat &mat) +// { +// std::vector> result; +// result.reserve(mat.cols * mat.rows); +// for (int y = 0; y < mat.rows; ++y) { +// const T *row_ptr = mat.ptr(y); +// for (int x = 0; x < 2 * mat.cols; x += 2) { +// result.push_back(std::complex(row_ptr[x], row_ptr[x + 1])); +// } +// } +// return result; +// } +// +// ComplexMat_ mat_mat_operator(void (*op)(std::complex &c_lhs, const std::complex &c_rhs), +// const ComplexMat_ &mat_rhs) const; +// ComplexMat_ matn_mat1_operator(void (*op)(std::complex &c_lhs, const std::complex &c_rhs), +// const ComplexMat_ &mat_rhs) const; +// ComplexMat_ matn_mat2_operator(void (*op)(std::complex &c_lhs, const std::complex &c_rhs), +// const ComplexMat_ &mat_rhs) const; +// ComplexMat_ mat_const_operator(const std::function &c_rhs)> &op) const; +// +// cv::Mat channel_to_cv_mat(int channel_id) const +// { +// cv::Mat result(rows, cols, CV_32FC2); +// for (uint y = 0; y < rows; ++y) { +// std::complex *row_ptr = result.ptr>(y); +// for (uint x = 0; x < cols; ++x) { +// row_ptr[x] = p_data[channel_id * rows * cols + y * cols + x]; +// } +// } +// return result; +// } +// +//#ifdef CUFFT +// void cudaSync() const; +//#else +// void cudaSync() const {} +//#endif +//}; +// +//typedef ComplexMat_ ComplexMat; +// +//#endif // COMPLEX_MAT_HPP_213123048309482094 diff --git a/src/debug.cpp b/src/debug.cpp index 808bd83f..c47e1387 100644 --- a/src/debug.cpp +++ b/src/debug.cpp @@ -14,18 +14,3 @@ std::ostream &operator<<(std::ostream &os, const DbgTracer::Printer &p) return os; } -std::ostream &operator<<(std::ostream &os, const DbgTracer::Printer &p) -{ - IOSave s(os); - os << std::setprecision(DbgTracer::precision); - os << " " << p.obj.size() << " " << p.obj.channels() << "ch "; // << p.obj.get_p_data(); - const int num = 10; //p.obj.rows * p.obj.cols * p.obj.n_channels / p.obj.n_scales; - for (uint s = 0; s < p.obj.n_scales; ++s) { - uint ofs = s * p.obj.rows * p.obj.cols * p.obj.n_channels / p.obj.n_scales; - os << " = [ "; - for (int i = 0; i < std::min(num, p.obj.size().area()); ++i) - os << p.obj.get_p_data()[ofs + i] << ", "; - os << (num < p.obj.size().area() ? "... ]" : "]"); - } - return os; -} diff --git a/src/debug.h b/src/debug.h index cce83272..18707ec1 100644 --- a/src/debug.h +++ b/src/debug.h @@ -6,8 +6,6 @@ #include #include #include -#include "dynmem.hpp" -#include "complexmat.hpp" #ifdef CUFFT #include @@ -95,9 +93,6 @@ class DbgTracer { }; template Printer print(const T& obj) { return Printer(obj); } - Printer print(const MatScales& obj) { return Printer(obj); } - Printer print(const MatFeats& obj) { return Printer(obj); } - Printer print(const MatScaleFeats& obj) { return Printer(obj); } }; template @@ -130,8 +125,6 @@ static inline std::ostream &operator<<(std::ostream &os, const cufftComplex &p) } #endif -std::ostream &operator<<(std::ostream &os, const DbgTracer::Printer &p); - extern DbgTracer __dbgTracer; #define TRACE(...) const DbgTracer::FTrace __tracer(__dbgTracer, __PRETTY_FUNCTION__, ##__VA_ARGS__) diff --git a/src/dynmem.hpp b/src/dynmem.hpp index 8e496432..39ee10ca 100644 --- a/src/dynmem.hpp +++ b/src/dynmem.hpp @@ -1,210 +1,210 @@ -#ifndef DYNMEM_HPP -#define DYNMEM_HPP - -#include -#include -#include -#include -#include -#include - -#if defined(CUFFT) || defined(CUFFTW) -#include "cuda_runtime.h" -#ifdef CUFFT -#include "cuda_error_check.hpp" -#endif -#endif - -class MemoryManager { - std::mutex mutex; - std::map > map; - -public: - void *get(size_t size) { - std::lock_guard guard(mutex); - auto &stack = map[size]; - void *ptr = nullptr; - if (!stack.empty()) { - ptr = stack.top(); - stack.pop(); - } - return ptr; - } - void put(void *ptr, size_t size) { - std::lock_guard guard(mutex); - map[size].push(ptr); - } -}; - -template class DynMem_ { - private: - T *ptr_h = nullptr; -#ifdef CUFFT - T *ptr_d = nullptr; - static MemoryManager mmng; -#endif - public: - typedef T value_type; - const size_t num_elem; - - DynMem_(size_t num_elem) : num_elem(num_elem) - { -#ifdef CUFFT - ptr_h = reinterpret_cast(mmng.get(num_elem)); - if (!ptr_h) - CudaSafeCall(cudaHostAlloc(reinterpret_cast(&ptr_h), num_elem * sizeof(T), cudaHostAllocMapped)); - - CudaSafeCall(cudaHostGetDevicePointer(reinterpret_cast(&ptr_d), reinterpret_cast(ptr_h), 0)); -#else - 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; - other.ptr_h = nullptr; -#ifdef CUFFT - ptr_d = other.ptr_d; - other.ptr_d = nullptr; -#endif - } - ~DynMem_() - { - release(); - } - T *hostMem() { return ptr_h; } - const T *hostMem() const { return ptr_h; } -#ifdef CUFFT - T *deviceMem() { return ptr_d; } - const T *deviceMem() const { return ptr_d; } -#endif - void operator=(DynMem_ &rhs) { - assert(num_elem == rhs.num_elem); - memcpy(ptr_h, rhs.ptr_h, num_elem * sizeof(T)); - } - void operator=(DynMem_ &&rhs) - { - assert(num_elem == rhs.num_elem); - release(); - ptr_h = rhs.ptr_h; - rhs.ptr_h = nullptr; -#ifdef CUFFT - ptr_d = rhs.ptr_d; - rhs.ptr_d = nullptr; -#endif - } - T operator[](uint i) const { return ptr_h[i]; } -private: - void release() - { -#ifdef CUFFT - if (ptr_h) - mmng.put(ptr_h, num_elem); - //CudaSafeCall(cudaFreeHost(ptr_h)); -#else - delete[] ptr_h; -#endif - } -}; - -#ifdef CUFFT -template -MemoryManager DynMem_::mmng; -#endif - -typedef DynMem_ DynMem; - - -class MatDynMem : public DynMem, public cv::Mat { - public: - MatDynMem(cv::Size size, int type) - : DynMem(size.area() * CV_MAT_CN(type)), cv::Mat(size, type, hostMem()) - { - assert((type & CV_MAT_DEPTH_MASK) == CV_32F); - } - MatDynMem(int height, int width, int type) - : DynMem(width * height * CV_MAT_CN(type)), cv::Mat(height, width, type, hostMem()) - { - assert((type & CV_MAT_DEPTH_MASK) == CV_32F); - } - MatDynMem(int ndims, const int *sizes, int type) - : DynMem(volume(ndims, sizes) * CV_MAT_CN(type)), cv::Mat(ndims, sizes, type, hostMem()) - { - assert((type & CV_MAT_DEPTH_MASK) == CV_32F); - } - MatDynMem(std::vector size, int type) - : DynMem(std::accumulate(size.begin(), size.end(), 1, std::multiplies())) - , cv::Mat(size.size(), size.data(), type, hostMem()) {} - MatDynMem(MatDynMem &&other) = default; - MatDynMem(const cv::Mat &other) - : DynMem(other.total()) , cv::Mat(other) {} - - void operator=(const cv::MatExpr &expr) { - static_cast(*this) = expr; - } - - private: - static int volume(int ndims, const int *sizes) - { - int vol = 1; - for (int i = 0; i < ndims; i++) - vol *= sizes[i]; - return vol; - } - - 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)); - } - const cv::Mat plane(uint idx) const { - assert(dims == 3); - assert(int(idx) < size[0]); - return cv::Mat(size[1], size[2], cv::Mat::type(), const_cast(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)); - } - cv::Mat scale(uint scale) { - assert(dims == 4); - assert(int(scale) < size[0]); - return cv::Mat(3, std::vector({size[1], size[2], size[3]}).data(), cv::Mat::type(), ptr(scale)); - } -}; - -#endif // DYNMEM_HPP +//#ifndef DYNMEM_HPP +//#define DYNMEM_HPP +// +//#include +//#include +//#include +//#include +//#include +//#include +// +//#if defined(CUFFT) || defined(CUFFTW) +//#include "cuda_runtime.h" +//#ifdef CUFFT +//#include "cuda_error_check.hpp" +//#endif +//#endif +// +//class MemoryManager { +// std::mutex mutex; +// std::map > map; +// +//public: +// void *get(size_t size) { +// std::lock_guard guard(mutex); +// auto &stack = map[size]; +// void *ptr = nullptr; +// if (!stack.empty()) { +// ptr = stack.top(); +// stack.pop(); +// } +// return ptr; +// } +// void put(void *ptr, size_t size) { +// std::lock_guard guard(mutex); +// map[size].push(ptr); +// } +//}; +// +//template class DynMem_ { +// private: +// T *ptr_h = nullptr; +//#ifdef CUFFT +// T *ptr_d = nullptr; +// static MemoryManager mmng; +//#endif +// public: +// typedef T value_type; +// const size_t num_elem; +// +// DynMem_(size_t num_elem) : num_elem(num_elem) +// { +//#ifdef CUFFT +// ptr_h = reinterpret_cast(mmng.get(num_elem)); +// if (!ptr_h) +// CudaSafeCall(cudaHostAlloc(reinterpret_cast(&ptr_h), num_elem * sizeof(T), cudaHostAllocMapped)); +// +// CudaSafeCall(cudaHostGetDevicePointer(reinterpret_cast(&ptr_d), reinterpret_cast(ptr_h), 0)); +//#else +// 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; +// other.ptr_h = nullptr; +//#ifdef CUFFT +// ptr_d = other.ptr_d; +// other.ptr_d = nullptr; +//#endif +// } +// ~DynMem_() +// { +// release(); +// } +// T *hostMem() { return ptr_h; } +// const T *hostMem() const { return ptr_h; } +//#ifdef CUFFT +// T *deviceMem() { return ptr_d; } +// const T *deviceMem() const { return ptr_d; } +//#endif +// void operator=(DynMem_ &rhs) { +// assert(num_elem == rhs.num_elem); +// memcpy(ptr_h, rhs.ptr_h, num_elem * sizeof(T)); +// } +// void operator=(DynMem_ &&rhs) +// { +// assert(num_elem == rhs.num_elem); +// release(); +// ptr_h = rhs.ptr_h; +// rhs.ptr_h = nullptr; +//#ifdef CUFFT +// ptr_d = rhs.ptr_d; +// rhs.ptr_d = nullptr; +//#endif +// } +// T operator[](uint i) const { return ptr_h[i]; } +//private: +// void release() +// { +//#ifdef CUFFT +// if (ptr_h) +// mmng.put(ptr_h, num_elem); +// //CudaSafeCall(cudaFreeHost(ptr_h)); +//#else +// delete[] ptr_h; +//#endif +// } +//}; +// +//#ifdef CUFFT +//template +//MemoryManager DynMem_::mmng; +//#endif +// +//typedef DynMem_ DynMem; +// +// +//class MatDynMem : public DynMem, public cv::Mat { +// public: +// MatDynMem(cv::Size size, int type) +// : DynMem(size.area() * CV_MAT_CN(type)), cv::Mat(size, type, hostMem()) +// { +// assert((type & CV_MAT_DEPTH_MASK) == CV_32F); +// } +// MatDynMem(int height, int width, int type) +// : DynMem(width * height * CV_MAT_CN(type)), cv::Mat(height, width, type, hostMem()) +// { +// assert((type & CV_MAT_DEPTH_MASK) == CV_32F); +// } +// MatDynMem(int ndims, const int *sizes, int type) +// : DynMem(volume(ndims, sizes) * CV_MAT_CN(type)), cv::Mat(ndims, sizes, type, hostMem()) +// { +// assert((type & CV_MAT_DEPTH_MASK) == CV_32F); +// } +// MatDynMem(std::vector size, int type) +// : DynMem(std::accumulate(size.begin(), size.end(), 1, std::multiplies())) +// , cv::Mat(size.size(), size.data(), type, hostMem()) {} +// MatDynMem(MatDynMem &&other) = default; +// MatDynMem(const cv::Mat &other) +// : DynMem(other.total()) , cv::Mat(other) {} +// +// void operator=(const cv::MatExpr &expr) { +// static_cast(*this) = expr; +// } +// +// private: +// static int volume(int ndims, const int *sizes) +// { +// int vol = 1; +// for (int i = 0; i < ndims; i++) +// vol *= sizes[i]; +// return vol; +// } +// +// 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)); +// } +// const cv::Mat plane(uint idx) const { +// assert(dims == 3); +// assert(int(idx) < size[0]); +// return cv::Mat(size[1], size[2], cv::Mat::type(), const_cast(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)); +// } +// cv::Mat scale(uint scale) { +// assert(dims == 4); +// assert(int(scale) < size[0]); +// return cv::Mat(3, std::vector({size[1], size[2], size[3]}).data(), cv::Mat::type(), ptr(scale)); +// } +//}; +// +//#endif // DYNMEM_HPP diff --git a/src/fft.h b/src/fft.h index dfe9650d..2dcc2bc7 100644 --- a/src/fft.h +++ b/src/fft.h @@ -5,7 +5,6 @@ #include #include #include -#include "complexmat.hpp" #ifdef BIG_BATCH #define BIG_BATCH_MODE 1 diff --git a/src/fft_cufft.cpp b/src/fft_cufft.cpp index fcf93f0e..414e4b97 100644 --- a/src/fft_cufft.cpp +++ b/src/fft_cufft.cpp @@ -53,65 +53,27 @@ void cuFFT::init(unsigned width, unsigned height, unsigned num_of_feats, unsigne #endif } -void cuFFT::set_window(const MatDynMem &window) +void cuFFT::set_window(const cv::Mat &window) { Fft::set_window(window); m_window = window; } -void cuFFT::forward(const MatScales &real_input, ComplexMat &complex_result) -{ - Fft::forward(real_input, complex_result); - auto in = static_cast(const_cast(real_input).deviceMem()); - - if (real_input.size[0] == 1) - cudaErrorCheck(cufftExecR2C(plan_f, in, complex_result.get_dev_data())); -#ifdef BIG_BATCH - else - cudaErrorCheck(cufftExecR2C(plan_f_all_scales, in, complex_result.get_dev_data())); -#endif -} - -// REPLACEMENT void cuFFT::forward(const cv::Mat &real_input, cv::Mat &complex_result) { (void)real_input; (void)complex_result; // Fft::forward(real_input, complex_result); -// auto in = static_cast(const_cast(real_input).deviceMem()); +// auto in = static_cast(const_cast(real_input).deviceMem()); // -// if (real_input.size[0] == 1) -// cudaErrorCheck(cufftExecR2C(plan_f, in, complex_result.get_dev_data())); -//#ifdef BIG_BATCH -// else -// cudaErrorCheck(cufftExecR2C(plan_f_all_scales, in, complex_result.get_dev_data())); -//#endif +// if (real_input.size[0] == 1) +// cudaErrorCheck(cufftExecR2C(plan_f, in, complex_result.get_dev_data())); +// #ifdef BIG_BATCH +// else +// cudaErrorCheck(cufftExecR2C(plan_f_all_scales, in, complex_result.get_dev_data())); +// #endif } -void cuFFT::forward_window(MatScaleFeats &feat, ComplexMat &complex_result, MatScaleFeats &temp) -{ - Fft::forward_window(feat, complex_result, temp); - - cufftReal *temp_data = temp.deviceMem(); - uint n_scales = feat.size[0]; - - for (uint s = 0; s < n_scales; ++s) { - for (uint ch = 0; ch < uint(feat.size[1]); ++ch) { - cv::Mat feat_plane = feat.plane(s, ch); - cv::Mat temp_plane = temp.plane(s, ch); - temp_plane = feat_plane.mul(m_window); - } - } - - if (n_scales == 1) - cudaErrorCheck(cufftExecR2C(plan_fw, temp_data, complex_result.get_dev_data())); -#ifdef BIG_BATCH - else - cudaErrorCheck(cufftExecR2C(plan_fw_all_scales, temp_data, complex_result.get_dev_data())); -#endif -} - -// REPLACEMENT void cuFFT::forward_window(cv::Mat &feat, cv::Mat &complex_result, cv::Mat &temp) { (void)feat; @@ -119,47 +81,25 @@ void cuFFT::forward_window(cv::Mat &feat, cv::Mat &complex_result, cv::Mat &temp (void)temp; // Fft::forward_window(feat, complex_result, temp); // -// cufftReal *temp_data = temp.deviceMem(); -// uint n_scales = feat.size[0]; +// cufftReal *temp_data = temp.deviceMem(); +// uint n_scales = feat.size[0]; // -// for (uint s = 0; s < n_scales; ++s) { -// for (uint ch = 0; ch < uint(feat.size[1]); ++ch) { -// cv::Mat feat_plane = feat.plane(s, ch); -// cv::Mat temp_plane = temp.plane(s, ch); -// temp_plane = feat_plane.mul(m_window); +// for (uint s = 0; s < n_scales; ++s) { +// for (uint ch = 0; ch < uint(feat.size[1]); ++ch) { +// cv::Mat feat_plane = feat.plane(s, ch); +// cv::Mat temp_plane = temp.plane(s, ch); +// temp_plane = feat_plane.mul(m_window); +// } // } -// } // -// if (n_scales == 1) -// cudaErrorCheck(cufftExecR2C(plan_fw, temp_data, complex_result.get_dev_data())); -//#ifdef BIG_BATCH -// else -// cudaErrorCheck(cufftExecR2C(plan_fw_all_scales, temp_data, complex_result.get_dev_data())); -//#endif -} - -void cuFFT::inverse(ComplexMat &complex_input, MatScales &real_result) -{ - Fft::inverse(complex_input, real_result); - - uint n_channels = complex_input.n_channels; - cufftComplex *in = reinterpret_cast(complex_input.get_dev_data()); - cufftReal *out = real_result.deviceMem(); - float alpha = 1.0 / (m_width * m_height); - - if (n_channels == 1) - cudaErrorCheck(cufftExecC2R(plan_i_1ch, in, out)); -#ifdef BIG_BATCH - else - cudaErrorCheck(cufftExecC2R(plan_i_all_scales, in, out)); -#endif - cudaErrorCheck(cublasSscal(cublas, real_result.total(), &alpha, out, 1)); - // The result is a cv::Mat, which will be accesses by CPU, so we - // must synchronize with the GPU here - CudaSafeCall(cudaStreamSynchronize(cudaStreamPerThread)); +// if (n_scales == 1) +// cudaErrorCheck(cufftExecR2C(plan_fw, temp_data, complex_result.get_dev_data())); +// #ifdef BIG_BATCH +// else +// cudaErrorCheck(cufftExecR2C(plan_fw_all_scales, temp_data, complex_result.get_dev_data())); +// #endif } -// REPLACEMENT void cuFFT::inverse(cv::Mat &complex_input, cv::Mat &real_result) { (void)complex_input; diff --git a/src/fft_cufft.h b/src/fft_cufft.h index e194f11e..137304a5 100644 --- a/src/fft_cufft.h +++ b/src/fft_cufft.h @@ -16,12 +16,9 @@ class cuFFT : public Fft public: cuFFT(); void init(unsigned width, unsigned height, unsigned num_of_feats, unsigned num_of_scales); - void set_window(const MatDynMem &window); - void forward(const MatScales &real_input, ComplexMat &complex_result); + void set_window(const cv::Mat &window); void forward(const cv::Mat &real_input, cv::Mat &complex_result); - void forward_window(MatScaleFeats &patch_feats_in, ComplexMat &complex_result, MatScaleFeats &tmp); void forward_window(cv::Mat &feat, cv::Mat &complex_result, cv::Mat &temp); - void inverse(ComplexMat &complex_input, MatScales &real_result); void inverse(cv::Mat &complex_input, cv::Mat &real_result); ~cuFFT(); diff --git a/src/kcf.cpp b/src/kcf.cpp index b17fa30f..d77b4403 100644 --- a/src/kcf.cpp +++ b/src/kcf.cpp @@ -74,24 +74,14 @@ void KCF_Tracker::train(cv::Mat input_rgb, cv::Mat input_gray, double interp_fac TRACE(""); // obtain a sub-window for training - get_features(input_rgb, input_gray, nullptr, p_current_center.x, p_current_center.y, - p_windows_size.width, p_windows_size.height, - p_current_scale, p_current_angle).copyTo(model->patch_feats.scale(0)); - - // REPLACEMENT get_features(input_rgb, input_gray, nullptr, p_current_center.x, p_current_center.y, p_windows_size.width, p_windows_size.height, p_current_scale, p_current_angle).copyTo(MatUtil::scale(0, model->patch_feats_Test)); - DEBUG_PRINT(model->patch_feats); DEBUG_PRINT(model->patch_feats_Test); - fft.forward_window(model->patch_feats, model->xf, model->temp); fft.forward_window(model->patch_feats_Test, model->xf_Test, model->temp_Test); - DEBUG_PRINTM(model->xf); DEBUG_PRINTM(model->xf_Test); - model->model_xf = model->model_xf * (1. - interp_factor) + model->xf * interp_factor; model->model_xf_Test = model->model_xf_Test * (1. - interp_factor) + model->xf_Test * interp_factor; - DEBUG_PRINTM(model->model_xf); DEBUG_PRINTM(model->model_xf_Test); if (m_use_linearkernel) { @@ -101,13 +91,6 @@ void KCF_Tracker::train(cv::Mat input_rgb, cv::Mat input_gray, double interp_fac } 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, model->model_xf, model->model_xf, p_kernel_sigma, true, *this); - DEBUG_PRINTM(kf); - model->model_alphaf_num = model->yf * kf; - model->model_alphaf_den = kf * (kf + p_lambda); - - cv::Mat kf_Test = cv::Mat(sz.height, sz.width, CV_32FC2); (*gaussian_correlation)(kf_Test, model->model_xf_Test, model->model_xf_Test, p_kernel_sigma, true, *this); DEBUG_PRINTM(kf_Test); @@ -115,9 +98,7 @@ void KCF_Tracker::train(cv::Mat input_rgb, cv::Mat input_gray, double interp_fac cv::Mat addedMat = MatUtil::add_scalar(kf_Test, p_lambda); model->model_alphaf_den_Test = MatUtil::mul_matn_matn(kf_Test, addedMat); } - model->model_alphaf = model->model_alphaf_num / model->model_alphaf_den; model->model_alphaf_Test = MatUtil::divide_matn_matn(model->model_alphaf_num_Test, model->model_alphaf_den_Test); - DEBUG_PRINTM(model->model_alphaf); DEBUG_PRINTM(model->model_alphaf_Test); // p_model_alphaf = p_yf / (kf + p_lambda); //equation for fast training } @@ -254,19 +235,13 @@ void KCF_Tracker::init(cv::Mat &img, const cv::Rect &bbox, int fit_size_x, int f * p_output_sigma_factor / p_cell_size; fft.init(feature_size.width, feature_size.height, p_num_of_feats, p_num_scales * p_num_angles); - fft.set_window(MatDynMem(cosine_window_function(feature_size.width, feature_size.height))); + fft.set_window(cosine_window_function(feature_size.width, feature_size.height)); // 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, model->yf); - -// REPLACEMENT - cv::Mat gsl2(feature_size,CV_32F); - gaussian_shaped_labels(p_output_sigma, feature_size.width, feature_size.height).copyTo(gsl2); - fft.forward(gsl2, model->yf_Test); + cv::Mat gsl(feature_size,CV_32F); + gaussian_shaped_labels(p_output_sigma, feature_size.width, feature_size.height).copyTo(gsl); + fft.forward(gsl, model->yf_Test); - DEBUG_PRINTM(model->yf); DEBUG_PRINTM(model->yf_Test); // train initial model @@ -351,21 +326,22 @@ double KCF_Tracker::findMaxReponse(uint &max_idx, cv::Point2d &new_location) con max_idx = std::distance(vec.begin(), max_it); cv::Point2i max_response_pt = IF_BIG_BATCH(max_it->loc, max_it->max.loc); - cv::Mat max_response_map = IF_BIG_BATCH(d->threadctxs[0].response.plane(max_idx), - max_it->response.plane(0)); +// cv::Mat max_response_map = IF_BIG_BATCH(d->threadctxs[0].response.plane(max_idx), +// max_it->response.plane(0)); + cv::Mat tempResponse = IF_BIG_BATCH(,max_it->response_Test); cv::Mat max_response_map_Test = IF_BIG_BATCH(MatUtil::plane(max_idx, d->threadctxs[0].response_Test), MatUtil::plane(0, tempResponse)); - DEBUG_PRINTM(max_response_map); + DEBUG_PRINTM(max_response_map_Test); DEBUG_PRINT(max_response_pt); - max_response_pt = wrapAroundFreq(max_response_pt, max_response_map); + max_response_pt = wrapAroundFreq(max_response_pt, max_response_map_Test); // sub pixel quadratic interpolation from neighbours if (m_use_subpixel_localization) { - new_location = sub_pixel_peak(max_response_pt, max_response_map); + new_location = sub_pixel_peak(max_response_pt, max_response_map_Test); } else { new_location = max_response_pt; } @@ -382,16 +358,16 @@ double KCF_Tracker::findMaxReponse(uint &max_idx, cv::Point2d &new_location) con auto &threadctx = d->IF_BIG_BATCH(threadctxs[0], threadctxs(i, j)); cv::Mat tmp; cv::Point2d cross = threadctx.IF_BIG_BATCH(max(i, j), max).loc; - cross = wrapAroundFreq(cross, max_response_map); + cross = wrapAroundFreq(cross, max_response_map_Test); if (m_visual_debug == vd::PATCH ) { threadctx.dbg_patch IF_BIG_BATCH((i, j),) .convertTo(tmp, all_responses.type(), 1.0 / 255); cross.x = cross.x / fit_size.width * tmp.cols + tmp.cols / 2; cross.y = cross.y / fit_size.height * tmp.rows + tmp.rows / 2; } else { - cv::cvtColor(threadctx.response.plane(IF_BIG_BATCH(threadctx.max.getIdx(i, j), 0)), - tmp, cv::COLOR_GRAY2BGR); - cv::cvtColor(MatUtil::plane(IF_BIG_BATCH(threadctx.max.getIdx(i, j), 0), threadctx.response), +// cv::cvtColor(threadctx.response.plane(IF_BIG_BATCH(threadctx.max.getIdx(i, j), 0)), +// tmp, cv::COLOR_GRAY2BGR); + cv::cvtColor(MatUtil::plane(IF_BIG_BATCH(threadctx.max.getIdx(i, j), 0), threadctx.response_Test), tmp, cv::COLOR_GRAY2BGR); tmp /= max; // Normalize to 1 cross += cv::Point2d(tmp.size())/2; @@ -490,14 +466,6 @@ void ThreadCtx::track(const KCF_Tracker &kcf, cv::Mat &input_rgb, cv::Mat &input BIG_BATCH_OMP_PARALLEL_FOR for (uint i = 0; i < IF_BIG_BATCH(max.size(), 1); ++i) { - kcf.get_features(input_rgb, input_gray, &dbg_patch IF_BIG_BATCH([i],), - kcf.p_current_center.x, kcf.p_current_center.y, - kcf.p_windows_size.width, kcf.p_windows_size.height, - kcf.p_current_scale * IF_BIG_BATCH(max.scale(i), scale), - kcf.p_current_angle + IF_BIG_BATCH(max.angle(i), angle)) - .copyTo(patch_feats.scale(i)); - DEBUG_PRINT(patch_feats.scale(i)); - kcf.get_features(input_rgb, input_gray, &dbg_patch IF_BIG_BATCH([i],), kcf.p_current_center.x, kcf.p_current_center.y, kcf.p_windows_size.width, kcf.p_windows_size.height, @@ -507,38 +475,24 @@ void ThreadCtx::track(const KCF_Tracker &kcf, cv::Mat &input_rgb, cv::Mat &input DEBUG_PRINT(MatUtil::scale(i, patch_feats_Test)); } - kcf.fft.forward_window(patch_feats, zf, temp); kcf.fft.forward_window(patch_feats_Test, zf_Test, temp_Test); - DEBUG_PRINTM(zf); DEBUG_PRINTM(zf_Test); if (kcf.m_use_linearkernel) { // Unused feature - kzf = zf.mul(kcf.model->model_alphaf).sum_over_channels(); } else { - gaussian_correlation(kzf, zf, kcf.model->model_xf, kcf.p_kernel_sigma, false, kcf); - DEBUG_PRINTM(kzf); - kzf = kzf.mul(kcf.model->model_alphaf); - gaussian_correlation(kzf_Test, zf_Test, kcf.model->model_xf_Test, kcf.p_kernel_sigma, false, kcf); DEBUG_PRINTM(kzf_Test); kzf_Test = MatUtil::mul_matn_mat1(kzf_Test, kcf.model->model_alphaf_Test); } - DEBUG_PRINTM(kzf); DEBUG_PRINTM(kzf_Test); - - kcf.fft.inverse(kzf, response); kcf.fft.inverse(kzf_Test, response_Test); - - DEBUG_PRINTM(response); DEBUG_PRINTM(response_Test); /* target location is at the maximum response. we must take into account the fact that, if the target doesn't move, the peak will appear at the top-left corner, not at the center (this is discussed in the paper). the responses wrap around cyclically. */ - double min_val, max_val; - cv::Point2i min_loc, max_loc; double min_val_Test, max_val_Test; cv::Point2i min_loc_Test, max_loc_Test; @@ -550,18 +504,14 @@ void ThreadCtx::track(const KCF_Tracker &kcf, cv::Mat &input_rgb, cv::Mat &input max[i].response = max_val * weight; max[i].loc = max_loc; } -#else - cv::minMaxLoc(response.plane(0), &min_val, &max_val, &min_loc, &max_loc); - DEBUG_PRINT(max_loc); - DEBUG_PRINT(max_val); - +#else cv::minMaxLoc(MatUtil::plane(0, response_Test), &min_val_Test, &max_val_Test, &min_loc_Test, &max_loc_Test); DEBUG_PRINT(max_loc_Test); DEBUG_PRINT(max_val_Test); - + double weight = scale < 1. ? scale : 1. / scale; - max.response = max_val * weight; - max.loc = max_loc; + max.response = max_val_Test * weight; + max.loc = max_loc_Test; #endif } @@ -646,7 +596,7 @@ cv::Mat KCF_Tracker::gaussian_shaped_labels(double sigma, int dim1, int dim2) } // rotate so that 1 is at top-left corner (see KCF paper for explanation) - MatDynMem rot_labels = circshift(labels, range_x[0], range_y[0]); + cv::Mat rot_labels = circshift(labels, range_x[0], range_y[0]); // sanity check, 1 at top left corner assert(rot_labels.at(0, 0) >= 1.f - 1e-10f); @@ -798,45 +748,6 @@ cv::Mat KCF_Tracker::get_subwindow(const cv::Mat &input, int cx, int cy, int wid return patch; } -void KCF_Tracker::GaussianCorrelation::operator()(ComplexMat &result, const ComplexMat &xf, const ComplexMat &yf, - double sigma, bool auto_correlation, const KCF_Tracker &kcf) -{ - TRACE(""); - DEBUG_PRINTM(xf); - DEBUG_PRINT(xf_sqr_norm.num_elem); - xf.sqr_norm(xf_sqr_norm); - for (uint s = 0; s < xf.n_scales; ++s) - DEBUG_PRINT(xf_sqr_norm[s]); - if (auto_correlation) { - yf_sqr_norm = xf_sqr_norm; - } else { - DEBUG_PRINTM(yf); - yf.sqr_norm(yf_sqr_norm); - } - for (uint s = 0; s < yf.n_scales; ++s) - DEBUG_PRINTM(yf_sqr_norm[s]); - xyf = auto_correlation ? xf.sqr_mag() : xf * yf.conj(); // xf.muln(yf.conj()); - DEBUG_PRINTM(xyf); - - // ifft2 and sum over 3rd dimension, we dont care about individual channels - ComplexMat xyf_sum = xyf.sum_over_channels(); - DEBUG_PRINTM(xyf_sum); - kcf.fft.inverse(xyf_sum, ifft_res); - DEBUG_PRINTM(ifft_res); - - float numel_xf_inv = 1.f / (xf.cols * xf.rows * (xf.channels() / xf.n_scales)); - for (uint i = 0; i < xf.n_scales; ++i) { - cv::Mat plane = ifft_res.plane(i); - DEBUG_PRINT(ifft_res.plane(i)); - cv::exp(-1. / (sigma * sigma) * cv::max((xf_sqr_norm[i] + yf_sqr_norm[0] - 2 * ifft_res.plane(i)) - * numel_xf_inv, 0), plane); - DEBUG_PRINTM(plane); - } - - kcf.fft.forward(ifft_res, result); -} - -// REPLACEMENT void KCF_Tracker::GaussianCorrelation::operator()(cv::Mat &result, cv::Mat &xf, cv::Mat &yf, double sigma, bool auto_correlation, const KCF_Tracker &kcf) { @@ -864,13 +775,11 @@ void KCF_Tracker::GaussianCorrelation::operator()(cv::Mat &result, cv::Mat &xf, DEBUG_PRINTM(ifft_res_Test); float numel_xf_inv = 1.f / (xf.cols * xf.rows * (xf.channels() / 2)); -// for (uint i = 0; i < xf.n_scales; ++i) { - cv::Mat plane = MatUtil::plane(0,ifft_res_Test); - DEBUG_PRINTM(plane); - cv::exp(-1. / (sigma * sigma) * cv::max((xf_sqr_norm[0] + yf_sqr_norm[0] - 2 * MatUtil::plane(0,ifft_res_Test)) - * numel_xf_inv, 0), plane); - DEBUG_PRINTM(plane); -// } + cv::Mat plane = MatUtil::plane(0,ifft_res_Test); + DEBUG_PRINTM(plane); + cv::exp(-1. / (sigma * sigma) * cv::max((xf_sqr_norm_Test + yf_sqr_norm_Test - 2 * MatUtil::plane(0,ifft_res_Test)) + * numel_xf_inv, 0), plane); + DEBUG_PRINTM(plane); kcf.fft.forward(MatUtil::plane(0,ifft_res_Test), result); } diff --git a/src/kcf.h b/src/kcf.h index 397a27e5..b9c2e7a1 100644 --- a/src/kcf.h +++ b/src/kcf.h @@ -6,7 +6,6 @@ #include #include "fhog.hpp" -#include "complexmat.hpp" #ifdef CUFFT #include "cuda_error_check.hpp" #include @@ -133,20 +132,7 @@ class KCF_Tracker 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 training - MatScaleFeats patch_feats{1, n_feats, feature_size}; - MatScaleFeats temp{1, n_feats, feature_size}; - - // FORMER ATTRIBUTES CONVERTED TO cv::Mat // Complex matrix now equals 2*k channels matrix by design cv::Mat yf_Test = cv::Mat::zeros((int) height, (int) width, CV_32FC2); cv::Mat model_alphaf_Test = cv::Mat::zeros((int) height, (int) width, CV_32FC2); @@ -171,26 +157,15 @@ class KCF_Tracker 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) { cv::Size temp = Fft::freq_size(size); xyf_Test = cv::Mat(3, std::vector({(int) num_scales, temp.height, temp.width}).data(), CV_32FC(num_feats*2)); ifft_res_Test = cv::Mat(3, std::vector({(int) num_scales, size.height, size.width}).data(), CV_32F); k_Test = cv::Mat(3, std::vector({(int) num_scales, size.height, size.width}).data(), CV_32F); } - void operator()(ComplexMat &result, const ComplexMat &xf, const ComplexMat &yf, double sigma, bool auto_correlation, const KCF_Tracker &kcf); void operator()(cv::Mat &result, cv::Mat &xf, cv::Mat &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; - float xf_sqr_norm_Test; float yf_sqr_norm_Test; cv::Mat xyf_Test; diff --git a/src/matutil.h b/src/matutil.h index 9d09535e..aa9025d5 100644 --- a/src/matutil.h +++ b/src/matutil.h @@ -5,6 +5,7 @@ #include #include #include "debug.h" +#include class MatUtil{ public: diff --git a/src/threadctx.hpp b/src/threadctx.hpp index 3db300a9..dd281a61 100644 --- a/src/threadctx.hpp +++ b/src/threadctx.hpp @@ -2,9 +2,7 @@ #define SCALE_VARS_HPP #include -#include "dynmem.hpp" #include "kcf.h" -#include "complexmat.hpp" #include class KCF_Tracker; From 95dd8fa1feaebbd6e4ecf23540880a745ec3d401 Mon Sep 17 00:00:00 2001 From: Your Name Date: Wed, 8 Jan 2020 21:45:22 +0100 Subject: [PATCH 071/121] =?UTF-8?q?Odstran=C4=9Bn=20postfix=20"=5FTest"=20?= =?UTF-8?q?z=20n=C3=A1zvu=20v=C5=A1ech=20p=C5=AFvodn=C4=9B=20experiment?= =?UTF-8?q?=C3=A1ln=C3=ADch=20prom=C4=9Bnn=C3=BDch=20-=20tyto=20prom=C4=9B?= =?UTF-8?q?nn=C3=A9=20jsou=20nyn=C3=AD=20p=C5=99ipraveny=20pro=20b=C4=9B?= =?UTF-8?q?=C5=BEn=C3=BD=20provoz?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- src/kcf.cpp | 112 +++++++++++++++++++++++----------------------- src/kcf.h | 34 +++++++------- src/threadctx.hpp | 10 ++--- 3 files changed, 78 insertions(+), 78 deletions(-) diff --git a/src/kcf.cpp b/src/kcf.cpp index d77b4403..3abbfba5 100644 --- a/src/kcf.cpp +++ b/src/kcf.cpp @@ -76,30 +76,30 @@ void KCF_Tracker::train(cv::Mat input_rgb, cv::Mat input_gray, double interp_fac // obtain a sub-window for training get_features(input_rgb, input_gray, nullptr, p_current_center.x, p_current_center.y, p_windows_size.width, p_windows_size.height, - p_current_scale, p_current_angle).copyTo(MatUtil::scale(0, model->patch_feats_Test)); + p_current_scale, p_current_angle).copyTo(MatUtil::scale(0, model->patch_feats)); - DEBUG_PRINT(model->patch_feats_Test); - fft.forward_window(model->patch_feats_Test, model->xf_Test, model->temp_Test); - DEBUG_PRINTM(model->xf_Test); - model->model_xf_Test = model->model_xf_Test * (1. - interp_factor) + model->xf_Test * interp_factor; - DEBUG_PRINTM(model->model_xf_Test); + DEBUG_PRINT(model->patch_feats); + fft.forward_window(model->patch_feats, model->xf, model->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) { - cv::Mat xfconj_Test = MatUtil::conj(model->xf_Test); - model->model_alphaf_num_Test = MatUtil::mul_matn_mat1(xfconj_Test, model->yf_Test); - model->model_alphaf_den_Test = MatUtil::mul_matn_matn(model->xf_Test, xfconj_Test); + cv::Mat xfconj = MatUtil::conj(model->xf); + model->model_alphaf_num = MatUtil::mul_matn_mat1(xfconj, model->yf); + model->model_alphaf_den = MatUtil::mul_matn_matn(model->xf, xfconj); } else { // Kernel Ridge Regression, calculate alphas (in Fourier domain) cv::Size sz(Fft::freq_size(feature_size)); - cv::Mat kf_Test = cv::Mat(sz.height, sz.width, CV_32FC2); - (*gaussian_correlation)(kf_Test, model->model_xf_Test, model->model_xf_Test, p_kernel_sigma, true, *this); - DEBUG_PRINTM(kf_Test); - model->model_alphaf_num_Test = MatUtil::mul_matn_matn(model->yf_Test, kf_Test); - cv::Mat addedMat = MatUtil::add_scalar(kf_Test, p_lambda); - model->model_alphaf_den_Test = MatUtil::mul_matn_matn(kf_Test, addedMat); + cv::Mat kf = cv::Mat(sz.height, sz.width, CV_32FC2); + (*gaussian_correlation)(kf, model->model_xf, model->model_xf, p_kernel_sigma, true, *this); + DEBUG_PRINTM(kf); + model->model_alphaf_num = MatUtil::mul_matn_matn(model->yf, kf); + cv::Mat addedMat = MatUtil::add_scalar(kf, p_lambda); + model->model_alphaf_den = MatUtil::mul_matn_matn(kf, addedMat); } - model->model_alphaf_Test = MatUtil::divide_matn_matn(model->model_alphaf_num_Test, model->model_alphaf_den_Test); - DEBUG_PRINTM(model->model_alphaf_Test); + model->model_alphaf = MatUtil::divide_matn_matn(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 } @@ -240,9 +240,9 @@ void KCF_Tracker::init(cv::Mat &img, const cv::Rect &bbox, int fit_size_x, int f // window weights, i.e. labels cv::Mat gsl(feature_size,CV_32F); gaussian_shaped_labels(p_output_sigma, feature_size.width, feature_size.height).copyTo(gsl); - fft.forward(gsl, model->yf_Test); + fft.forward(gsl, model->yf); - DEBUG_PRINTM(model->yf_Test); + DEBUG_PRINTM(model->yf); // train initial model train(input_rgb, input_gray, 1.0); @@ -329,19 +329,19 @@ double KCF_Tracker::findMaxReponse(uint &max_idx, cv::Point2d &new_location) con // cv::Mat max_response_map = IF_BIG_BATCH(d->threadctxs[0].response.plane(max_idx), // max_it->response.plane(0)); - cv::Mat tempResponse = IF_BIG_BATCH(,max_it->response_Test); - cv::Mat max_response_map_Test = IF_BIG_BATCH(MatUtil::plane(max_idx, d->threadctxs[0].response_Test), + cv::Mat tempResponse = IF_BIG_BATCH(,max_it->response); + cv::Mat max_response_map = IF_BIG_BATCH(MatUtil::plane(max_idx, d->threadctxs[0].response), MatUtil::plane(0, tempResponse)); - DEBUG_PRINTM(max_response_map_Test); + DEBUG_PRINTM(max_response_map); DEBUG_PRINT(max_response_pt); - max_response_pt = wrapAroundFreq(max_response_pt, max_response_map_Test); + max_response_pt = wrapAroundFreq(max_response_pt, max_response_map); // sub pixel quadratic interpolation from neighbours if (m_use_subpixel_localization) { - new_location = sub_pixel_peak(max_response_pt, max_response_map_Test); + new_location = sub_pixel_peak(max_response_pt, max_response_map); } else { new_location = max_response_pt; } @@ -358,7 +358,7 @@ double KCF_Tracker::findMaxReponse(uint &max_idx, cv::Point2d &new_location) con auto &threadctx = d->IF_BIG_BATCH(threadctxs[0], threadctxs(i, j)); cv::Mat tmp; cv::Point2d cross = threadctx.IF_BIG_BATCH(max(i, j), max).loc; - cross = wrapAroundFreq(cross, max_response_map_Test); + cross = wrapAroundFreq(cross, max_response_map); if (m_visual_debug == vd::PATCH ) { threadctx.dbg_patch IF_BIG_BATCH((i, j),) .convertTo(tmp, all_responses.type(), 1.0 / 255); @@ -367,7 +367,7 @@ double KCF_Tracker::findMaxReponse(uint &max_idx, cv::Point2d &new_location) con } else { // cv::cvtColor(threadctx.response.plane(IF_BIG_BATCH(threadctx.max.getIdx(i, j), 0)), // tmp, cv::COLOR_GRAY2BGR); - cv::cvtColor(MatUtil::plane(IF_BIG_BATCH(threadctx.max.getIdx(i, j), 0), threadctx.response_Test), + cv::cvtColor(MatUtil::plane(IF_BIG_BATCH(threadctx.max.getIdx(i, j), 0), threadctx.response), tmp, cv::COLOR_GRAY2BGR); tmp /= max; // Normalize to 1 cross += cv::Point2d(tmp.size())/2; @@ -471,31 +471,31 @@ void ThreadCtx::track(const KCF_Tracker &kcf, cv::Mat &input_rgb, cv::Mat &input kcf.p_windows_size.width, kcf.p_windows_size.height, kcf.p_current_scale * IF_BIG_BATCH(max.scale(i), scale), kcf.p_current_angle + IF_BIG_BATCH(max.angle(i), angle)) - .copyTo(MatUtil::scale(i, patch_feats_Test)); - DEBUG_PRINT(MatUtil::scale(i, patch_feats_Test)); + .copyTo(MatUtil::scale(i, patch_feats)); + DEBUG_PRINT(MatUtil::scale(i, patch_feats)); } - kcf.fft.forward_window(patch_feats_Test, zf_Test, temp_Test); - DEBUG_PRINTM(zf_Test); + kcf.fft.forward_window(patch_feats, zf, temp); + DEBUG_PRINTM(zf); if (kcf.m_use_linearkernel) { // Unused feature } else { - gaussian_correlation(kzf_Test, zf_Test, kcf.model->model_xf_Test, kcf.p_kernel_sigma, false, kcf); - DEBUG_PRINTM(kzf_Test); - kzf_Test = MatUtil::mul_matn_mat1(kzf_Test, kcf.model->model_alphaf_Test); + gaussian_correlation(kzf, zf, kcf.model->model_xf, kcf.p_kernel_sigma, false, kcf); + DEBUG_PRINTM(kzf); + kzf = MatUtil::mul_matn_mat1(kzf, kcf.model->model_alphaf); } - DEBUG_PRINTM(kzf_Test); - kcf.fft.inverse(kzf_Test, response_Test); - DEBUG_PRINTM(response_Test); + DEBUG_PRINTM(kzf); + kcf.fft.inverse(kzf, response); + DEBUG_PRINTM(response); /* target location is at the maximum response. we must take into account the fact that, if the target doesn't move, the peak will appear at the top-left corner, not at the center (this is discussed in the paper). the responses wrap around cyclically. */ - double min_val_Test, max_val_Test; - cv::Point2i min_loc_Test, max_loc_Test; + double min_val, max_val; + cv::Point2i min_loc, max_loc; #ifdef BIG_BATCH for (size_t i = 0; i < max.size(); ++i) { cv::minMaxLoc(response.plane(i), &min_val, &max_val, &min_loc, &max_loc); @@ -505,13 +505,13 @@ void ThreadCtx::track(const KCF_Tracker &kcf, cv::Mat &input_rgb, cv::Mat &input max[i].loc = max_loc; } #else - cv::minMaxLoc(MatUtil::plane(0, response_Test), &min_val_Test, &max_val_Test, &min_loc_Test, &max_loc_Test); - DEBUG_PRINT(max_loc_Test); - DEBUG_PRINT(max_val_Test); + cv::minMaxLoc(MatUtil::plane(0, response), &min_val, &max_val, &min_loc, &max_loc); + DEBUG_PRINT(max_loc); + DEBUG_PRINT(max_val); double weight = scale < 1. ? scale : 1. / scale; - max.response = max_val_Test * weight; - max.loc = max_loc_Test; + max.response = max_val * weight; + max.loc = max_loc; #endif } @@ -753,35 +753,35 @@ void KCF_Tracker::GaussianCorrelation::operator()(cv::Mat &result, cv::Mat &xf, { TRACE(""); DEBUG_PRINTM(xf); - xf_sqr_norm_Test = MatUtil::sqr_norm(xf); - DEBUG_PRINT(xf_sqr_norm_Test); + xf_sqr_norm = MatUtil::sqr_norm(xf); + DEBUG_PRINT(xf_sqr_norm); if (auto_correlation) { - yf_sqr_norm_Test = xf_sqr_norm_Test; + yf_sqr_norm = xf_sqr_norm; } else { DEBUG_PRINTM(yf); - yf_sqr_norm_Test = MatUtil::sqr_norm(yf); + yf_sqr_norm = MatUtil::sqr_norm(yf); } - DEBUG_PRINT(yf_sqr_norm_Test); + DEBUG_PRINT(yf_sqr_norm); cv::Mat conjMat = MatUtil::conj(yf); - xyf_Test = auto_correlation ? MatUtil::sqr_mag(xf) : MatUtil::mul_matn_matn(xf, conjMat); // xf.muln(yf.conj()); - DEBUG_PRINTM(xyf_Test); + xyf = auto_correlation ? MatUtil::sqr_mag(xf) : MatUtil::mul_matn_matn(xf, conjMat); // xf.muln(yf.conj()); + DEBUG_PRINTM(xyf); // ifft2 and sum over 3rd dimension, we dont care about individual channels - cv::Mat xyf_sum = MatUtil::sum_over_channels(xyf_Test); + cv::Mat xyf_sum = MatUtil::sum_over_channels(xyf); DEBUG_PRINTM(xyf_sum); - kcf.fft.inverse(xyf_sum, ifft_res_Test); - DEBUG_PRINTM(ifft_res_Test); + kcf.fft.inverse(xyf_sum, ifft_res); + DEBUG_PRINTM(ifft_res); float numel_xf_inv = 1.f / (xf.cols * xf.rows * (xf.channels() / 2)); - cv::Mat plane = MatUtil::plane(0,ifft_res_Test); + cv::Mat plane = MatUtil::plane(0,ifft_res); DEBUG_PRINTM(plane); - cv::exp(-1. / (sigma * sigma) * cv::max((xf_sqr_norm_Test + yf_sqr_norm_Test - 2 * MatUtil::plane(0,ifft_res_Test)) + cv::exp(-1. / (sigma * sigma) * cv::max((xf_sqr_norm + yf_sqr_norm - 2 * MatUtil::plane(0,ifft_res)) * numel_xf_inv, 0), plane); DEBUG_PRINTM(plane); - kcf.fft.forward(MatUtil::plane(0,ifft_res_Test), result); + kcf.fft.forward(MatUtil::plane(0,ifft_res), result); } float get_response_circular(cv::Point2i &pt, cv::Mat &response) diff --git a/src/kcf.h b/src/kcf.h index b9c2e7a1..a21497a9 100644 --- a/src/kcf.h +++ b/src/kcf.h @@ -134,15 +134,15 @@ class KCF_Tracker public: // Complex matrix now equals 2*k channels matrix by design - cv::Mat yf_Test = cv::Mat::zeros((int) height, (int) width, CV_32FC2); - cv::Mat model_alphaf_Test = cv::Mat::zeros((int) height, (int) width, CV_32FC2); - cv::Mat model_alphaf_num_Test = cv::Mat::zeros((int) height, (int) width, CV_32FC2); - cv::Mat model_alphaf_den_Test = cv::Mat::zeros((int) height, (int) width, CV_32FC2); - cv::Mat model_xf_Test = cv::Mat::zeros((int) height, (int) width, CV_32FC(n_feats*2)); - cv::Mat xf_Test = cv::Mat::zeros((int) height, (int) width, CV_32FC(n_feats*2)); - - cv::Mat patch_feats_Test{ 4, std::vector({1, int(n_feats), feature_size.height, feature_size.width}).data(), CV_32F}; - cv::Mat temp_Test{ 4, std::vector({1, int(n_feats), feature_size.height, feature_size.width}).data(), CV_32F}; + cv::Mat yf = cv::Mat::zeros((int) height, (int) width, CV_32FC2); + cv::Mat model_alphaf = cv::Mat::zeros((int) height, (int) width, CV_32FC2); + cv::Mat model_alphaf_num = cv::Mat::zeros((int) height, (int) width, CV_32FC2); + cv::Mat model_alphaf_den = cv::Mat::zeros((int) height, (int) width, CV_32FC2); + cv::Mat model_xf = cv::Mat::zeros((int) height, (int) width, CV_32FC(n_feats*2)); + cv::Mat xf = cv::Mat::zeros((int) height, (int) width, CV_32FC(n_feats*2)); + + cv::Mat patch_feats{ 4, std::vector({1, int(n_feats), feature_size.height, feature_size.width}).data(), CV_32F}; + cv::Mat temp{ 4, std::vector({1, int(n_feats), feature_size.height, feature_size.width}).data(), CV_32F}; Model(cv::Size feature_size, uint _n_feats) @@ -159,18 +159,18 @@ class KCF_Tracker GaussianCorrelation(uint num_scales, uint num_feats, cv::Size size) { cv::Size temp = Fft::freq_size(size); - xyf_Test = cv::Mat(3, std::vector({(int) num_scales, temp.height, temp.width}).data(), CV_32FC(num_feats*2)); - ifft_res_Test = cv::Mat(3, std::vector({(int) num_scales, size.height, size.width}).data(), CV_32F); - k_Test = cv::Mat(3, std::vector({(int) num_scales, size.height, size.width}).data(), CV_32F); + xyf = cv::Mat(3, std::vector({(int) num_scales, temp.height, temp.width}).data(), CV_32FC(num_feats*2)); + ifft_res = cv::Mat(3, std::vector({(int) num_scales, size.height, size.width}).data(), CV_32F); + k = cv::Mat(3, std::vector({(int) num_scales, size.height, size.width}).data(), CV_32F); } void operator()(cv::Mat &result, cv::Mat &xf, cv::Mat &yf, double sigma, bool auto_correlation, const KCF_Tracker &kcf); private: - float xf_sqr_norm_Test; - float yf_sqr_norm_Test; - cv::Mat xyf_Test; - cv::Mat ifft_res_Test; - cv::Mat k_Test; + float xf_sqr_norm; + float yf_sqr_norm; + cv::Mat xyf; + cv::Mat ifft_res; + cv::Mat k; }; //helping functions diff --git a/src/threadctx.hpp b/src/threadctx.hpp index dd281a61..d2122761 100644 --- a/src/threadctx.hpp +++ b/src/threadctx.hpp @@ -64,11 +64,11 @@ struct ThreadCtx { uint num_angles; cv::Size freq_size = Fft::freq_size(roi); - cv::Mat patch_feats_Test{ 4, std::vector({ int(num_scales * num_angles), int(num_features), roi.height, roi.width}).data(), CV_32F}; - cv::Mat temp_Test{ 4, std::vector({ int(num_scales * num_angles), int(num_features), roi.height, roi.width}).data(), CV_32F}; + cv::Mat patch_feats{ 4, std::vector({ int(num_scales * num_angles), int(num_features), roi.height, roi.width}).data(), CV_32F}; + cv::Mat temp{ 4, std::vector({ int(num_scales * num_angles), int(num_features), roi.height, roi.width}).data(), CV_32F}; - cv::Mat zf_Test = cv::Mat::zeros((int) freq_size.height, (int) freq_size.width, CV_32FC(num_features*2)); - cv::Mat kzf_Test = cv::Mat::zeros((int) freq_size.height, (int) freq_size.width, CV_32FC2); + cv::Mat zf = cv::Mat::zeros((int) freq_size.height, (int) freq_size.width, CV_32FC(num_features*2)); + cv::Mat kzf = cv::Mat::zeros((int) freq_size.height, (int) freq_size.width, CV_32FC2); KCF_Tracker::GaussianCorrelation gaussian_correlation{num_scales * num_angles, num_features, roi}; @@ -78,7 +78,7 @@ struct ThreadCtx { std::future async_res; #endif - cv::Mat response_Test = cv::Mat(3, std::vector({int(num_scales * num_angles), (int) roi.height, (int) roi.width}).data(), CV_32F); + cv::Mat response = cv::Mat(3, std::vector({int(num_scales * num_angles), (int) roi.height, (int) roi.width}).data(), CV_32F); struct Max { cv::Point2i loc; From 78e28d9712f9e91bf75fbb30d9657477fde4f050 Mon Sep 17 00:00:00 2001 From: Your Name Date: Wed, 8 Jan 2020 22:10:30 +0100 Subject: [PATCH 072/121] Oprava warningu (build-specific call) --- src/kcf.cpp | 3 +-- 1 file changed, 1 insertion(+), 2 deletions(-) diff --git a/src/kcf.cpp b/src/kcf.cpp index 3abbfba5..b327622a 100644 --- a/src/kcf.cpp +++ b/src/kcf.cpp @@ -329,9 +329,8 @@ double KCF_Tracker::findMaxReponse(uint &max_idx, cv::Point2d &new_location) con // cv::Mat max_response_map = IF_BIG_BATCH(d->threadctxs[0].response.plane(max_idx), // max_it->response.plane(0)); - cv::Mat tempResponse = IF_BIG_BATCH(,max_it->response); cv::Mat max_response_map = IF_BIG_BATCH(MatUtil::plane(max_idx, d->threadctxs[0].response), - MatUtil::plane(0, tempResponse)); + MatUtil::plane(0, max_it->response)); DEBUG_PRINTM(max_response_map); From 1caf2adbcdc8ec1e21e903be6e6f298cd9ef99e4 Mon Sep 17 00:00:00 2001 From: Your Name Date: Wed, 8 Jan 2020 22:12:43 +0100 Subject: [PATCH 073/121] Oprava warningu (build-specific call) (oprava 2) --- src/kcf.cpp | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) diff --git a/src/kcf.cpp b/src/kcf.cpp index b327622a..58f3ae60 100644 --- a/src/kcf.cpp +++ b/src/kcf.cpp @@ -329,8 +329,9 @@ double KCF_Tracker::findMaxReponse(uint &max_idx, cv::Point2d &new_location) con // cv::Mat max_response_map = IF_BIG_BATCH(d->threadctxs[0].response.plane(max_idx), // max_it->response.plane(0)); + cv::Mat tempResponse = IF_BIG_BATCH(max_it->response, max_it->response); cv::Mat max_response_map = IF_BIG_BATCH(MatUtil::plane(max_idx, d->threadctxs[0].response), - MatUtil::plane(0, max_it->response)); + MatUtil::plane(0, tempResponse)); DEBUG_PRINTM(max_response_map); From 94bab25d9844bb0b5a9bd3e733241e4c335b0b19 Mon Sep 17 00:00:00 2001 From: Your Name Date: Wed, 8 Jan 2020 22:18:35 +0100 Subject: [PATCH 074/121] Oprava warningu (build-specific call) (oprava 3) --- src/kcf.cpp | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/kcf.cpp b/src/kcf.cpp index 58f3ae60..20b9837c 100644 --- a/src/kcf.cpp +++ b/src/kcf.cpp @@ -329,7 +329,7 @@ double KCF_Tracker::findMaxReponse(uint &max_idx, cv::Point2d &new_location) con // cv::Mat max_response_map = IF_BIG_BATCH(d->threadctxs[0].response.plane(max_idx), // max_it->response.plane(0)); - cv::Mat tempResponse = IF_BIG_BATCH(max_it->response, max_it->response); + cv::Mat tempResponse = IF_BIG_BATCH(cv::Mat(), max_it->response); cv::Mat max_response_map = IF_BIG_BATCH(MatUtil::plane(max_idx, d->threadctxs[0].response), MatUtil::plane(0, tempResponse)); From 97e248c14581b51f22716716206a29335ed0f94e Mon Sep 17 00:00:00 2001 From: Your Name Date: Wed, 8 Jan 2020 22:23:49 +0100 Subject: [PATCH 075/121] Oprava warningu (build-specific call) (oprava 4) --- src/kcf.cpp | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/kcf.cpp b/src/kcf.cpp index 20b9837c..a244326e 100644 --- a/src/kcf.cpp +++ b/src/kcf.cpp @@ -498,7 +498,7 @@ void ThreadCtx::track(const KCF_Tracker &kcf, cv::Mat &input_rgb, cv::Mat &input cv::Point2i min_loc, max_loc; #ifdef BIG_BATCH for (size_t i = 0; i < max.size(); ++i) { - cv::minMaxLoc(response.plane(i), &min_val, &max_val, &min_loc, &max_loc); + cv::minMaxLoc(MatUtil::plane(i, response), &min_val, &max_val, &min_loc, &max_loc); DEBUG_PRINT(max_loc); double weight = max.scale(i) < 1. ? max.scale(i) : 1. / max.scale(i); max[i].response = max_val * weight; From 84730ea4a19c0ff83b9479d8991dec99b72a4e9c Mon Sep 17 00:00:00 2001 From: oraveja1 <57142143+oraveja1@users.noreply.github.com> Date: Wed, 8 Jan 2020 22:34:36 +0100 Subject: [PATCH 076/121] Delete complexmat.cu --- src/complexmat.cu | 352 ---------------------------------------------- 1 file changed, 352 deletions(-) delete mode 100644 src/complexmat.cu diff --git a/src/complexmat.cu b/src/complexmat.cu deleted file mode 100644 index a96a97d7..00000000 --- a/src/complexmat.cu +++ /dev/null @@ -1,352 +0,0 @@ -#include "complexmat.hpp" - - -__global__ void sqr_norm_kernel(const float *in, float *block_res, int total) -{ - extern __shared__ float sdata[]; - int in_idx = 2 * (blockIdx.x * blockDim.x + threadIdx.x); - int i = threadIdx.x; - unsigned ins = blockDim.x; - - if (in_idx >= total * 2) - sdata[i] = 0; - else - sdata[i] = in[in_idx] * in[in_idx] + in[in_idx + 1] * in[in_idx + 1]; - - for (unsigned outs = (ins + 1) / 2; ins > 1; ins = outs, outs = (outs + 1) / 2) { - __syncthreads(); - if (i + outs < ins) - sdata[i] += sdata[i + outs]; - } - - if (i == 0) - block_res[blockIdx.x] = sdata[0]; -} - -void ComplexMat_::sqr_norm(DynMem &result) const -{ - - assert(result.num_elem == n_scales); - - const uint total = n_channels / n_scales * rows * cols; - const dim3 threads(1024); - const dim3 blocks((total + threads.x - 1) / threads.x); - - DynMem block_res(blocks.x * n_scales); - - for (uint s = 0; s < n_scales; ++s) { - sqr_norm_kernel<<>>((const float*)(p_data.deviceMem() + s * total), - block_res.deviceMem() + s * blocks.x, total); - CudaCheckError(); - } - cudaSync(); - - for (uint s = 0; s < n_scales; ++s) { - T res = 0; - for (int i = 0; i < blocks.x; i++) - res += block_res[s * blocks.x + i]; - result.hostMem()[s] = res / static_cast(cols * rows); - } -} - -__global__ void sqr_mag_kernel(const float *data, float *result, int total) -{ - int idx = 2 * (blockIdx.x * blockDim.x + threadIdx.x); - - if (idx / 2 < total) { - result[idx] = data[idx] * data[idx] + data[idx + 1] * data[idx + 1]; - result[idx + 1] = 0; - } -} - -ComplexMat_ ComplexMat_::sqr_mag() const -{ - ComplexMat_ result = ComplexMat_::same_size(*this); - - const uint total = n_channels * rows * cols; - const dim3 threads(256); - const dim3 blocks((total + threads.x - 1) / threads.x); - - sqr_mag_kernel<<>>((float*)this->p_data.deviceMem(), - (float*)result.p_data.deviceMem(), - total); - CudaCheckError(); - - return result; -} - -__global__ void conj_kernel(const float *data, float *result, int total) -{ - int idx = 2 * (blockIdx.x * blockDim.x + threadIdx.x); - - if (idx / 2 < total) { - result[idx] = data[idx]; - result[idx + 1] = -data[idx + 1]; - } -} - -ComplexMat_ ComplexMat_::conj() const -{ - ComplexMat_ result = ComplexMat_::same_size(*this); - - const uint total = n_channels * rows * cols; - const dim3 threads(256); - const dim3 blocks((total + threads.x - 1) / threads.x); - - conj_kernel<<>>((float*)this->p_data.deviceMem(), (float*)result.p_data.deviceMem(), total); - CudaCheckError(); - - return result; -} - -__global__ static void sum_channels(float *dest, const float *src, uint channels, uint num_channel_elem) -{ - int idx = blockIdx.x * blockDim.x + threadIdx.x; - - if (idx >= num_channel_elem) - return; - - float acc = 0; - for (uint i = 0; i < channels; ++i) - acc += src[idx + i * num_channel_elem]; - dest[idx] = acc; -} - -ComplexMat_ ComplexMat_::sum_over_channels() const -{ - assert(p_data.num_elem == n_channels * rows * cols); - - uint n_channels_per_scale = n_channels / n_scales; - - ComplexMat_ result(this->rows, this->cols, 1, n_scales); - - const uint total = rows * cols * 2; - const dim3 threads(256); - const dim3 blocks((total + threads.x - 1) / threads.x); - - for (uint scale = 0; scale < n_scales; ++scale) { - sum_channels<<>>(reinterpret_cast(result.p_data.deviceMem() + scale * rows * cols), - reinterpret_cast(p_data.deviceMem() + scale * n_channels_per_scale * rows * cols), - n_channels_per_scale, total); - } - return result; -} - -__global__ void same_num_channels_mul_kernel(const float *data_l, const float *data_r, float *result, int total) -{ - int idx = 2 * (blockIdx.x * blockDim.x + threadIdx.x); - - if (idx / 2 < total) { - result[idx] = data_l[idx] * data_r[idx] - data_l[idx + 1] * data_r[idx + 1]; - result[idx + 1] = data_l[idx] * data_r[idx + 1] + data_l[idx + 1] * data_r[idx]; - } -} - -// element-wise per channel multiplication, division and addition -ComplexMat_ ComplexMat_::operator*(const ComplexMat_ &rhs) const -{ - assert(n_channels == n_scales * rhs.n_channels && rhs.cols == cols && rhs.rows == rows); - - ComplexMat_ result = ComplexMat_::same_size(*this); - - const uint total = n_channels / n_scales * rows * cols; - const dim3 threads(256); - const dim3 blocks((total + threads.x - 1) / threads.x); - - for (uint s = 0; s < n_scales; ++s) { - same_num_channels_mul_kernel<<>>((float*)(this->p_data.deviceMem() + s * total), - (float*)rhs.p_data.deviceMem(), - (float*)(result.p_data.deviceMem() + s * total), - total); - CudaCheckError(); - } - - return result; -} - -__global__ void same_num_channels_div_kernel(const float *data_l, const float *data_r, float *result, unsigned total) -{ - int idx = 2 * (blockIdx.x * blockDim.x + threadIdx.x); - - if (idx / 2 < total) { - result[idx] = (data_l[idx] * data_r[idx] + data_l[idx + 1] * data_r[idx + 1]) / - (data_r[idx] * data_r[idx] + data_r[idx + 1] * data_r[idx + 1]); - result[idx + 1] = (data_l[idx + 1] * data_r[idx] - data_l[idx] * data_r[idx + 1]) / - (data_r[idx] * data_r[idx] + data_r[idx + 1] * data_r[idx + 1]); - } -} - -ComplexMat_ ComplexMat_::operator/(const ComplexMat_ &rhs) const -{ - assert(rhs.n_channels == n_channels && rhs.cols == cols && rhs.rows == rows); - - ComplexMat_ result = ComplexMat_::same_size(*this); - - const uint total = n_channels * rows * cols; - const dim3 threads(256); - const dim3 blocks((total + threads.x - 1) / threads.x); - - same_num_channels_div_kernel<<>>((float*)this->p_data.deviceMem(), - (float*)rhs.p_data.deviceMem(), - (float*)result.p_data.deviceMem(), total); - CudaCheckError(); - - return result; -} - -__global__ void same_num_channels_add_kernel(const float *data_l, const float *data_r, float *result, int total) -{ - int idx = 2 * (blockIdx.x * blockDim.x + threadIdx.x); - - if (idx / 2 < total) { - result[idx] = data_l[idx] + data_r[idx]; - result[idx + 1] = data_l[idx + 1] + data_r[idx + 1]; - } -} - -ComplexMat_ ComplexMat_::operator+(const ComplexMat_ &rhs) const -{ - assert(rhs.n_channels == n_channels && rhs.cols == cols && rhs.rows == rows); - - ComplexMat_ result = ComplexMat_::same_size(*this); - - const uint total = n_channels * rows * cols; - const dim3 threads(256); - const dim3 blocks((total + threads.x - 1) / threads.x); - - same_num_channels_add_kernel<<>>((float*)this->p_data.deviceMem(), - (float*)rhs.p_data.deviceMem(), - (float*)result.p_data.deviceMem(), - total); - CudaCheckError(); - - return result; -} - -__global__ void constant_mul_kernel(const float *data_l, float constant, float *result, int total) -{ - int idx = 2 * (blockIdx.x * blockDim.x + threadIdx.x); - - if (idx / 2 < total) { - result[idx] = data_l[idx] * constant; - result[idx + 1] = data_l[idx + 1] * constant; - } -} - -ComplexMat_ ComplexMat_::operator*(const float &rhs) const -{ - ComplexMat_ result = ComplexMat_::same_size(*this); - - const uint total = n_channels * rows * cols; - const dim3 threads(256); - const dim3 blocks((total + threads.x - 1) / threads.x); - - constant_mul_kernel<<>>((float*)this->p_data.deviceMem(), - rhs, - (float*)result.p_data.deviceMem(), - total); - CudaCheckError(); - - return result; -} - -__global__ void constant_add_kernel(const float *data_l, float constant, float *result, int total) -{ - int idx = 2 * (blockIdx.x * blockDim.x + threadIdx.x); - - if (idx / 2 < total) { - result[idx] = data_l[idx] + constant; - result[idx + 1] = data_l[idx + 1]; - } -} - -ComplexMat_ ComplexMat_::operator+(const float &rhs) const -{ - ComplexMat_ result = ComplexMat_::same_size(*this); - - const uint total = n_channels * rows * cols; - const dim3 threads(256); - const dim3 blocks((total + threads.x - 1) / threads.x); - - constant_add_kernel<<>>((float*)this->p_data.deviceMem(), - rhs, - (float*)result.p_data.deviceMem(), - total); - CudaCheckError(); - - return result; -} - -__global__ void one_channel_mul_kernel(const float *data_l, const float *data_r, float *result, - int channel_total, int total) -{ - int idx = 2 * (blockIdx.x * blockDim.x + threadIdx.x); - int one_ch_idx = idx % (2 * channel_total); - - if (idx / 2 < total) { - result[idx] = data_l[idx] * data_r[one_ch_idx] - data_l[idx + 1] * data_r[one_ch_idx + 1]; - result[idx + 1] = data_l[idx] * data_r[one_ch_idx + 1] + data_l[idx + 1] * data_r[one_ch_idx]; - } -} - -// multiplying element-wise multichannel by one channel mats (rhs mat is with one channel) -ComplexMat_ ComplexMat_::mul(const ComplexMat_ &rhs) const -{ - assert(rhs.n_channels == 1 && rhs.cols == cols && rhs.rows == rows); - - ComplexMat_ result = ComplexMat_::same_size(*this); - - const uint total = n_channels * rows * cols; - const dim3 threads(256); - const dim3 blocks((total + threads.x - 1) / threads.x); - - one_channel_mul_kernel<<>>((float*)this->p_data.deviceMem(), - (float*)rhs.p_data.deviceMem(), - (float*)result.p_data.deviceMem(), - rows * cols, total); - CudaCheckError(); - - return result; -} - -// __global__ void scales_channel_mul_kernel(float *data_l, float *data_r, float *result) -// { -// int blockId = blockIdx.x + blockIdx.y * gridDim.x; -// int idx = 2 * (blockId * (blockDim.x * blockDim.y) + (threadIdx.y * blockDim.x) + threadIdx.x); -// int one_ch_index = 2 * ((threadIdx.y * blockDim.x) + threadIdx.x + blockIdx.x * blockDim.x * blockDim.y); - -// result[idx] = data_l[idx] * data_r[one_ch_index] - data_l[idx + 1] * data_r[one_ch_index + 1]; -// result[idx + 1] = data_l[idx] * data_r[one_ch_index + 1] + data_l[idx + 1] * data_r[one_ch_index]; -// } - -// multiplying element-wise multichannel by one channel mats (rhs mat is with multiple channel) -// ComplexMat_ ComplexMat_::mul2(const ComplexMat_ &rhs) const -// { -// assert(rhs.n_channels == n_channels / n_scales && rhs.cols == cols && rhs.rows == rows); - -// ComplexMat_ result(this->rows, this->cols, this->channels(), this->n_scales); - -// dim3 threadsPerBlock(rows, cols); -// dim3 numBlocks(n_channels / n_scales, n_scales); -// scales_channel_mul_kernel<<>>(this->p_data, rhs.p_data, result.p_data); -// CudaCheckError(); - -// return result; -// } - -// void ComplexMat_::operator=(ComplexMat_ &&rhs) -// { -// cols = rhs.cols; -// rows = rhs.rows; -// n_channels = rhs.n_channels; -// n_scales = rhs.n_scales; - -// p_data = rhs.p_data; - -// rhs.p_data = nullptr; -// } - -void ComplexMat_::cudaSync() const -{ - CudaSafeCall(cudaStreamSynchronize(cudaStreamPerThread)); -} From 343adee86a980829077fc899490030248c4120c3 Mon Sep 17 00:00:00 2001 From: oraveja1 <57142143+oraveja1@users.noreply.github.com> Date: Wed, 8 Jan 2020 22:34:45 +0100 Subject: [PATCH 077/121] Delete complexmat.hpp --- src/complexmat.hpp | 181 --------------------------------------------- 1 file changed, 181 deletions(-) delete mode 100644 src/complexmat.hpp diff --git a/src/complexmat.hpp b/src/complexmat.hpp deleted file mode 100644 index 0d5e69f9..00000000 --- a/src/complexmat.hpp +++ /dev/null @@ -1,181 +0,0 @@ -//#ifndef COMPLEX_MAT_HPP_213123048309482094 -//#define COMPLEX_MAT_HPP_213123048309482094 -// -//#include -//#include -//#include -//#include -//#include "dynmem.hpp" -//#include "pragmas.h" -// -//#ifdef CUFFT -//#include -//#endif -// -//class ComplexMat_ { -// public: -// typedef float T; -// -// uint cols; -// uint rows; -// uint n_channels; -// 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(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(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) -// { -// cudaSync(); -// memcpy(p_data.hostMem(), mat.ptr>(), mat.total() * mat.elemSize()); -// } -// -// static ComplexMat_ same_size(const ComplexMat_ &o) -// { -// return ComplexMat_(o.rows, o.cols, o.n_channels / o.n_scales, o.n_scales); -// } -// -// // cv::Mat API compatibility -// cv::Size size() const { return cv::Size(cols, rows); } -// uint channels() const { return n_channels; } -// -// // assuming that mat has 2 channels (real, imag) -// void set_channel(uint idx, const cv::Mat &mat) -// { -// assert(idx < n_channels); -// cudaSync(); -// for (uint i = 0; i < rows; ++i) { -// const std::complex *row = mat.ptr>(i); -// for (uint j = 0; j < cols; ++j) -// p_data.hostMem()[idx * rows * cols + i * cols + j] = row[j]; -// } -// } -// -// T sqr_norm() const; -// -// void sqr_norm(DynMem_ &result) const; -// -// ComplexMat_ sqr_mag() const; -// -// ComplexMat_ conj() const; -// -// ComplexMat_ sum_over_channels() const; -// -// // return 2 channels (real, imag) for first complex channel -// cv::Mat to_cv_mat() const -// { -// assert(p_data.num_elem >= 1); -// return channel_to_cv_mat(0); -// } -// // return a vector of 2 channels (real, imag) per one complex channel -// std::vector to_cv_mat_vector() const -// { -// std::vector result; -// result.reserve(n_channels); -// -// for (uint i = 0; i < n_channels; ++i) -// result.push_back(channel_to_cv_mat(i)); -// -// return result; -// } -// -// std::complex *get_p_data() { -// cudaSync(); -// return p_data.hostMem(); -// } -// const std::complex *get_p_data() const { -// cudaSync(); -// return p_data.hostMem(); -// } -// -//#ifdef CUFFT -// cufftComplex *get_dev_data() { return (cufftComplex*)p_data.deviceMem(); } -// const cufftComplex *get_dev_data() const { return (cufftComplex*)p_data.deviceMem(); } -//#endif -// -// // element-wise per channel multiplication, division and addition -// ComplexMat_ operator*(const ComplexMat_ &rhs) const; -// ComplexMat_ operator/(const ComplexMat_ &rhs) const; -// ComplexMat_ operator+(const ComplexMat_ &rhs) const; -// -// // multiplying or adding constant -// ComplexMat_ operator*(const T &rhs) const; -// ComplexMat_ operator+(const T &rhs) const; -// -// // multiplying element-wise multichannel by one channel mats (rhs mat is with one channel) -// ComplexMat_ mul(const ComplexMat_ &rhs) const; -// -// // multiplying element-wise multichannel mats - same as operator*(ComplexMat), but without allocating memory for the result -// ComplexMat_ muln(const ComplexMat_ &rhs) const -// { -// return mat_mat_operator([](std::complex &c_lhs, const std::complex &c_rhs) { c_lhs *= c_rhs; }, rhs); -// } -// -// // text output -// friend std::ostream &operator<<(std::ostream &os, const ComplexMat_ &mat) -// { -// // for (int i = 0; i < mat.n_channels; ++i){ -// for (int i = 0; i < 1; ++i) { -// os << "Channel " << i << std::endl; -// for (uint j = 0; j < mat.rows; ++j) { -// for (uint k = 0; k < mat.cols - 1; ++k) -// os << mat.p_data[j * mat.cols + k] << ", "; -// os << mat.p_data[j * mat.cols + mat.cols - 1] << std::endl; -// } -// } -// return os; -// } -// -// private: -// DynMem_> p_data; -// -// // convert 2 channel mat (real, imag) to vector row-by-row -// std::vector> convert(const cv::Mat &mat) -// { -// std::vector> result; -// result.reserve(mat.cols * mat.rows); -// for (int y = 0; y < mat.rows; ++y) { -// const T *row_ptr = mat.ptr(y); -// for (int x = 0; x < 2 * mat.cols; x += 2) { -// result.push_back(std::complex(row_ptr[x], row_ptr[x + 1])); -// } -// } -// return result; -// } -// -// ComplexMat_ mat_mat_operator(void (*op)(std::complex &c_lhs, const std::complex &c_rhs), -// const ComplexMat_ &mat_rhs) const; -// ComplexMat_ matn_mat1_operator(void (*op)(std::complex &c_lhs, const std::complex &c_rhs), -// const ComplexMat_ &mat_rhs) const; -// ComplexMat_ matn_mat2_operator(void (*op)(std::complex &c_lhs, const std::complex &c_rhs), -// const ComplexMat_ &mat_rhs) const; -// ComplexMat_ mat_const_operator(const std::function &c_rhs)> &op) const; -// -// cv::Mat channel_to_cv_mat(int channel_id) const -// { -// cv::Mat result(rows, cols, CV_32FC2); -// for (uint y = 0; y < rows; ++y) { -// std::complex *row_ptr = result.ptr>(y); -// for (uint x = 0; x < cols; ++x) { -// row_ptr[x] = p_data[channel_id * rows * cols + y * cols + x]; -// } -// } -// return result; -// } -// -//#ifdef CUFFT -// void cudaSync() const; -//#else -// void cudaSync() const {} -//#endif -//}; -// -//typedef ComplexMat_ ComplexMat; -// -//#endif // COMPLEX_MAT_HPP_213123048309482094 From 081fd1cc0a79118e7ca442d9a092032c8b0dfbbc Mon Sep 17 00:00:00 2001 From: oraveja1 <57142143+oraveja1@users.noreply.github.com> Date: Wed, 8 Jan 2020 22:34:57 +0100 Subject: [PATCH 078/121] Delete complexmat.cpp --- src/complexmat.cpp | 149 --------------------------------------------- 1 file changed, 149 deletions(-) delete mode 100644 src/complexmat.cpp diff --git a/src/complexmat.cpp b/src/complexmat.cpp deleted file mode 100644 index 5ce178fc..00000000 --- a/src/complexmat.cpp +++ /dev/null @@ -1,149 +0,0 @@ -//#include "complexmat.hpp" -// -//ComplexMat_::T ComplexMat_::sqr_norm() const -//{ -// assert(n_scales == 1); -// -// int n_channels_per_scale = n_channels / n_scales; -// T sum_sqr_norm = 0; -// for (int i = 0; i < n_channels_per_scale; ++i) { -// for (auto lhs = p_data.hostMem() + i * rows * cols; lhs != p_data.hostMem() + (i + 1) * rows * cols; ++lhs) -// sum_sqr_norm += lhs->real() * lhs->real() + lhs->imag() * lhs->imag(); -// } -// sum_sqr_norm = sum_sqr_norm / static_cast(cols * rows); -// return sum_sqr_norm; -//} -// -//void ComplexMat_::sqr_norm(DynMem_ &result) const -//{ -// int n_channels_per_scale = n_channels / n_scales; -// int scale_offset = n_channels_per_scale * rows * cols; -// 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.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(cols * rows); -// } -// return; -//} -// -//ComplexMat_ ComplexMat_::sqr_mag() const -//{ -// return mat_const_operator([](std::complex &c) { c = c.real() * c.real() + c.imag() * c.imag(); }); -//} -// -//ComplexMat_ ComplexMat_::conj() const -//{ -// return mat_const_operator([](std::complex &c) { c = std::complex(c.real(), -c.imag()); }); -//} -// -//ComplexMat_ ComplexMat_::sum_over_channels() const -//{ -// 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; -// -// ComplexMat_ result(this->rows, this->cols, 1, n_scales); -// for (uint scale = 0; scale < n_scales; ++scale) { -// for (uint i = 0; i < rows * cols; ++i) { -// std::complex 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.hostMem()[scale * rows * cols + i] = acc; -// } -// } -// return result; -//} -// -//ComplexMat_ ComplexMat_::operator/(const ComplexMat_ &rhs) const -//{ -// return mat_mat_operator([](std::complex &c_lhs, const std::complex &c_rhs) { c_lhs /= c_rhs; }, rhs); -//} -// -//ComplexMat_ ComplexMat_::operator+(const ComplexMat_ &rhs) const -//{ -// return mat_mat_operator([](std::complex &c_lhs, const std::complex &c_rhs) { c_lhs += c_rhs; }, rhs); -//} -// -//ComplexMat_ ComplexMat_::operator*(const ComplexMat_::T &rhs) const -//{ -// return mat_const_operator([&rhs](std::complex &c) { c *= rhs; }); -//} -// -//ComplexMat_ ComplexMat_::mul(const ComplexMat_ &rhs) const -//{ -// return matn_mat1_operator([](std::complex &c_lhs, const std::complex &c_rhs) { c_lhs *= c_rhs; }, rhs); -//} -// -//ComplexMat_ ComplexMat_::operator+(const ComplexMat_::T &rhs) const -//{ -// return mat_const_operator([&rhs](std::complex &c) { c += rhs; }); -//} -// -//ComplexMat_ ComplexMat_::operator*(const ComplexMat_ &rhs) const -//{ -// return mat_mat_operator([](std::complex &c_lhs, const std::complex &c_rhs) { c_lhs *= c_rhs; }, rhs); -//} -// -//ComplexMat_ ComplexMat_::mat_mat_operator(void (*op)(std::complex &, const std::complex &), const ComplexMat_ &mat_rhs) const -//{ -// assert(mat_rhs.n_channels == n_channels/n_scales && mat_rhs.cols == cols && mat_rhs.rows == rows); -// -// ComplexMat_ result = *this; -// for (uint s = 0; s < n_scales; ++s) { -// 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)); -// } -// -// return result; -//} -// -//ComplexMat_ ComplexMat_::matn_mat1_operator(void (*op)(std::complex &, const std::complex &), const ComplexMat_ &mat_rhs) const -//{ -// assert(mat_rhs.n_channels == 1 && mat_rhs.cols == cols && mat_rhs.rows == rows); -// -// ComplexMat_ result = *this; -// for (uint i = 0; i < n_channels; ++i) { -// 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); -// } -// -// return result; -//} -// -//ComplexMat_ ComplexMat_::matn_mat2_operator(void (*op)(std::complex &, const std::complex &), const ComplexMat_ &mat_rhs) const -//{ -// assert(mat_rhs.n_channels == n_channels / n_scales && mat_rhs.cols == cols && mat_rhs.rows == rows); -// -// int n_channels_per_scale = n_channels / n_scales; -// int scale_offset = n_channels_per_scale * rows * cols; -// ComplexMat_ result = *this; -// for (uint i = 0; i < n_scales; ++i) { -// for (int j = 0; j < n_channels_per_scale; ++j) { -// auto lhs = result.p_data.hostMem() + (j * rows * cols) + (i * scale_offset); -// auto rhs = mat_rhs.p_data.hostMem() + (j * rows * cols); -// for (; lhs != result.p_data.hostMem() + ((j + 1) * rows * cols) + (i * scale_offset); ++lhs, ++rhs) -// op(*lhs, *rhs); -// } -// } -// -// return result; -//} -// -//ComplexMat_ ComplexMat_::mat_const_operator(const std::function &)> &op) const -//{ -// ComplexMat_ result = *this; -// for (uint i = 0; i < n_channels; ++i) { -// for (auto lhs = result.p_data.hostMem() + i * rows * cols; -// lhs != result.p_data.hostMem() + (i + 1) * rows * cols; ++lhs) -// op(*lhs); -// } -// return result; -//} From d25660a7acbe867d95f5d3f8c58580ba829055d7 Mon Sep 17 00:00:00 2001 From: oraveja1 <57142143+oraveja1@users.noreply.github.com> Date: Wed, 8 Jan 2020 22:35:06 +0100 Subject: [PATCH 079/121] Delete dynmem.hpp --- src/dynmem.hpp | 210 ------------------------------------------------- 1 file changed, 210 deletions(-) delete mode 100644 src/dynmem.hpp diff --git a/src/dynmem.hpp b/src/dynmem.hpp deleted file mode 100644 index 39ee10ca..00000000 --- a/src/dynmem.hpp +++ /dev/null @@ -1,210 +0,0 @@ -//#ifndef DYNMEM_HPP -//#define DYNMEM_HPP -// -//#include -//#include -//#include -//#include -//#include -//#include -// -//#if defined(CUFFT) || defined(CUFFTW) -//#include "cuda_runtime.h" -//#ifdef CUFFT -//#include "cuda_error_check.hpp" -//#endif -//#endif -// -//class MemoryManager { -// std::mutex mutex; -// std::map > map; -// -//public: -// void *get(size_t size) { -// std::lock_guard guard(mutex); -// auto &stack = map[size]; -// void *ptr = nullptr; -// if (!stack.empty()) { -// ptr = stack.top(); -// stack.pop(); -// } -// return ptr; -// } -// void put(void *ptr, size_t size) { -// std::lock_guard guard(mutex); -// map[size].push(ptr); -// } -//}; -// -//template class DynMem_ { -// private: -// T *ptr_h = nullptr; -//#ifdef CUFFT -// T *ptr_d = nullptr; -// static MemoryManager mmng; -//#endif -// public: -// typedef T value_type; -// const size_t num_elem; -// -// DynMem_(size_t num_elem) : num_elem(num_elem) -// { -//#ifdef CUFFT -// ptr_h = reinterpret_cast(mmng.get(num_elem)); -// if (!ptr_h) -// CudaSafeCall(cudaHostAlloc(reinterpret_cast(&ptr_h), num_elem * sizeof(T), cudaHostAllocMapped)); -// -// CudaSafeCall(cudaHostGetDevicePointer(reinterpret_cast(&ptr_d), reinterpret_cast(ptr_h), 0)); -//#else -// 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; -// other.ptr_h = nullptr; -//#ifdef CUFFT -// ptr_d = other.ptr_d; -// other.ptr_d = nullptr; -//#endif -// } -// ~DynMem_() -// { -// release(); -// } -// T *hostMem() { return ptr_h; } -// const T *hostMem() const { return ptr_h; } -//#ifdef CUFFT -// T *deviceMem() { return ptr_d; } -// const T *deviceMem() const { return ptr_d; } -//#endif -// void operator=(DynMem_ &rhs) { -// assert(num_elem == rhs.num_elem); -// memcpy(ptr_h, rhs.ptr_h, num_elem * sizeof(T)); -// } -// void operator=(DynMem_ &&rhs) -// { -// assert(num_elem == rhs.num_elem); -// release(); -// ptr_h = rhs.ptr_h; -// rhs.ptr_h = nullptr; -//#ifdef CUFFT -// ptr_d = rhs.ptr_d; -// rhs.ptr_d = nullptr; -//#endif -// } -// T operator[](uint i) const { return ptr_h[i]; } -//private: -// void release() -// { -//#ifdef CUFFT -// if (ptr_h) -// mmng.put(ptr_h, num_elem); -// //CudaSafeCall(cudaFreeHost(ptr_h)); -//#else -// delete[] ptr_h; -//#endif -// } -//}; -// -//#ifdef CUFFT -//template -//MemoryManager DynMem_::mmng; -//#endif -// -//typedef DynMem_ DynMem; -// -// -//class MatDynMem : public DynMem, public cv::Mat { -// public: -// MatDynMem(cv::Size size, int type) -// : DynMem(size.area() * CV_MAT_CN(type)), cv::Mat(size, type, hostMem()) -// { -// assert((type & CV_MAT_DEPTH_MASK) == CV_32F); -// } -// MatDynMem(int height, int width, int type) -// : DynMem(width * height * CV_MAT_CN(type)), cv::Mat(height, width, type, hostMem()) -// { -// assert((type & CV_MAT_DEPTH_MASK) == CV_32F); -// } -// MatDynMem(int ndims, const int *sizes, int type) -// : DynMem(volume(ndims, sizes) * CV_MAT_CN(type)), cv::Mat(ndims, sizes, type, hostMem()) -// { -// assert((type & CV_MAT_DEPTH_MASK) == CV_32F); -// } -// MatDynMem(std::vector size, int type) -// : DynMem(std::accumulate(size.begin(), size.end(), 1, std::multiplies())) -// , cv::Mat(size.size(), size.data(), type, hostMem()) {} -// MatDynMem(MatDynMem &&other) = default; -// MatDynMem(const cv::Mat &other) -// : DynMem(other.total()) , cv::Mat(other) {} -// -// void operator=(const cv::MatExpr &expr) { -// static_cast(*this) = expr; -// } -// -// private: -// static int volume(int ndims, const int *sizes) -// { -// int vol = 1; -// for (int i = 0; i < ndims; i++) -// vol *= sizes[i]; -// return vol; -// } -// -// 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)); -// } -// const cv::Mat plane(uint idx) const { -// assert(dims == 3); -// assert(int(idx) < size[0]); -// return cv::Mat(size[1], size[2], cv::Mat::type(), const_cast(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)); -// } -// cv::Mat scale(uint scale) { -// assert(dims == 4); -// assert(int(scale) < size[0]); -// return cv::Mat(3, std::vector({size[1], size[2], size[3]}).data(), cv::Mat::type(), ptr(scale)); -// } -//}; -// -//#endif // DYNMEM_HPP From dd3a79fa05bec61619860ee1ad005a85f9285fcb Mon Sep 17 00:00:00 2001 From: Your Name Date: Sat, 7 Mar 2020 22:32:19 +0100 Subject: [PATCH 080/121] =?UTF-8?q?Opraveny=20hl=C3=A1=C5=A1ky=20o=20nenal?= =?UTF-8?q?ezen=C3=BDch=20jm=C3=A9nech=20OpenCV=20konstant=20-=20byla=20kn?= =?UTF-8?q?ihovna=20na=20pracovn=C3=AD=20stanici=20ned=C3=A1vno=20aktualiz?= =?UTF-8?q?ov=C3=A1na=3F?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- main_vot.cpp | 4 +++- src/kcf.cpp | 5 +++-- vot.hpp | 3 ++- 3 files changed, 8 insertions(+), 4 deletions(-) diff --git a/main_vot.cpp b/main_vot.cpp index d4d13c16..7870f53e 100644 --- a/main_vot.cpp +++ b/main_vot.cpp @@ -11,6 +11,8 @@ #include "kcf.h" #include "vot.hpp" #include "videoio.hpp" +#include +#include // Needed for OpenCV <= 3.2 as replacement for Rect::empty() bool empty(cv::Rect r) @@ -297,7 +299,7 @@ int main(int argc, char *argv[]) io->outputBoundingBox(init_rect); if (!video_out.empty()) { - int codec = CV_FOURCC('M', 'J', 'P', 'G'); // select desired codec (must be available at runtime) + int codec = cv::VideoWriter::fourcc('M', 'J', 'P', 'G'); // select desired codec (must be available at runtime) double fps = 25.0; // framerate of the created video stream videoWriter.open(video_out, codec, fps, image.size(), true); } diff --git a/src/kcf.cpp b/src/kcf.cpp index a244326e..d95fae3f 100644 --- a/src/kcf.cpp +++ b/src/kcf.cpp @@ -8,6 +8,7 @@ #include "threadctx.hpp" #include "debug.h" #include +#include #ifdef OPENMP #include @@ -154,7 +155,7 @@ void KCF_Tracker::init(cv::Mat &img, const cv::Rect &bbox, int fit_size_x, int f cv::Mat input_gray, input_rgb = img.clone(); if (img.channels() == 3) { - cv::cvtColor(img, input_gray, CV_BGR2GRAY); + cv::cvtColor(img, input_gray, cv::COLOR_BGR2GRAY); input_gray.convertTo(input_gray, CV_32FC1); } else img.convertTo(input_gray, CV_32FC1); @@ -403,7 +404,7 @@ void KCF_Tracker::track(cv::Mat &img) cv::Mat input_gray, input_rgb = img.clone(); if (img.channels() == 3) { - cv::cvtColor(img, input_gray, CV_BGR2GRAY); + cv::cvtColor(img, input_gray, cv::COLOR_BGR2GRAY); input_gray.convertTo(input_gray, CV_32FC1); } else img.convertTo(input_gray, CV_32FC1); diff --git a/vot.hpp b/vot.hpp index eaf1245b..58bbc55c 100644 --- a/vot.hpp +++ b/vot.hpp @@ -13,6 +13,7 @@ #include #include #include "videoio.hpp" +#include // Bounding box type @@ -160,7 +161,7 @@ class VOT : public VideoIO std::string line; std::getline (p_images_stream, line); if (line.empty() && p_images_stream.eof()) return -1; - img = cv::imread(line, CV_LOAD_IMAGE_COLOR); + img = cv::imread(line, cv::IMREAD_COLOR); num++; return 1; From a9e5edd5915e21aed6c5e1893ecd29e70ccc4219 Mon Sep 17 00:00:00 2001 From: Your Name Date: Fri, 27 Mar 2020 12:51:53 +0100 Subject: [PATCH 081/121] =?UTF-8?q?Opraven=20CMakeLists.txt,=20aby=20se=20?= =?UTF-8?q?nepokou=C5=A1el=20kompilovat=20odstran=C4=9Bn=C3=A9=20soubory?= =?UTF-8?q?=20-=20tzn.=20soubory=20jm=C3=A9nem=20complexmat=20a=20dynmem?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- src/CMakeLists.txt | 8 +------- 1 file changed, 1 insertion(+), 7 deletions(-) diff --git a/src/CMakeLists.txt b/src/CMakeLists.txt index 7ed9f605..92fcc543 100644 --- a/src/CMakeLists.txt +++ b/src/CMakeLists.txt @@ -1,6 +1,6 @@ cmake_minimum_required(VERSION 2.8) -set(KCF_LIB_SRC kcf.cpp kcf.h fft.cpp threadctx.hpp pragmas.h dynmem.hpp debug.cpp complexmat.hpp) +set(KCF_LIB_SRC kcf.cpp kcf.h fft.cpp threadctx.hpp pragmas.h debug.cpp) find_package(PkgConfig) @@ -51,12 +51,6 @@ ELSE() MESSAGE(FATAL_ERROR "Invalid FFT implementation selected") ENDIF() -IF(FFT STREQUAL "cuFFT") - list(APPEND KCF_LIB_SRC complexmat.cu) -ELSE() - list(APPEND KCF_LIB_SRC complexmat.cpp) -ENDIF() - IF((FFT STREQUAL "OpenCV") AND BIG_BATCH) message(SEND_ERROR "OpenCV version does not support big batch mode.") ENDIF() From 61f74b8f7dcaf91ee984c1b58b80bc7a8a384dff Mon Sep 17 00:00:00 2001 From: Your Name Date: Fri, 27 Mar 2020 13:06:01 +0100 Subject: [PATCH 082/121] =?UTF-8?q?Opravena=20GitHub=20hl=C3=A1=C5=A1ka=20?= =?UTF-8?q?o=20neexistuj=C3=ADc=C3=ADm=20include=20"opencv2/imgcodecs"?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- vot.hpp | 1 - 1 file changed, 1 deletion(-) diff --git a/vot.hpp b/vot.hpp index 58bbc55c..d52f90c7 100644 --- a/vot.hpp +++ b/vot.hpp @@ -13,7 +13,6 @@ #include #include #include "videoio.hpp" -#include // Bounding box type From 4422851dcfe7fd93d54a5739b2fad48f4547c1fe Mon Sep 17 00:00:00 2001 From: Your Name Date: Fri, 27 Mar 2020 13:15:48 +0100 Subject: [PATCH 083/121] =?UTF-8?q?Opravena=20GitHub=20hl=C3=A1=C5=A1ka=20?= =?UTF-8?q?o=20neexistuj=C3=ADc=C3=ADm=20include=20"opencv2/videoio"?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- vot.hpp | 1 - 1 file changed, 1 deletion(-) diff --git a/vot.hpp b/vot.hpp index d52f90c7..131ca33f 100644 --- a/vot.hpp +++ b/vot.hpp @@ -11,7 +11,6 @@ #include #include #include -#include #include "videoio.hpp" From 0eeba28b01895213b99feca6f4d4bcec795dde5c Mon Sep 17 00:00:00 2001 From: Your Name Date: Fri, 27 Mar 2020 13:38:52 +0100 Subject: [PATCH 084/121] =?UTF-8?q?Opravena=20GitHub=20hl=C3=A1=C5=A1ka=20?= =?UTF-8?q?o=20neexistuj=C3=ADc=C3=ADm=20include=20"opencv2/videoio"=20-?= =?UTF-8?q?=20tentokr=C3=A1t=20v=20main=5Fvot.cpp?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- main_vot.cpp | 1 - 1 file changed, 1 deletion(-) diff --git a/main_vot.cpp b/main_vot.cpp index 7870f53e..b2e7e639 100644 --- a/main_vot.cpp +++ b/main_vot.cpp @@ -11,7 +11,6 @@ #include "kcf.h" #include "vot.hpp" #include "videoio.hpp" -#include #include // Needed for OpenCV <= 3.2 as replacement for Rect::empty() From 18665b9e03d2c355fdf7a5ce7cbc64c4f3774707 Mon Sep 17 00:00:00 2001 From: Your Name Date: Sun, 5 Apr 2020 00:02:35 +0200 Subject: [PATCH 085/121] =?UTF-8?q?Vytvo=C5=99en=20UMat=20override=20pro?= =?UTF-8?q?=20vypisovac=C3=AD=20funkci=20debuggeru?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- src/debug.cpp | 12 ++++++++++++ src/debug.h | 1 + 2 files changed, 13 insertions(+) diff --git a/src/debug.cpp b/src/debug.cpp index c47e1387..3a754634 100644 --- a/src/debug.cpp +++ b/src/debug.cpp @@ -14,3 +14,15 @@ std::ostream &operator<<(std::ostream &os, const DbgTracer::Printer &p) return os; } +std::ostream &operator<<(std::ostream &os, const DbgTracer::Printer &p) +{ + IOSave s(os); + os << std::setprecision(DbgTracer::precision); + os << p.obj.size << " " << p.obj.channels() << "ch ";// << static_cast(p.obj.data); + os << " = [ "; + const size_t num = 10; //p.obj.total(); + for (size_t i = 0; i < std::min(num, p.obj.total() * p.obj.channels()); ++i) + os << p.obj.getMat(cv::ACCESS_READ).ptr()[i] << ", "; + os << (num < (p.obj.total() * p.obj.channels()) ? "... ]" : "]"); + return os; +} \ No newline at end of file diff --git a/src/debug.h b/src/debug.h index 18707ec1..df83bd9d 100644 --- a/src/debug.h +++ b/src/debug.h @@ -116,6 +116,7 @@ static inline std::ostream &operator<<(std::ostream &out, const cv::MatSize &msi #endif std::ostream &operator<<(std::ostream &os, const DbgTracer::Printer &p); +std::ostream &operator<<(std::ostream &os, const DbgTracer::Printer &p); #if defined(CUFFT) static inline std::ostream &operator<<(std::ostream &os, const cufftComplex &p) From 420977102fb9178bcc4483bcd9c6c1ffa9fd109b Mon Sep 17 00:00:00 2001 From: Your Name Date: Tue, 7 Apr 2020 20:29:00 +0200 Subject: [PATCH 086/121] =?UTF-8?q?Vytvo=C5=99eny=20testovac=C3=AD=20prom?= =?UTF-8?q?=C4=9Bnn=C3=A9=20typu=20UMat=20pro=20t=C5=99=C3=ADdy=20Model=20?= =?UTF-8?q?a=20GaussianCorrelation?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- src/kcf.cpp | 63 +++++++++++++++++++++++++++++++++++++++++++++++++++++ src/kcf.h | 28 +++++++++++++++++++++++- 2 files changed, 90 insertions(+), 1 deletion(-) diff --git a/src/kcf.cpp b/src/kcf.cpp index d95fae3f..84ad5112 100644 --- a/src/kcf.cpp +++ b/src/kcf.cpp @@ -117,6 +117,69 @@ void KCF_Tracker::init(cv::Mat &img, const cv::Rect &bbox, int fit_size_x, int f { __dbgTracer.debug = m_debug; TRACE(""); + +// cv::UMat test = cv::UMat(2,2,CV_32FC4,float(1)); +// cv::UMat test = cv::UMat(3, std::vector({2, 2, 2}).data(), CV_32FC2, float(5)); +// cv::UMat testPl = cv::UMat(test.size[1], test.size[2], test.type(), test.ptr(0)); + +// +//// cv::Mat_> testComplex = cv::Mat_>(test2); +// +// test.getMat(cv::ACCESS_WRITE).ptr(0)[0] = float(1); +// test.getMat(cv::ACCESS_WRITE).ptr(0)[1] = float(2); +// test.getMat(cv::ACCESS_WRITE).ptr(0)[2] = float(3); +// test.getMat(cv::ACCESS_WRITE).ptr(0)[3] = float(4); +// test.getMat(cv::ACCESS_WRITE).ptr(0)[4] = float(5); +// test.getMat(cv::ACCESS_WRITE).ptr(0)[5] = float(6); +// test.getMat(cv::ACCESS_WRITE).ptr(0)[6] = float(7); +// test.getMat(cv::ACCESS_WRITE).ptr(0)[7] = float(8); +// test.getMat(cv::ACCESS_WRITE).ptr(1)[0] = float(9); +// test.getMat(cv::ACCESS_WRITE).ptr(1)[1] = float(10); +// test.getMat(cv::ACCESS_WRITE).ptr(1)[2] = float(11); +// test.getMat(cv::ACCESS_WRITE).ptr(1)[3] = float(12); +// test.getMat(cv::ACCESS_WRITE).ptr(1)[4] = float(13); +// test.getMat(cv::ACCESS_WRITE).ptr(1)[5] = float(14); +// test.getMat(cv::ACCESS_WRITE).ptr(1)[6] = float(15); +// test.getMat(cv::ACCESS_WRITE).ptr(1)[7] = float(16); +// +// cv::Mat matTest = cv::Mat(test.size[1], test.size[2], test.type(), test.getMat(cv::ACCESS_READ).ptr(1)); +// cv::UMat testPl = matTest.getUMat(cv::ACCESS_RW); +// cv::UMat test2 = cv::UMat(2,2,CV_32FC2,float(6)); +// DEBUG_PRINTM(test); +// DEBUG_PRINTM(testPl); +// DEBUG_PRINTM(test2); +// return; +// +// int from_to[] = { 0,0 }; +// cv::mixChannels(&testPl,1,&test2,1,from_to,1); +// int from_to2[] = { 1,1 }; +// cv::mixChannels(&testPl,1,&test2,1,from_to2,1); +// +// DEBUG_PRINTM(test2); +// return; +// +// +// assert(test.channels() % 2 == 0); +// for (uint i = 0; i < test.rows; ++i) { +// for (uint j = 0; j < test.cols; ++j){ +// for (uint k = 0; k < test.channels() / 2 ; ++k){ +// std::complex cpxVal = test.ptr>(i)[(test.channels() / 2)*j + k]; +// cpxVal.imag(- cpxVal.imag()); +// test.ptr>(i)[(test.channels() / 2)*j + k] = cpxVal; +// DEBUG_PRINTM(cpxVal); +// } +// } +// } +// +// cv::Mat test = cv::Mat(3, std::vector({2, 2, 2}).data(), CV_32FC2, float(5)); +// test.ptr(0)[0] = float(1); +// test.ptr(1)[0] = float(1); +// test.ptr(1,1)[0] = float(1); +// +// DEBUG_PRINTM(test); +// +// +// return; // check boundary, enforce min size double x1 = bbox.x, x2 = bbox.x + bbox.width, y1 = bbox.y, y2 = bbox.y + bbox.height; diff --git a/src/kcf.h b/src/kcf.h index a21497a9..a1b9b2bb 100644 --- a/src/kcf.h +++ b/src/kcf.h @@ -5,6 +5,7 @@ #include #include #include "fhog.hpp" +#include "debug.h" #ifdef CUFFT #include "cuda_error_check.hpp" @@ -145,11 +146,28 @@ class KCF_Tracker cv::Mat temp{ 4, std::vector({1, int(n_feats), feature_size.height, feature_size.width}).data(), CV_32F}; + cv::UMat yf_Test = cv::UMat::zeros((int) height, (int) width, CV_32FC2); + cv::UMat model_alphaf_Test = cv::UMat::zeros((int) height, (int) width, CV_32FC2); + cv::UMat model_alphaf_num_Test = cv::UMat::zeros((int) height, (int) width, CV_32FC2); + cv::UMat model_alphaf_den_Test = cv::UMat::zeros((int) height, (int) width, CV_32FC2); + cv::UMat model_xf_Test; + cv::UMat xf_Test; + + cv::UMat patch_feats_Test{ 4, std::vector({1, int(n_feats), feature_size.height, feature_size.width}).data(), CV_32F}; + cv::UMat temp_Test{ 4, std::vector({1, int(n_feats), feature_size.height, feature_size.width}).data(), CV_32F}; + + 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) {} + , n_feats(_n_feats) { + + cv::Mat model_xf_temp = cv::Mat::zeros((int) height, (int) width, CV_32FC(n_feats*2)); + cv::Mat xf_temp = cv::Mat::zeros((int) height, (int) width, CV_32FC(n_feats*2)); + model_xf_Test = model_xf_temp.getUMat(cv::ACCESS_RW); + xf_Test = xf_temp.getUMat(cv::ACCESS_RW); + } }; std::unique_ptr model; @@ -162,6 +180,10 @@ class KCF_Tracker xyf = cv::Mat(3, std::vector({(int) num_scales, temp.height, temp.width}).data(), CV_32FC(num_feats*2)); ifft_res = cv::Mat(3, std::vector({(int) num_scales, size.height, size.width}).data(), CV_32F); k = cv::Mat(3, std::vector({(int) num_scales, size.height, size.width}).data(), CV_32F); + + xyf_Test = cv::UMat(3, std::vector({(int) num_scales, temp.height, temp.width}).data(), CV_32FC(num_feats*2)); + ifft_res_Test = cv::UMat(3, std::vector({(int) num_scales, size.height, size.width}).data(), CV_32F); + k_Test = cv::UMat(3, std::vector({(int) num_scales, size.height, size.width}).data(), CV_32F); } void operator()(cv::Mat &result, cv::Mat &xf, cv::Mat &yf, double sigma, bool auto_correlation, const KCF_Tracker &kcf); @@ -171,6 +193,10 @@ class KCF_Tracker cv::Mat xyf; cv::Mat ifft_res; cv::Mat k; + + cv::UMat xyf_Test; + cv::UMat ifft_res_Test; + cv::UMat k_Test; }; //helping functions From 4cf70037fe77f012842c2297a20e9f37fdd66a06 Mon Sep 17 00:00:00 2001 From: Your Name Date: Tue, 7 Apr 2020 21:45:05 +0200 Subject: [PATCH 087/121] =?UTF-8?q?Vytvo=C5=99eny=20v=C5=A1echny=20alterna?= =?UTF-8?q?tivn=C3=AD=20verze=20funkc=C3=AD=20MatUtil=20pro=20datov=C3=BD?= =?UTF-8?q?=20typ=20cv::UMat=20-=20je=20t=C5=99eba=20je=C5=A1t=C4=9B=20ote?= =?UTF-8?q?stovat=20shodnost=20v=C3=BDstup=C5=AF=20s=20verz=C3=AD=20pro=20?= =?UTF-8?q?cv::Mat?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- src/matutil.h | 157 +++++++++++++++++++++++++++++++++++++++++++++++++- 1 file changed, 156 insertions(+), 1 deletion(-) diff --git a/src/matutil.h b/src/matutil.h index aa9025d5..c23d5712 100644 --- a/src/matutil.h +++ b/src/matutil.h @@ -20,6 +20,14 @@ static cv::Mat plane(uint scale, uint feature, cv::Mat &host) { return cv::Mat(host.size[2], host.size[3], host.type(), host.ptr(scale, feature)); } +static cv::UMat plane(uint scale, uint feature, cv::UMat &host) { + assert(host.dims == 4); + assert(int(scale) < host.size[0]); + assert(int(feature) < host.size[1]); + cv::Mat temp = cv::Mat(host.size[2], host.size[3], host.type(), host.getMat(cv::ACCESS_READ).ptr(scale, feature)); + return temp.getUMat(cv::ACCESS_RW); +} + /* * Function for getting cv::Mat header referencing height and width of the input matrix. * Presumes input matrix of 3 dimensions with format: {features, height, width} @@ -30,6 +38,13 @@ static cv::Mat plane(uint dim0, cv::Mat &host) { return cv::Mat(host.size[1], host.size[2], host.type(), host.ptr(dim0)); } +static cv::UMat plane(uint dim0, cv::UMat &host) { + assert(host.dims == 3); + assert(int(dim0) < host.size[0]); + cv::Mat temp = cv::Mat(host.size[1], host.size[2], host.type(), host.getMat(cv::ACCESS_READ).ptr(dim0)); + return temp.getUMat(cv::ACCESS_RW); +} + /* * Function for getting cv::Mat header referencing last three dimensions of the input matrix. * Usually used for getting specific scale of a matrix. @@ -40,6 +55,14 @@ static cv::Mat scale(uint scale, cv::Mat &host) { assert(int(scale) < host.size[0]); return cv::Mat(3, std::vector({host.size[1], host.size[2], host.size[3]}).data(), host.type(), host.ptr(scale)); } + +static cv::UMat scale(uint scale, cv::UMat &host) { + assert(host.dims == 4); + assert(int(scale) < host.size[0]); + cv::Mat temp = cv::Mat(3, std::vector({host.size[1], host.size[2], host.size[3]}).data(), + host.type(), host.getMat(cv::ACCESS_READ).ptr(scale)); + return temp.getUMat(cv::ACCESS_RW); +} /* * Sets channel number idxFrom of the source as channel number idxTo of target matrix. @@ -54,6 +77,15 @@ static void set_channel(int idxFrom, int idxTo, cv::Mat &source, cv::Mat &target int from_to[] = { idxFrom,idxTo }; cv::mixChannels( &source, 1, &target, 1, from_to, 1 ); } +static void set_channel(int idxFrom, int idxTo, cv::UMat &source, cv::UMat &target) +{ + assert(idxTo < target.channels()); + assert(idxFrom < source.channels()); + int from_to[] = { idxFrom,idxTo }; + cv::Mat convSrc = source.getMat(cv::ACCESS_RW); + cv::Mat convTgt = target.getMat(cv::ACCESS_RW); + cv::mixChannels( &convSrc, 1, &convTgt, 1, from_to, 1 ); +} /* * Computes sum of results from formula ((real)^2 + (imag)^2) @@ -75,6 +107,24 @@ static float sqr_norm(const cv::Mat &host) sum_sqr_norm = sum_sqr_norm / static_cast(host.rows * host.cols); return sum_sqr_norm; } +static float sqr_norm(const cv::UMat &host) +{ + assert(host.channels() % 2 == 0); + float sum_sqr_norm = 0; + cv::Mat tempHost = host.getMat(cv::ACCESS_READ); + + for (int row = 0; row < host.rows; ++row){ + for (int col = 0; col < host.cols; ++col){ + for (int ch = 0; ch < host.channels() / 2; ++ch){ + std::complex cpxVal = tempHost.ptr>(row) + [(host.channels() / 2)*col + ch]; + sum_sqr_norm += cpxVal.real() * cpxVal.real() + cpxVal.imag() * cpxVal.imag(); + } + } + } + sum_sqr_norm = sum_sqr_norm / static_cast(host.rows * host.cols); + return sum_sqr_norm; +} /* * Sum of channel values for each point of input matrix @@ -94,6 +144,24 @@ static cv::Mat sum_over_channels(cv::Mat &host) } return result; } +static cv::UMat sum_over_channels(cv::UMat &host) +{ + assert(host.channels() % 2 == 0); + cv::UMat result(host.rows, host.cols, CV_32FC2); + cv::Mat tempHost = host.getMat(cv::ACCESS_RW); + cv::Mat tempResult = result.getMat(cv::ACCESS_RW); + + for (int row = 0; row < host.rows; ++row) + for (int col = 0; col < host.cols; ++col){ + std::complex acc = 0; + for (int ch = 0; ch < host.channels() / 2; ++ch){ + acc += tempHost.ptr>(row)[(host.channels() / 2)*col + ch]; + } + tempResult.ptr>(row)[col] = acc; + } + return result; +} + /* * Extracts two channels from input, and sets them as data of resulting new matrix. @@ -108,12 +176,27 @@ static cv::Mat channel_to_cv_mat(int channel_id, cv::Mat &host){ return result; } +static cv::UMat channel_to_cv_mat(int channel_id, cv::UMat &host){ + cv::UMat result(host.rows, host.cols, CV_32FC2); + cv::Mat tempHost = host.getMat(cv::ACCESS_RW); + cv::Mat tempResult = result.getMat(cv::ACCESS_RW); + + int from_to[] = { channel_id, 0 }; + cv::mixChannels(&tempHost,1,&tempResult,1,from_to,1); + int from_to2[] = { (channel_id + 1), 1 }; + cv::mixChannels(&tempHost,1,&tempResult,1,from_to2,1); + return result; +} + /* * Returns complex matrix, where every element is result of formula (hostElem.real() )^2 + (hostElem.imag() )^2 **/ static cv::Mat sqr_mag(cv::Mat &host){ return mat_const_operator([](std::complex &c) { c = c.real() * c.real() + c.imag() * c.imag(); }, host); } +static cv::UMat sqr_mag(cv::UMat &host){ + return mat_const_operator([](std::complex &c) { c = c.real() * c.real() + c.imag() * c.imag(); }, host); +} /* * Returns copy of input complex matrix, where every imaginary value is inverted @@ -121,6 +204,9 @@ static cv::Mat sqr_mag(cv::Mat &host){ static cv::Mat conj(cv::Mat &host){ return mat_const_operator([](std::complex &c) { c = std::complex(c.real(), -c.imag()); }, host); } +static cv::UMat conj(cv::UMat &host){ + return mat_const_operator([](std::complex &c) { c = std::complex(c.real(), -c.imag()); }, host); +} /* * Returns result of element wise multiplication between n-channeled and single-channeled complex matrixes @@ -128,6 +214,9 @@ static cv::Mat conj(cv::Mat &host){ static cv::Mat mul_matn_mat1(cv::Mat &host, cv::Mat &other){ return matn_mat1_operator([](std::complex &c_lhs, const std::complex &c_rhs) { c_lhs *= c_rhs; }, host, other); } +static cv::UMat mul_matn_mat1(cv::UMat &host, cv::UMat &other){ + return matn_mat1_operator([](std::complex &c_lhs, const std::complex &c_rhs) { c_lhs *= c_rhs; }, host, other); +} /* * Returns result of element wise multiplication between two n-channeled complex matrixes @@ -135,6 +224,9 @@ static cv::Mat mul_matn_mat1(cv::Mat &host, cv::Mat &other){ static cv::Mat mul_matn_matn(cv::Mat &host, cv::Mat &other){ return mat_mat_operator([](std::complex &c_lhs, const std::complex &c_rhs) { c_lhs *= c_rhs; }, host, other); } +static cv::UMat mul_matn_matn(cv::UMat &host, cv::UMat &other){ + return mat_mat_operator([](std::complex &c_lhs, const std::complex &c_rhs) { c_lhs *= c_rhs; }, host, other); +} /* * Returns result of element wise addition to complex matrix @@ -142,6 +234,9 @@ static cv::Mat mul_matn_matn(cv::Mat &host, cv::Mat &other){ static cv::Mat add_scalar(cv::Mat &host, const float &val){ return mat_const_operator([&val](std::complex &c) { c += val; }, host); } +static cv::UMat add_scalar(cv::UMat &host, const float &val){ + return mat_const_operator([&val](std::complex &c) { c += val; }, host); +} /* * Returns result of element wise division between two n-channeled complex matrixes @@ -149,6 +244,9 @@ static cv::Mat add_scalar(cv::Mat &host, const float &val){ static cv::Mat divide_matn_matn(cv::Mat &host, cv::Mat &other){ return mat_mat_operator([](std::complex &c_lhs, const std::complex &c_rhs) { c_lhs /= c_rhs; }, host, other); } +static cv::UMat divide_matn_matn(cv::UMat &host, cv::UMat &other){ + return mat_mat_operator([](std::complex &c_lhs, const std::complex &c_rhs) { c_lhs /= c_rhs; }, host, other); +} /* * Helper function to iterate through an input complex matrix. @@ -168,6 +266,21 @@ static cv::Mat mat_const_operator(const std::function } return result; } +static cv::UMat mat_const_operator(const std::function &)> &op, cv::UMat &host){ + assert(host.channels() % 2 == 0); + cv::UMat result = host.clone(); + cv::Mat tempResult = result.getMat(cv::ACCESS_RW); + for (int i = 0; i < tempResult.rows; ++i) { + for (int j = 0; j < tempResult.cols; ++j){ + for (int k = 0; k < tempResult.channels() / 2 ; ++k){ + std::complex cpxVal = tempResult.ptr>(i)[(tempResult.channels() / 2)*j + k]; + op(cpxVal); + tempResult.ptr>(i)[(tempResult.channels() / 2)*j + k] = cpxVal; + } + } + } + return result; +} /* * Helper function to iterate through n-channeled and single-channeled complex matrixes. @@ -193,6 +306,28 @@ static cv::Mat matn_mat1_operator(void (*op)(std::complex &, const std::c } return result; } +static cv::UMat matn_mat1_operator(void (*op)(std::complex &, const std::complex &), cv::UMat &host, cv::UMat &other){ + assert(host.channels() % 2 == 0); + assert(other.channels() == 2); + assert(other.cols == host.cols); + assert(other.rows == host.rows); + + cv::UMat result = host.clone(); + cv::Mat tempResult = result.getMat(cv::ACCESS_RW); + cv::Mat tempOther = other.getMat(cv::ACCESS_READ); + for (int i = 0; i < result.rows; ++i) { + for (int j = 0; j < result.cols; ++j){ + for (int k = 0; k < result.channels() / 2 ; ++k){ + std::complex cpxValOther = tempOther.ptr>(i)[j]; + std::complex cpxValHost = tempResult.ptr>(i)[(tempResult.channels() / 2)*j + k]; + op(cpxValHost, cpxValOther); + tempResult.ptr>(i)[(tempResult.channels() / 2)*j + k] = cpxValHost; + } + } + } + return result; +} + /* * Helper function to iterate through n-channeled and single-channeled complex matrixes. @@ -219,7 +354,27 @@ static cv::Mat mat_mat_operator(void (*op)(std::complex &, const std::com } return result; } - +static cv::UMat mat_mat_operator(void (*op)(std::complex &, const std::complex &), cv::UMat &host, cv::UMat &other){ + assert(host.channels() % 2 == 0); + assert(other.channels() == host.channels()); + assert(other.cols == host.cols); + assert(other.rows == host.rows); + + cv::UMat result = host.clone(); + cv::Mat tempResult = result.getMat(cv::ACCESS_RW); + cv::Mat tempOther = other.getMat(cv::ACCESS_READ); + for (int i = 0; i < result.rows; ++i) { + for (int j = 0; j < result.cols; ++j){ + for (int k = 0; k < result.channels() / 2 ; ++k){ + std::complex cpxValHost = tempResult.ptr>(i)[(tempResult.channels() / 2)*j + k]; + std::complex cpxValOther = tempOther.ptr>(i)[(tempOther.channels() / 2)*j + k]; + op(cpxValHost, cpxValOther); + tempResult.ptr>(i)[(tempResult.channels() / 2)*j + k] = cpxValHost; + } + } + } + return result; +} }; From f0e290c064f1b243ac15c1ee746e4508706274fb Mon Sep 17 00:00:00 2001 From: Your Name Date: Fri, 10 Apr 2020 20:06:05 +0200 Subject: [PATCH 088/121] =?UTF-8?q?Vytvo=C5=99eny=20fft=20asserty=20pro=20?= =?UTF-8?q?datov=C3=BD=20typ=20cv::UMat?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- src/fft.cpp | 26 ++++++++++++++++++++++++++ src/fft.h | 5 +++++ 2 files changed, 31 insertions(+) diff --git a/src/fft.cpp b/src/fft.cpp index 09eec58a..1f2e55a9 100644 --- a/src/fft.cpp +++ b/src/fft.cpp @@ -15,6 +15,12 @@ void Fft::init(unsigned width, unsigned height, unsigned num_of_feats, unsigned #endif } +void Fft::set_window(const cv::UMat &window) +{ + cv::Mat tempInput = window.getMat(cv::ACCESS_READ); + set_window(tempInput); +} + void Fft::set_window(const cv::Mat &window) { assert(window.dims == 2); @@ -23,6 +29,12 @@ void Fft::set_window(const cv::Mat &window) (void)window; } +void Fft::forward(const cv::UMat &real_input, cv::UMat &complex_result){ + cv::Mat tempInput = real_input.getMat(cv::ACCESS_READ); + cv::Mat tempResult = complex_result.getMat(cv::ACCESS_READ); + forward(tempInput, tempResult); +} + void Fft::forward(const cv::Mat &real_input, cv::Mat &complex_result) { TRACE(""); @@ -41,6 +53,13 @@ void Fft::forward(const cv::Mat &real_input, cv::Mat &complex_result) (void)complex_result; } +void Fft::forward_window(cv::UMat &patch_feats, cv::UMat &complex_result, cv::UMat &tmp){ + cv::Mat tempFeats = patch_feats.getMat(cv::ACCESS_READ); + cv::Mat tempResult = complex_result.getMat(cv::ACCESS_READ); + cv::Mat tempTmp = tmp.getMat(cv::ACCESS_READ); + forward_window(tempFeats, tempResult, tempTmp); +} + void Fft::forward_window(cv::Mat &patch_feats, cv::Mat &complex_result, cv::Mat &tmp) { assert(patch_feats.dims == 4); @@ -68,6 +87,13 @@ void Fft::forward_window(cv::Mat &patch_feats, cv::Mat &complex_result, cv::Mat (void)tmp; } +void Fft::inverse(cv::UMat &complex_input, cv::UMat &real_result){ + cv::Mat tempInput = complex_input.getMat(cv::ACCESS_READ); + cv::Mat tempResult = real_result.getMat(cv::ACCESS_READ); + inverse(tempInput, tempResult); +} + + void Fft::inverse(cv::Mat &complex_input, cv::Mat &real_result) { TRACE(""); diff --git a/src/fft.h b/src/fft.h index 2dcc2bc7..d3770f0a 100644 --- a/src/fft.h +++ b/src/fft.h @@ -22,6 +22,11 @@ class Fft void forward(const cv::Mat &real_input, cv::Mat &complex_result); void forward_window(cv::Mat &patch_feats, cv::Mat &complex_result, cv::Mat &tmp); void inverse(cv::Mat &complex_input, cv::Mat &real_result); + + void set_window(const cv::UMat &window); + void forward(const cv::UMat &real_input, cv::UMat &complex_result); + void forward_window(cv::UMat &patch_feats, cv::UMat &complex_result, cv::UMat &tmp); + void inverse(cv::UMat &complex_input, cv::UMat &real_result); static cv::Size freq_size(cv::Size space_size) { From dcf32db8c38a9c2c3ac06afd43e9b8b9903b4adf Mon Sep 17 00:00:00 2001 From: Your Name Date: Fri, 10 Apr 2020 20:44:15 +0200 Subject: [PATCH 089/121] =?UTF-8?q?Vytvo=C5=99eny=20v=C5=A1echny=20fft=20f?= =?UTF-8?q?unkce=20pro=20datov=C3=BD=20typ=20cv::UMat=20-=20vynech=C3=A1ny?= =?UTF-8?q?=20funkce=20pou=C5=BE=C3=ADvaj=C3=ADc=C3=AD=20cufft,=20kter?= =?UTF-8?q?=C3=A9=20podle=20vedouc=C3=ADho=20nen=C3=AD=20t=C5=99eba=20upra?= =?UTF-8?q?vovat?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- src/fft_fftw.cpp | 59 ++++++++++++++++++++++++++++++++++++++++++++++ src/fft_fftw.h | 6 +++++ src/fft_opencv.cpp | 40 +++++++++++++++++++++++++++++++ src/fft_opencv.h | 6 +++++ 4 files changed, 111 insertions(+) diff --git a/src/fft_fftw.cpp b/src/fft_fftw.cpp index fa1ad374..cf428ff6 100644 --- a/src/fft_fftw.cpp +++ b/src/fft_fftw.cpp @@ -78,6 +78,12 @@ void Fftw::set_window(const cv::Mat &window) m_window = window; } +void Fftw::set_window(const cv::UMat &window) +{ + Fft::set_window(window); + m_window_Test = window; +} + void Fftw::forward(const cv::Mat &real_input, cv::Mat &complex_result) { Fft::forward(real_input, complex_result); @@ -92,6 +98,20 @@ void Fftw::forward(const cv::Mat &real_input, cv::Mat &complex_result) #endif } +void Fftw::forward(const cv::UMat &real_input, cv::UMat &complex_result) +{ + Fft::forward(real_input, complex_result); + + if (real_input.dims == 2) + fftwf_execute_dft_r2c(plan_f, reinterpret_cast(real_input.getMat(cv::ACCESS_RW).data), + reinterpret_cast(complex_result.getMat(cv::ACCESS_RW).ptr>(0))); +#ifdef BIG_BATCH + else + fftwf_execute_dft_r2c(plan_f_all_scales, reinterpret_cast(real_input.getMat(cv::ACCESS_RW).data), + reinterpret_cast(complex_result.getMat(cv::ACCESS_RW).ptr>(0))); +#endif +} + void Fftw::forward_window(cv::Mat &feat, cv::Mat & complex_result, cv::Mat &temp) { Fft::forward_window(feat, complex_result, temp); @@ -115,6 +135,29 @@ void Fftw::forward_window(cv::Mat &feat, cv::Mat & complex_result, cv::Mat &temp #endif } +void Fftw::forward_window(cv::UMat &feat, cv::UMat & complex_result, cv::UMat &temp) +{ + Fft::forward_window(feat, complex_result, temp); + + for (uint i = 0; i < uint(feat.size[0]); ++i) { + for (uint j = 0; j < uint(feat.size[1]); ++j) { + cv::UMat feat_plane = MatUtil::plane(i,j,feat); + cv::UMat temp_plane = MatUtil::plane(i,j,temp); + temp_plane = feat_plane.mul(m_window); + } + } + + float *in = temp.getMat(cv::ACCESS_RW).ptr(); + fftwf_complex *out = reinterpret_cast(complex_result.getMat(cv::ACCESS_RW).ptr>(0)); + + if (feat.size[0] == 1) + fftwf_execute_dft_r2c(plan_fw, in, out); +#ifdef BIG_BATCH + else + fftwf_execute_dft_r2c(plan_fw_all_scales, in, out); +#endif +} + void Fftw::inverse(cv::Mat &complex_input, cv::Mat &real_result) { Fft::inverse(complex_input, real_result); @@ -131,6 +174,22 @@ void Fftw::inverse(cv::Mat &complex_input, cv::Mat &real_result) real_result *= 1.0 / (m_width * m_height); } +void Fftw::inverse(cv::UMat &complex_input, cv::UMat &real_result) +{ + Fft::inverse(complex_input, real_result); + + fftwf_complex *in = reinterpret_cast(complex_input.getMat(cv::ACCESS_RW).ptr>(0)); + float *out = real_result.getMat(cv::ACCESS_RW).ptr(); + + if (complex_input.channels() == 2) + fftwf_execute_dft_c2r(plan_i_1ch, in, out); +#ifdef BIG_BATCH + else + fftwf_execute_dft_c2r(plan_i_all_scales, in, out); +#endif + real_result *= 1.0 / (m_width * m_height); +} + Fftw::~Fftw() { if (plan_f) fftwf_destroy_plan(plan_f); diff --git a/src/fft_fftw.h b/src/fft_fftw.h index 2db51aaf..f9d01c57 100644 --- a/src/fft_fftw.h +++ b/src/fft_fftw.h @@ -18,6 +18,11 @@ class Fftw : public Fft void forward(const cv::Mat &real_input, cv::Mat &complex_result); void forward_window(cv::Mat &feat, cv::Mat & complex_result, cv::Mat &temp); void inverse(cv::Mat &complex_input, cv::Mat &real_result); + + void set_window(const cv::UMat &window); + void forward(const cv::UMat &real_input, cv::UMat &complex_result); + void forward_window(cv::UMat &feat, cv::UMat & complex_result, cv::UMat &temp); + void inverse(cv::UMat &complex_input, cv::UMat &real_result); ~Fftw(); protected: @@ -26,6 +31,7 @@ class Fftw : public Fft private: cv::Mat m_window; + cv::Mat m_window_Test; fftwf_plan plan_f = 0, plan_fw = 0, plan_i_1ch = 0; #ifdef BIG_BATCH fftwf_plan plan_f_all_scales = 0, plan_fw_all_scales = 0, plan_i_all_scales = 0; diff --git a/src/fft_opencv.cpp b/src/fft_opencv.cpp index 6a3ab1b4..b7d0e830 100644 --- a/src/fft_opencv.cpp +++ b/src/fft_opencv.cpp @@ -13,6 +13,11 @@ void FftOpencv::set_window(const cv::Mat &window) m_window = window; } +void FftOpencv::set_window(const cv::UMat &window) +{ + m_window_Test = window; +} + void FftOpencv::forward(const cv::Mat &real_input, cv::Mat &complex_result) { Fft::forward(real_input, complex_result); @@ -20,6 +25,13 @@ void FftOpencv::forward(const cv::Mat &real_input, cv::Mat &complex_result) cv::dft(real_input, complex_result, cv::DFT_COMPLEX_OUTPUT); } +void FftOpencv::forward(const cv::UMat &real_input, cv::UMat &complex_result) +{ + Fft::forward(real_input, complex_result); + + cv::dft(real_input, complex_result, cv::DFT_COMPLEX_OUTPUT); +} + // Real and imag parts of complex elements from previous format are represented by 2 neighbouring channels. void FftOpencv::forward_window(cv::Mat &feat, cv::Mat &complex_result, cv::Mat &temp) { @@ -37,6 +49,22 @@ void FftOpencv::forward_window(cv::Mat &feat, cv::Mat &complex_result, cv::Mat & } } +void FftOpencv::forward_window(cv::UMat &feat, cv::UMat &complex_result, cv::UMat &temp) +{ + Fft::forward_window(feat, complex_result, temp); + (void) temp; + for (uint i = 0; i < uint(feat.size[0]); ++i) { + for (uint j = 0; j < uint(feat.size[1]); ++j) { + cv::UMat complex_res; + cv::UMat channel = MatUtil::plane(i, j, feat); + cv::dft(channel.mul(m_window_Test), complex_res, cv::DFT_COMPLEX_OUTPUT); + + MatUtil::set_channel(int(0), int(2*j), complex_res, complex_result); + MatUtil::set_channel(int(1), int(2*j+1), complex_res, complex_result); + } + } +} + void FftOpencv::inverse(cv::Mat &complex_input, cv::Mat &real_result) { Fft::inverse(complex_input, real_result); @@ -49,4 +77,16 @@ void FftOpencv::inverse(cv::Mat &complex_input, cv::Mat &real_result) } } +void FftOpencv::inverse(cv::UMat &complex_input, cv::UMat &real_result) +{ + Fft::inverse(complex_input, real_result); + + assert(complex_input.channels() % 2 == 0); + for (uint i = 0; i < uint(complex_input.channels() / 2); ++i) { + cv::UMat inputChannel = MatUtil::channel_to_cv_mat(i*2, complex_input); // extract input channel matrix + cv::UMat target = MatUtil::plane(i, real_result); // select output plane + cv::dft(inputChannel, target, cv::DFT_INVERSE | cv::DFT_REAL_OUTPUT | cv::DFT_SCALE); + } +} + FftOpencv::~FftOpencv() {} diff --git a/src/fft_opencv.h b/src/fft_opencv.h index 7e50c10a..ad8ed984 100644 --- a/src/fft_opencv.h +++ b/src/fft_opencv.h @@ -12,9 +12,15 @@ class FftOpencv : public Fft void forward(const cv::Mat &real_input, cv::Mat &complex_result); void forward_window(cv::Mat &feat, cv::Mat &complex_result, cv::Mat &temp); void inverse(cv::Mat &complex_input, cv::Mat &real_result); + + void set_window(const cv::UMat &window); + void forward(const cv::UMat &real_input, cv::UMat &complex_result); + void forward_window(cv::UMat &feat, cv::UMat &complex_result, cv::UMat &temp); + void inverse(cv::UMat &complex_input, cv::UMat &real_result); ~FftOpencv(); private: cv::Mat m_window; + cv::UMat m_window_Test; }; #endif // FFTOPENCV_H From b3a00c06eb95f4fa3807774511d4164d0faf1e11 Mon Sep 17 00:00:00 2001 From: Your Name Date: Mon, 13 Apr 2020 14:28:18 +0200 Subject: [PATCH 090/121] =?UTF-8?q?Konverze=20na=20UMat=20v=C5=A1eho=20co?= =?UTF-8?q?=20se=20t=C3=BDk=C3=A1=20funkc=C3=AD=20KCF=5FTracker::init()=20?= =?UTF-8?q?a=20train()=20-=20zb=C3=BDv=C3=A1=20KCF=5FTracker::track()=20a?= =?UTF-8?q?=20ThreadCtx::track()?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- src/fft_opencv.cpp | 1 - src/kcf.cpp | 92 +++++++++++++++++++++++++++++++++++++++++++++- src/kcf.h | 4 ++ 3 files changed, 95 insertions(+), 2 deletions(-) diff --git a/src/fft_opencv.cpp b/src/fft_opencv.cpp index b7d0e830..8fb0fb54 100644 --- a/src/fft_opencv.cpp +++ b/src/fft_opencv.cpp @@ -58,7 +58,6 @@ void FftOpencv::forward_window(cv::UMat &feat, cv::UMat &complex_result, cv::UMa cv::UMat complex_res; cv::UMat channel = MatUtil::plane(i, j, feat); cv::dft(channel.mul(m_window_Test), complex_res, cv::DFT_COMPLEX_OUTPUT); - MatUtil::set_channel(int(0), int(2*j), complex_res, complex_result); MatUtil::set_channel(int(1), int(2*j+1), complex_res, complex_result); } diff --git a/src/kcf.cpp b/src/kcf.cpp index 84ad5112..1ae5e4aa 100644 --- a/src/kcf.cpp +++ b/src/kcf.cpp @@ -79,11 +79,23 @@ 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, p_current_angle).copyTo(MatUtil::scale(0, model->patch_feats)); + get_features(input_rgb, input_gray, nullptr, p_current_center.x, p_current_center.y, + p_windows_size.width, p_windows_size.height, + p_current_scale, p_current_angle).copyTo(MatUtil::scale(0, model->patch_feats_Test)); + DEBUG_PRINT(model->patch_feats); fft.forward_window(model->patch_feats, model->xf, model->temp); DEBUG_PRINTM(model->xf); model->model_xf = model->model_xf * (1. - interp_factor) + model->xf * interp_factor; DEBUG_PRINTM(model->model_xf); + + DEBUG_PRINT(model->patch_feats_Test); + fft.forward_window(model->patch_feats_Test, model->xf_Test, model->temp_Test); + DEBUG_PRINTM(model->xf_Test); + model->model_xf_Test.getMat(cv::ACCESS_RW) = (model->model_xf_Test.getMat(cv::ACCESS_RW) * (1. - interp_factor) + + model->xf_Test.getMat(cv::ACCESS_RW) * interp_factor); + DEBUG_PRINTM(model->model_xf_Test); + if (m_use_linearkernel) { cv::Mat xfconj = MatUtil::conj(model->xf); @@ -98,10 +110,22 @@ void KCF_Tracker::train(cv::Mat input_rgb, cv::Mat input_gray, double interp_fac model->model_alphaf_num = MatUtil::mul_matn_matn(model->yf, kf); cv::Mat addedMat = MatUtil::add_scalar(kf, p_lambda); model->model_alphaf_den = MatUtil::mul_matn_matn(kf, addedMat); + + cv::UMat kf_Test = cv::UMat(sz.height, sz.width, CV_32FC2); + (*gaussian_correlation)(kf_Test, model->model_xf_Test, model->model_xf_Test, p_kernel_sigma, true, *this); + DEBUG_PRINTM(kf_Test); + model->model_alphaf_num_Test = MatUtil::mul_matn_matn(model->yf_Test, kf_Test); + cv::UMat addedMat_Test = MatUtil::add_scalar(kf_Test, p_lambda); + model->model_alphaf_den_Test = MatUtil::mul_matn_matn(kf_Test, addedMat_Test); + } model->model_alphaf = MatUtil::divide_matn_matn(model->model_alphaf_num, model->model_alphaf_den); DEBUG_PRINTM(model->model_alphaf); + + model->model_alphaf_Test = MatUtil::divide_matn_matn(model->model_alphaf_num_Test, model->model_alphaf_den_Test); + DEBUG_PRINTM(model->model_alphaf_Test); // p_model_alphaf = p_yf / (kf + p_lambda); //equation for fast training + } static int round_pw2_down(int x) @@ -118,7 +142,10 @@ void KCF_Tracker::init(cv::Mat &img, const cv::Rect &bbox, int fit_size_x, int f __dbgTracer.debug = m_debug; TRACE(""); -// cv::UMat test = cv::UMat(2,2,CV_32FC4,float(1)); +// cv::Mat test2 = cv::Mat(2,2,CV_32FC4,float(1)); +// DEBUG_PRINTM(test2); +// cv::UMat test = test2.getUMat(cv::ACCESS_RW); +// DEBUG_PRINTM(test); // cv::UMat test = cv::UMat(3, std::vector({2, 2, 2}).data(), CV_32FC2, float(5)); // cv::UMat testPl = cv::UMat(test.size[1], test.size[2], test.type(), test.ptr(0)); @@ -141,6 +168,8 @@ void KCF_Tracker::init(cv::Mat &img, const cv::Rect &bbox, int fit_size_x, int f // test.getMat(cv::ACCESS_WRITE).ptr(1)[5] = float(14); // test.getMat(cv::ACCESS_WRITE).ptr(1)[6] = float(15); // test.getMat(cv::ACCESS_WRITE).ptr(1)[7] = float(16); + + // // cv::Mat matTest = cv::Mat(test.size[1], test.size[2], test.type(), test.getMat(cv::ACCESS_READ).ptr(1)); // cv::UMat testPl = matTest.getUMat(cv::ACCESS_RW); @@ -300,13 +329,18 @@ void KCF_Tracker::init(cv::Mat &img, const cv::Rect &bbox, int fit_size_x, int f fft.init(feature_size.width, feature_size.height, p_num_of_feats, p_num_scales * p_num_angles); fft.set_window(cosine_window_function(feature_size.width, feature_size.height)); + fft.set_window(cosine_window_function_umat(feature_size.width, feature_size.height)); // window weights, i.e. labels cv::Mat gsl(feature_size,CV_32F); gaussian_shaped_labels(p_output_sigma, feature_size.width, feature_size.height).copyTo(gsl); + cv::UMat gsl_Test = gsl.getUMat(cv::ACCESS_RW); + fft.forward(gsl, model->yf); + fft.forward(gsl_Test, model->yf_Test); DEBUG_PRINTM(model->yf); + DEBUG_PRINTM(model->yf_Test); // train initial model train(input_rgb, input_gray, 1.0); @@ -745,6 +779,20 @@ cv::Mat KCF_Tracker::cosine_window_function(int dim1, int dim2) return ret; } +cv::UMat KCF_Tracker::cosine_window_function_umat(int dim1, int dim2) +{ + cv::Mat m1(1, dim1, CV_32FC1), m2(dim2, 1, CV_32FC1); + double N_inv = 1. / (static_cast(dim1) - 1.); + for (int i = 0; i < dim1; ++i) + m1.at(i) = float(0.5 * (1. - std::cos(2. * CV_PI * static_cast(i) * N_inv))); + N_inv = 1. / (static_cast(dim2) - 1.); + for (int i = 0; i < dim2; ++i) + m2.at(i) = float(0.5 * (1. - std::cos(2. * CV_PI * static_cast(i) * N_inv))); + cv::Mat tempMat = m2 * m1; + cv::UMat ret = tempMat.getUMat(cv::ACCESS_RW); + return ret; +} + // Returns sub-window of image input centered at [cx, cy] coordinates), // with size [width, height]. If any pixels are outside of the image, // they will replicate the values at the borders. @@ -848,6 +896,48 @@ void KCF_Tracker::GaussianCorrelation::operator()(cv::Mat &result, cv::Mat &xf, kcf.fft.forward(MatUtil::plane(0,ifft_res), result); } +void KCF_Tracker::GaussianCorrelation::operator()(cv::UMat &result, cv::UMat &xf, cv::UMat &yf, + double sigma, bool auto_correlation, const KCF_Tracker &kcf) +{ + TRACE(""); + DEBUG_PRINTM(xf); + + xf_sqr_norm_Test = MatUtil::sqr_norm(xf); + DEBUG_PRINT(xf_sqr_norm_Test); + + if (auto_correlation) { + yf_sqr_norm_Test = xf_sqr_norm_Test; + } else { + DEBUG_PRINTM(yf); + yf_sqr_norm_Test = MatUtil::sqr_norm(yf); + } + DEBUG_PRINT(yf_sqr_norm_Test); + + cv::UMat conjMat = MatUtil::conj(yf); + xyf_Test = auto_correlation ? MatUtil::sqr_mag(xf) : MatUtil::mul_matn_matn(xf, conjMat); // xf.muln(yf.conj()); + DEBUG_PRINTM(xyf_Test); + + // ifft2 and sum over 3rd dimension, we dont care about individual channels + cv::UMat xyf_sum = MatUtil::sum_over_channels(xyf_Test); + DEBUG_PRINTM(xyf_sum); + kcf.fft.inverse(xyf_sum, ifft_res_Test); + DEBUG_PRINTM(ifft_res_Test); + + float numel_xf_inv = 1.f / (xf.cols * xf.rows * (xf.channels() / 2)); + cv::UMat plane = MatUtil::plane(0,ifft_res_Test); + DEBUG_PRINTM(plane); + cv::UMat tempPlane = plane.clone(); + cv::multiply(tempPlane, -2, tempPlane); + cv::add(tempPlane, xf_sqr_norm_Test + yf_sqr_norm_Test, tempPlane); + cv::multiply(tempPlane, numel_xf_inv, tempPlane); + cv::max(tempPlane, 0, tempPlane); + cv::multiply(tempPlane, (-1. / (sigma * sigma)) , tempPlane); + cv::exp(tempPlane, plane); + DEBUG_PRINTM(plane); + + kcf.fft.forward(MatUtil::plane(0,ifft_res_Test), result); +} + float get_response_circular(cv::Point2i &pt, cv::Mat &response) { int x = pt.x; diff --git a/src/kcf.h b/src/kcf.h index a1b9b2bb..62c959f4 100644 --- a/src/kcf.h +++ b/src/kcf.h @@ -186,6 +186,7 @@ class KCF_Tracker k_Test = cv::UMat(3, std::vector({(int) num_scales, size.height, size.width}).data(), CV_32F); } void operator()(cv::Mat &result, cv::Mat &xf, cv::Mat &yf, double sigma, bool auto_correlation, const KCF_Tracker &kcf); + void operator()(cv::UMat &result, cv::UMat &xf, cv::UMat &yf, double sigma, bool auto_correlation, const KCF_Tracker &kcf); private: float xf_sqr_norm; @@ -194,6 +195,8 @@ class KCF_Tracker cv::Mat ifft_res; cv::Mat k; + float xf_sqr_norm_Test; + float yf_sqr_norm_Test; cv::UMat xyf_Test; cv::UMat ifft_res_Test; cv::UMat k_Test; @@ -206,6 +209,7 @@ class KCF_Tracker 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); + cv::UMat cosine_window_function_umat(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); From 97ffc4832c656972f0f2fd51e807fdce59a79573 Mon Sep 17 00:00:00 2001 From: Your Name Date: Mon, 13 Apr 2020 17:43:07 +0200 Subject: [PATCH 091/121] =?UTF-8?q?Konverze=20typu=20dat=20na=C4=8Dten?= =?UTF-8?q?=C3=BDch=20ze=20streamu=20na=20UMat=20-=20V=C4=9Bt=C5=A1ina=20p?= =?UTF-8?q?odp=C5=AFrn=C3=BDch=20funkc=C3=AD,=20v=C4=8Detn=C4=9B=20init(),?= =?UTF-8?q?=20train()=20a=20track()=20tak=C3=A9=20konvertov=C3=A1na=20-=20?= =?UTF-8?q?N=C4=9Bkter=C3=A9=20ze=20z=C3=A1visl=C3=BDch=20podp=C5=AFrn?= =?UTF-8?q?=C3=BDch=20funkc=C3=AD=20nech=C3=A1ny=20jako=20Mat,=20kv=C5=AFl?= =?UTF-8?q?i=20nekompatibilit=C4=9B=20funkc=C3=AD=20OpenCV=20-=20K=C3=B3d?= =?UTF-8?q?=20do=20za=C4=8D=C3=A1tku=20funkce=20KCF=5FTracker::track()=20m?= =?UTF-8?q?=C3=A1=20v=20tuto=20chv=C3=ADli=20otestovan=C3=BD=20v=C3=BDstup?= =?UTF-8?q?=20jako=20shodn=C3=BD=20s=20p=C5=AFvodn=C3=AD=20implementac?= =?UTF-8?q?=C3=AD=20cv::Mat?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- main_vot.cpp | 7 +-- src/kcf.cpp | 138 +++++++++++++++++++++++++++++++++++++++++----- src/kcf.h | 10 +++- src/threadctx.hpp | 17 +++++- videoio.cpp | 7 +++ videoio.hpp | 4 +- vot.hpp | 14 +++++ 7 files changed, 173 insertions(+), 24 deletions(-) diff --git a/main_vot.cpp b/main_vot.cpp index b2e7e639..b7f6b08b 100644 --- a/main_vot.cpp +++ b/main_vot.cpp @@ -281,7 +281,7 @@ int main(int argc, char *argv[]) std::getline(groundtruth_stream, line); } - cv::Mat image; + cv::UMat image; io->getNextImage(image); //img = firts frame, initPos = initial position in the first frame @@ -289,7 +289,7 @@ int main(int argc, char *argv[]) init_rect = io->getInitRectangle(); // Try to get BBox from VOT or .txt files if (empty(init_rect) || set_box_interactively) { - init_rect = selectBBox(image, box_out, 1); + init_rect = selectBBox(image.getMat(cv::ACCESS_RW), box_out, 1); auto b = init_rect; printf("--box=%d,%d,%d,%d\n", b.x, b.y, b.width, b.height); if (visualize_delay < 0) @@ -305,7 +305,6 @@ int main(int argc, char *argv[]) tracker.init(image, init_rect, fit_size_x, fit_size_y); - BBox_c bb; cv::Rect bb_rect; double avg_time = 0., sum_accuracy = 0.; @@ -368,7 +367,7 @@ int main(int argc, char *argv[]) break; switch (key) { case 'i': - init_rect = selectBBox(image, box_out, io->getImageNum()); + init_rect = selectBBox(image.getMat(cv::ACCESS_RW), box_out, io->getImageNum()); tracker.init(image, init_rect, fit_size_x, fit_size_y); break; case 'o': diff --git a/src/kcf.cpp b/src/kcf.cpp index 1ae5e4aa..2d8084b2 100644 --- a/src/kcf.cpp +++ b/src/kcf.cpp @@ -70,18 +70,19 @@ KCF_Tracker::~KCF_Tracker() delete &fft; } -void KCF_Tracker::train(cv::Mat input_rgb, cv::Mat input_gray, double interp_factor) +void KCF_Tracker::train(cv::UMat input_rgb, cv::UMat input_gray, double interp_factor) { TRACE(""); // obtain a sub-window for training - get_features(input_rgb, input_gray, nullptr, p_current_center.x, p_current_center.y, + cv::Mat inputRgbTemp = input_rgb.getMat(cv::ACCESS_RW); + cv::Mat inputGrayTemp = input_gray.getMat(cv::ACCESS_RW); + get_features(inputRgbTemp, inputGrayTemp, nullptr, p_current_center.x, p_current_center.y, p_windows_size.width, p_windows_size.height, p_current_scale, p_current_angle).copyTo(MatUtil::scale(0, model->patch_feats)); - - get_features(input_rgb, input_gray, nullptr, p_current_center.x, p_current_center.y, + get_features(inputRgbTemp, inputGrayTemp, nullptr, p_current_center.x, p_current_center.y, p_windows_size.width, p_windows_size.height, - p_current_scale, p_current_angle).copyTo(MatUtil::scale(0, model->patch_feats_Test)); + p_current_scale, p_current_angle).getUMat(cv::ACCESS_RW).copyTo(MatUtil::scale(0, model->patch_feats_Test)); DEBUG_PRINT(model->patch_feats); fft.forward_window(model->patch_feats, model->xf, model->temp); @@ -137,7 +138,7 @@ static int round_pw2_down(int x) } -void KCF_Tracker::init(cv::Mat &img, const cv::Rect &bbox, int fit_size_x, int fit_size_y) +void KCF_Tracker::init(cv::UMat &img, const cv::Rect &bbox, int fit_size_x, int fit_size_y) { __dbgTracer.debug = m_debug; TRACE(""); @@ -245,7 +246,7 @@ void KCF_Tracker::init(cv::Mat &img, const cv::Rect &bbox, int fit_size_x, int f p_init_pose.cx = x1 + p_init_pose.w / 2.; p_init_pose.cy = y1 + p_init_pose.h / 2.; - cv::Mat input_gray, input_rgb = img.clone(); + cv::UMat input_gray, input_rgb = img.clone(); if (img.channels() == 3) { cv::cvtColor(img, input_gray, cv::COLOR_BGR2GRAY); input_gray.convertTo(input_gray, CV_32FC1); @@ -346,7 +347,7 @@ void KCF_Tracker::init(cv::Mat &img, const cv::Rect &bbox, int fit_size_x, int f train(input_rgb, input_gray, 1.0); } -void KCF_Tracker::setTrackerPose(BBox_c &bbox, cv::Mat &img, int fit_size_x, int fit_size_y) +void KCF_Tracker::setTrackerPose(BBox_c &bbox, cv::UMat &img, int fit_size_x, int fit_size_y) { init(img, bbox.get_rect(), fit_size_x, fit_size_y); } @@ -387,6 +388,13 @@ void KCF_Tracker::resizeImgs(cv::Mat &input_rgb, cv::Mat &input_gray) cv::resize(input_rgb, input_rgb, cv::Size(0, 0), p_downscale_factor, p_downscale_factor, cv::INTER_AREA); } } +void KCF_Tracker::resizeImgs(cv::UMat &input_rgb, cv::UMat &input_gray) +{ + if (p_resize_image) { + cv::resize(input_gray, input_gray, cv::Size(0, 0), p_downscale_factor, p_downscale_factor, cv::INTER_AREA); + cv::resize(input_rgb, input_rgb, cv::Size(0, 0), p_downscale_factor, p_downscale_factor, cv::INTER_AREA); + } +} static void drawCross(cv::Mat &img, cv::Point center, bool green) { @@ -494,12 +502,12 @@ double KCF_Tracker::findMaxReponse(uint &max_idx, cv::Point2d &new_location) con return max; } -void KCF_Tracker::track(cv::Mat &img) +void KCF_Tracker::track(cv::UMat &img) { __dbgTracer.debug = m_debug; TRACE(""); - cv::Mat input_gray, input_rgb = img.clone(); + cv::UMat input_gray, input_rgb = img.clone(); if (img.channels() == 3) { cv::cvtColor(img, input_gray, cv::COLOR_BGR2GRAY); input_gray.convertTo(input_gray, CV_32FC1); @@ -557,21 +565,37 @@ void KCF_Tracker::track(cv::Mat &img) train(input_rgb, input_gray, p_interp_factor); } -void ThreadCtx::track(const KCF_Tracker &kcf, cv::Mat &input_rgb, cv::Mat &input_gray) +void ThreadCtx::track(const KCF_Tracker &kcf, cv::UMat &input_rgb, cv::UMat &input_gray) { TRACE(""); - + + cv::Mat tempRgb = input_rgb.getMat(cv::ACCESS_RW); + cv::Mat tempGray = input_gray.getMat(cv::ACCESS_RW); + BIG_BATCH_OMP_PARALLEL_FOR for (uint i = 0; i < IF_BIG_BATCH(max.size(), 1); ++i) { - kcf.get_features(input_rgb, input_gray, &dbg_patch IF_BIG_BATCH([i],), + kcf.get_features(tempRgb, tempGray, &dbg_patch IF_BIG_BATCH([i],), kcf.p_current_center.x, kcf.p_current_center.y, kcf.p_windows_size.width, kcf.p_windows_size.height, kcf.p_current_scale * IF_BIG_BATCH(max.scale(i), scale), kcf.p_current_angle + IF_BIG_BATCH(max.angle(i), angle)) .copyTo(MatUtil::scale(i, patch_feats)); DEBUG_PRINT(MatUtil::scale(i, patch_feats)); + + kcf.get_features(tempRgb, tempGray, &dbg_patch IF_BIG_BATCH([i],), + kcf.p_current_center.x, kcf.p_current_center.y, + kcf.p_windows_size.width, kcf.p_windows_size.height, + kcf.p_current_scale * IF_BIG_BATCH(max.scale(i), scale), + kcf.p_current_angle + IF_BIG_BATCH(max.angle(i), angle)) + .getUMat(cv::ACCESS_RW) + .copyTo(MatUtil::scale(i, patch_feats_Test)); + DEBUG_PRINT(MatUtil::scale(i, patch_feats_Test)); } + + // ------------------------------------------------ + // LAST CHANGE MADE HERE, continue from here... + // ------------------------------------------------ kcf.fft.forward_window(patch_feats, zf, temp); DEBUG_PRINTM(zf); @@ -701,6 +725,30 @@ cv::Mat KCF_Tracker::gaussian_shaped_labels(double sigma, int dim1, int dim2) return rot_labels; } +cv::UMat KCF_Tracker::gaussian_shaped_labels_umat(double sigma, int dim1, int dim2) +{ + cv::UMat labels(dim2, dim1, CV_32FC1); + int range_y[2] = {-dim2 / 2, dim2 - dim2 / 2}; + int range_x[2] = {-dim1 / 2, dim1 - dim1 / 2}; + + double sigma_s = sigma * sigma; + + for (int y = range_y[0], j = 0; y < range_y[1]; ++y, ++j) { + float *row_ptr = labels.getMat(cv::ACCESS_RW).ptr(j); + double y_s = y * y; + for (int x = range_x[0], i = 0; x < range_x[1]; ++x, ++i) { + row_ptr[i] = std::exp(-0.5 * (y_s + x * x) / sigma_s); //-1/2*e^((y^2+x^2)/sigma^2) + } + } + + // rotate so that 1 is at top-left corner (see KCF paper for explanation) + cv::UMat rot_labels = circshift(labels, range_x[0], range_y[0]); + // sanity check, 1 at top left corner + assert(rot_labels.getMat(cv::ACCESS_READ).at(0, 0) >= 1.f - 1e-10f); + + return rot_labels; +} + cv::Mat KCF_Tracker::circshift(const cv::Mat &patch, int x_rot, int y_rot) const { cv::Mat rot_patch(patch.size(), patch.type()); @@ -765,6 +813,70 @@ cv::Mat KCF_Tracker::circshift(const cv::Mat &patch, int x_rot, int y_rot) const return rot_patch; } +cv::UMat KCF_Tracker::circshift(const cv::UMat &patch, int x_rot, int y_rot) const +{ + cv::UMat rot_patch(patch.size(), patch.type()); + cv::UMat tmp_x_rot(patch.size(), patch.type()); + + // circular rotate x-axis + if (x_rot < 0) { + // move part that does not rotate over the edge + cv::Range orig_range(-x_rot, patch.cols); + cv::Range rot_range(0, patch.cols - (-x_rot)); + patch(cv::Range::all(), orig_range).copyTo(tmp_x_rot(cv::Range::all(), rot_range)); + + // rotated part + orig_range = cv::Range(0, -x_rot); + rot_range = cv::Range(patch.cols - (-x_rot), patch.cols); + patch(cv::Range::all(), orig_range).copyTo(tmp_x_rot(cv::Range::all(), rot_range)); + } else if (x_rot > 0) { + // move part that does not rotate over the edge + cv::Range orig_range(0, patch.cols - x_rot); + cv::Range rot_range(x_rot, patch.cols); + patch(cv::Range::all(), orig_range).copyTo(tmp_x_rot(cv::Range::all(), rot_range)); + + // rotated part + orig_range = cv::Range(patch.cols - x_rot, patch.cols); + rot_range = cv::Range(0, x_rot); + patch(cv::Range::all(), orig_range).copyTo(tmp_x_rot(cv::Range::all(), rot_range)); + } else { // zero rotation + // move part that does not rotate over the edge + cv::Range orig_range(0, patch.cols); + cv::Range rot_range(0, patch.cols); + patch(cv::Range::all(), orig_range).copyTo(tmp_x_rot(cv::Range::all(), rot_range)); + } + + // circular rotate y-axis + if (y_rot < 0) { + // move part that does not rotate over the edge + cv::Range orig_range(-y_rot, patch.rows); + cv::Range rot_range(0, patch.rows - (-y_rot)); + tmp_x_rot(orig_range, cv::Range::all()).copyTo(rot_patch(rot_range, cv::Range::all())); + + // rotated part + orig_range = cv::Range(0, -y_rot); + rot_range = cv::Range(patch.rows - (-y_rot), patch.rows); + tmp_x_rot(orig_range, cv::Range::all()).copyTo(rot_patch(rot_range, cv::Range::all())); + } else if (y_rot > 0) { + // move part that does not rotate over the edge + cv::Range orig_range(0, patch.rows - y_rot); + cv::Range rot_range(y_rot, patch.rows); + tmp_x_rot(orig_range, cv::Range::all()).copyTo(rot_patch(rot_range, cv::Range::all())); + + // rotated part + orig_range = cv::Range(patch.rows - y_rot, patch.rows); + rot_range = cv::Range(0, y_rot); + tmp_x_rot(orig_range, cv::Range::all()).copyTo(rot_patch(rot_range, cv::Range::all())); + } else { // zero rotation + // move part that does not rotate over the edge + cv::Range orig_range(0, patch.rows); + cv::Range rot_range(0, patch.rows); + tmp_x_rot(orig_range, cv::Range::all()).copyTo(rot_patch(rot_range, cv::Range::all())); + } + + return rot_patch; +} + // hann window actually (Power-of-cosine windows) cv::Mat KCF_Tracker::cosine_window_function(int dim1, int dim2) { diff --git a/src/kcf.h b/src/kcf.h index 62c959f4..9f3ca4ab 100644 --- a/src/kcf.h +++ b/src/kcf.h @@ -78,12 +78,13 @@ class KCF_Tracker ~KCF_Tracker(); // Init/re-init methods - void init(cv::Mat & img, const cv::Rect & bbox, int fit_size_x = -1, int fit_size_y = -1); + void init(cv::UMat & img, const cv::Rect & bbox, int fit_size_x = -1, int fit_size_y = -1); + void setTrackerPose(BBox_c & bbox, cv::UMat & img, 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); + void track(cv::UMat & img); BBox_c getBBox(); double getFilterResponse() const; // Measure of tracking accuracy @@ -205,16 +206,19 @@ class KCF_Tracker //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, double angle) const; + cv::UMat gaussian_shaped_labels_umat(double sigma, int dim1, int dim2); 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) const; + cv::UMat circshift(const cv::UMat &patch, int x_rot, int y_rot) const; cv::Mat cosine_window_function(int dim1, int dim2); cv::UMat cosine_window_function_umat(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); + void resizeImgs(cv::UMat &input_rgb, cv::UMat &input_gray); + void train(cv::UMat input_rgb, cv::UMat input_gray, double interp_factor); double findMaxReponse(uint &max_idx, cv::Point2d &new_location) const; double sub_grid_angle(uint max_index); }; diff --git a/src/threadctx.hpp b/src/threadctx.hpp index d2122761..fac743d4 100644 --- a/src/threadctx.hpp +++ b/src/threadctx.hpp @@ -50,13 +50,20 @@ struct ThreadCtx { #else , scale(scale) , angle(angle) - {} + { + cv::Mat patch_feat{ 4, std::vector({ int(num_scales * num_angles), int(num_features), roi.height, roi.width}).data(), CV_32F}; + cv::Mat tmp{ 4, std::vector({ int(num_scales * num_angles), int(num_features), roi.height, roi.width}).data(), CV_32F}; + cv::Mat zf_Tmp = cv::Mat::zeros((int) freq_size.height, (int) freq_size.width, CV_32FC(num_features*2)); + patch_feats_Test = patch_feat.getUMat(cv::ACCESS_RW); + temp_Test = tmp.getUMat(cv::ACCESS_RW); + zf_Test = zf_Tmp.getUMat(cv::ACCESS_RW); + } #endif ThreadCtx(ThreadCtx &&) = default; - void track(const KCF_Tracker &kcf, cv::Mat &input_rgb, cv::Mat &input_gray); + void track(const KCF_Tracker &kcf, cv::UMat &input_rgb, cv::UMat &input_gray); private: cv::Size roi; uint num_features; @@ -66,10 +73,14 @@ struct ThreadCtx { cv::Mat patch_feats{ 4, std::vector({ int(num_scales * num_angles), int(num_features), roi.height, roi.width}).data(), CV_32F}; cv::Mat temp{ 4, std::vector({ int(num_scales * num_angles), int(num_features), roi.height, roi.width}).data(), CV_32F}; - cv::Mat zf = cv::Mat::zeros((int) freq_size.height, (int) freq_size.width, CV_32FC(num_features*2)); cv::Mat kzf = cv::Mat::zeros((int) freq_size.height, (int) freq_size.width, CV_32FC2); + cv::UMat patch_feats_Test; + cv::UMat temp_Test; + cv::UMat zf_Test; + cv::UMat kzf_Test = cv::UMat::zeros((int) freq_size.height, (int) freq_size.width, CV_32FC2); + KCF_Tracker::GaussianCorrelation gaussian_correlation{num_scales * num_angles, num_features, roi}; diff --git a/videoio.cpp b/videoio.cpp index 94f5d684..64c03970 100644 --- a/videoio.cpp +++ b/videoio.cpp @@ -69,6 +69,13 @@ int FileIO::getNextImage(cv::Mat &img) return img.empty() ? 0 : 1; } +int FileIO::getNextImage(cv::UMat &img) +{ + capture >> img; + num++; + return img.empty() ? 0 : 1; +} + int FileIO::getImageNum() const { return num; diff --git a/videoio.hpp b/videoio.hpp index dbddc4bb..496ced85 100644 --- a/videoio.hpp +++ b/videoio.hpp @@ -11,6 +11,7 @@ class VideoIO { virtual cv::Rect getInitRectangle() = 0; virtual void outputBoundingBox(const cv::Rect & bbox) = 0; virtual int getNextFileName(char * fName) = 0; + virtual int getNextImage(cv::UMat & img) = 0; virtual int getNextImage(cv::Mat & img) = 0; virtual int getImageNum() const = 0; }; @@ -22,7 +23,8 @@ class FileIO : public VideoIO { cv::Rect getInitRectangle() override; void outputBoundingBox(const cv::Rect & bbox) override; - int getNextFileName(char * fName) override; + int getNextFileName(char * fName) override; + int getNextImage(cv::UMat &img) override; int getNextImage(cv::Mat & img) override; int getImageNum() const override; diff --git a/vot.hpp b/vot.hpp index 131ca33f..8f246439 100644 --- a/vot.hpp +++ b/vot.hpp @@ -164,6 +164,20 @@ class VOT : public VideoIO return 1; } + + inline int getNextImage(cv::UMat & img) override + { + if (p_images_stream.eof() || !p_images_stream.is_open()) + return -1; + + std::string line; + std::getline (p_images_stream, line); + if (line.empty() && p_images_stream.eof()) return -1; + img = cv::imread(line, cv::IMREAD_COLOR).getUMat(cv::ACCESS_RW); + num++; + + return 1; + } int getImageNum() const override { From 623bc0eef8d38c84f525f147e22c8a211af0d016 Mon Sep 17 00:00:00 2001 From: Your Name Date: Mon, 13 Apr 2020 17:43:41 +0200 Subject: [PATCH 092/121] =?UTF-8?q?Konverze=20typu=20dat=20na=C4=8Dten?= =?UTF-8?q?=C3=BDch=20ze=20streamu=20na=20UMat=20-=20V=C4=9Bt=C5=A1ina=20p?= =?UTF-8?q?odp=C5=AFrn=C3=BDch=20funkc=C3=AD,=20v=C4=8Detn=C4=9B=20init(),?= =?UTF-8?q?=20train()=20a=20track()=20tak=C3=A9=20konvertov=C3=A1na=20-=20?= =?UTF-8?q?N=C4=9Bkter=C3=A9=20ze=20z=C3=A1visl=C3=BDch=20podp=C5=AFrn?= =?UTF-8?q?=C3=BDch=20funkc=C3=AD=20nech=C3=A1ny=20jako=20Mat,=20kv=C5=AFl?= =?UTF-8?q?i=20nekompatibilit=C4=9B=20funkc=C3=AD=20OpenCV=20-=20K=C3=B3d?= =?UTF-8?q?=20do=20za=C4=8D=C3=A1tku=20funkce=20KCF=5FTracker::track()=20m?= =?UTF-8?q?=C3=A1=20v=20tuto=20chv=C3=ADli=20otestovan=C3=BD=20v=C3=BDstup?= =?UTF-8?q?=20jako=20shodn=C3=BD=20s=20p=C5=AFvodn=C3=AD=20implementac?= =?UTF-8?q?=C3=AD=20cv::Mat?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- src/cn/cnfeat.hpp | 21 +++++++++++ src/piotr_fhog/fhog.hpp | 77 +++++++++++++++++++++++++++++++++++++++++ 2 files changed, 98 insertions(+) diff --git a/src/cn/cnfeat.hpp b/src/cn/cnfeat.hpp index 04709016..5b61f70f 100644 --- a/src/cn/cnfeat.hpp +++ b/src/cn/cnfeat.hpp @@ -30,6 +30,27 @@ class CNFeat } return cn_feat; } + + static std::vector extract(const cv::UMat & patch_rgb) + { + std::vector cn_feat(p_cn_channels); + for (int i = 0; i < p_cn_channels; ++i) { + cn_feat[i].create(patch_rgb.size(), CV_32FC1); + } + + float * ch_ptr[p_cn_channels]; + for (int y = 0; y < patch_rgb.rows; ++y) { + for (int i = 0; i < p_cn_channels; ++i) + ch_ptr[i] = cn_feat[i].getMat(cv::ACCESS_RW).ptr(y); + for (int x = 0; x < patch_rgb.cols; ++x) { + //images in opencv stored in BGR order + cv::Vec3b bgr_val = patch_rgb.getMat(cv::ACCESS_RW).at(y,x); + for (int i = 0; i < p_cn_channels; ++i) + ch_ptr[i][x] = p_id2feat[rgb2id(bgr_val[2], bgr_val[1], bgr_val[0])][i]; + } + } + return cn_feat; + } private: inline static int rgb2id(int r, int g, int b) diff --git a/src/piotr_fhog/fhog.hpp b/src/piotr_fhog/fhog.hpp index d3b9d161..f93d573d 100644 --- a/src/piotr_fhog/fhog.hpp +++ b/src/piotr_fhog/fhog.hpp @@ -95,6 +95,83 @@ class FHoG return res; } + + static std::vector extract(const cv::UMat & img, int use_hog = 2, int bin_size = 4, int n_orients = 9, int soft_bin = -1, float clip = 0.2) + { + // d image dimension -> gray image d = 1 + // h, w -> height, width of image + // full -> ?? + // I -> input image, M, O -> mag, orientation OUTPUT + int h = img.rows, w = img.cols, d = 1; + bool full = true; + if (h < 2 || w < 2) { + std::cerr << "I must be at least 2x2." << std::endl; + return std::vector(); + } + +// //image rows-by-rows +// float * I = new float[h*w]; +// for (int y = 0; y < h; ++y) { +// const float * row_ptr = img.ptr(y); +// for (int x = 0; x < w; ++x) { +// I[y*w + x] = row_ptr[x]; +// } +// } + + //image cols-by-cols + float * I = new float[h*w]; + for (int x = 0; x < w; ++x) { + for (int y = 0; y < h; ++y) { + I[x*h + y] = img.getMat(cv::ACCESS_RW).at(y, x)/255.f; + } + } + + float *M = new float[h*w], *O = new float[h*w]; + gradMag(I, M, O, h, w, d, full); + + int n_chns = (use_hog == 0) ? n_orients : (use_hog==1 ? n_orients*4 : n_orients*3+5); + int hb = h/bin_size, wb = w/bin_size; + + float *H = new float[hb*wb*n_chns]; + memset(H, 0, hb*wb*n_chns*sizeof(float)); + + if (use_hog == 0) { + full = false; //by default + gradHist( M, O, H, h, w, bin_size, n_orients, soft_bin, full ); + } else if (use_hog == 1) { + full = false; //by default + hog( M, O, H, h, w, bin_size, n_orients, soft_bin, full, clip ); + } else { + fhog( M, O, H, h, w, bin_size, n_orients, soft_bin, clip ); + } + + //convert, assuming row-by-row-by-channel storage + std::vector res; + int n_res_channels = (use_hog == 2) ? n_chns-1 : n_chns; //last channel all zeros for fhog + res.reserve(n_res_channels); + for (int i = 0; i < n_res_channels; ++i) { + //output rows-by-rows +// cv::UMat desc(hb, wb, CV_32F, (H+hb*wb*i)); + + //output cols-by-cols + cv::UMat desc(hb, wb, CV_32F); + for (int x = 0; x < wb; ++x) { + for (int y = 0; y < hb; ++y) { + desc.getMat(cv::ACCESS_RW).at(y,x) = H[i*hb*wb + x*hb + y]; + } + } + + res.push_back(desc.clone()); + } + + //clean + delete [] I; + delete [] M; + delete [] O; + delete [] H; + + return res; + } }; From ce50317b8e18e77597ce097e031dcde0b42f4687 Mon Sep 17 00:00:00 2001 From: Your Name Date: Tue, 14 Apr 2020 20:39:11 +0200 Subject: [PATCH 093/121] =?UTF-8?q?Dokon=C4=8Dena=20posledn=C3=AD=20=C4=8D?= =?UTF-8?q?=C3=A1st=20konverze=20na=20UMat=20-=20program=20by=20v=20tuto?= =?UTF-8?q?=20chv=C3=ADli=20m=C4=9Bl=20b=C3=BDt=20p=C5=99ipraven=C3=BD=20k?= =?UTF-8?q?=20p=C5=99epnut=C3=AD=20na=20testovac=C3=AD=20prom=C4=9Bnn?= =?UTF-8?q?=C3=A9=20-=20P=C5=99ed=20uzav=C5=99en=C3=ADm=20je=C5=A1t=C4=9B?= =?UTF-8?q?=20t=C5=99eba=20prov=C3=A9st=20test=20shody=20obsahu=20prom?= =?UTF-8?q?=C4=9Bnn=C3=BDch=20a=20funkce=20programu?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- src/kcf.cpp | 40 +++++++++++++++++++++++++++++++--------- src/threadctx.hpp | 3 +++ 2 files changed, 34 insertions(+), 9 deletions(-) diff --git a/src/kcf.cpp b/src/kcf.cpp index 2d8084b2..2f189eab 100644 --- a/src/kcf.cpp +++ b/src/kcf.cpp @@ -247,20 +247,24 @@ void KCF_Tracker::init(cv::UMat &img, const cv::Rect &bbox, int fit_size_x, int p_init_pose.cy = y1 + p_init_pose.h / 2.; cv::UMat input_gray, input_rgb = img.clone(); + if (img.channels() == 3) { cv::cvtColor(img, input_gray, cv::COLOR_BGR2GRAY); input_gray.convertTo(input_gray, CV_32FC1); } else img.convertTo(input_gray, CV_32FC1); - + + cv::Mat tempGray = input_gray.getMat(cv::ACCESS_RW); + cv::Mat tempRgb = input_rgb.getMat(cv::ACCESS_RW); // don't need too large image if (p_init_pose.w * p_init_pose.h > 100. * 100.) { std::cout << "resizing image by factor of " << 1 / p_downscale_factor << std::endl; p_resize_image = true; p_init_pose.scale(p_downscale_factor); - cv::resize(input_gray, input_gray, cv::Size(0, 0), p_downscale_factor, p_downscale_factor, cv::INTER_AREA); - cv::resize(input_rgb, input_rgb, cv::Size(0, 0), p_downscale_factor, p_downscale_factor, cv::INTER_AREA); + cv::resize(tempGray, tempGray, cv::Size(0, 0), p_downscale_factor, p_downscale_factor, cv::INTER_AREA); + cv::resize(tempRgb, tempRgb, cv::Size(0, 0), p_downscale_factor, p_downscale_factor, cv::INTER_AREA); } + // compute win size + fit to fhog cell size p_windows_size.width = round(p_init_pose.w * (1. + p_padding) / p_cell_size) * p_cell_size; @@ -390,9 +394,12 @@ void KCF_Tracker::resizeImgs(cv::Mat &input_rgb, cv::Mat &input_gray) } void KCF_Tracker::resizeImgs(cv::UMat &input_rgb, cv::UMat &input_gray) { + cv::Mat tempGray = input_gray.getMat(cv::ACCESS_RW); + cv::Mat tempRgb = input_rgb.getMat(cv::ACCESS_RW); + if (p_resize_image) { - cv::resize(input_gray, input_gray, cv::Size(0, 0), p_downscale_factor, p_downscale_factor, cv::INTER_AREA); - cv::resize(input_rgb, input_rgb, cv::Size(0, 0), p_downscale_factor, p_downscale_factor, cv::INTER_AREA); + cv::resize(tempGray, tempGray, cv::Size(0, 0), p_downscale_factor, p_downscale_factor, cv::INTER_AREA); + cv::resize(tempRgb, tempRgb, cv::Size(0, 0), p_downscale_factor, p_downscale_factor, cv::INTER_AREA); } } @@ -593,24 +600,31 @@ void ThreadCtx::track(const KCF_Tracker &kcf, cv::UMat &input_rgb, cv::UMat &inp DEBUG_PRINT(MatUtil::scale(i, patch_feats_Test)); } - // ------------------------------------------------ - // LAST CHANGE MADE HERE, continue from here... - // ------------------------------------------------ - kcf.fft.forward_window(patch_feats, zf, temp); DEBUG_PRINTM(zf); + kcf.fft.forward_window(patch_feats_Test, zf_Test, temp_Test); + DEBUG_PRINTM(zf_Test); + if (kcf.m_use_linearkernel) { // Unused feature } else { gaussian_correlation(kzf, zf, kcf.model->model_xf, kcf.p_kernel_sigma, false, kcf); DEBUG_PRINTM(kzf); kzf = MatUtil::mul_matn_mat1(kzf, kcf.model->model_alphaf); + + gaussian_correlation(kzf_Test, zf_Test, kcf.model->model_xf_Test, kcf.p_kernel_sigma, false, kcf); + DEBUG_PRINTM(kzf_Test); + kzf_Test = MatUtil::mul_matn_mat1(kzf_Test, kcf.model->model_alphaf_Test); } DEBUG_PRINTM(kzf); kcf.fft.inverse(kzf, response); DEBUG_PRINTM(response); + DEBUG_PRINTM(kzf_Test); + kcf.fft.inverse(kzf_Test, response_Test); + DEBUG_PRINTM(response_Test); + /* target location is at the maximum response. we must take into account the fact that, if the target doesn't move, the peak will appear at the top-left corner, not at the center (this is @@ -627,6 +641,14 @@ void ThreadCtx::track(const KCF_Tracker &kcf, cv::UMat &input_rgb, cv::UMat &inp max[i].loc = max_loc; } #else + + + // ------------------------------------------------ + // LAST CHANGE MADE HERE, continue from here... + // ------------------------------------------------ + + + // _Test EDIT HERE to change which data is used for determining best match of the tracking rectangle cv::minMaxLoc(MatUtil::plane(0, response), &min_val, &max_val, &min_loc, &max_loc); DEBUG_PRINT(max_loc); DEBUG_PRINT(max_val); diff --git a/src/threadctx.hpp b/src/threadctx.hpp index fac743d4..7376fe9d 100644 --- a/src/threadctx.hpp +++ b/src/threadctx.hpp @@ -54,9 +54,11 @@ struct ThreadCtx { cv::Mat patch_feat{ 4, std::vector({ int(num_scales * num_angles), int(num_features), roi.height, roi.width}).data(), CV_32F}; cv::Mat tmp{ 4, std::vector({ int(num_scales * num_angles), int(num_features), roi.height, roi.width}).data(), CV_32F}; cv::Mat zf_Tmp = cv::Mat::zeros((int) freq_size.height, (int) freq_size.width, CV_32FC(num_features*2)); + cv::Mat resp = cv::Mat::zeros(3, std::vector({int(num_scales * num_angles), (int) roi.height, (int) roi.width}).data(), CV_32F); patch_feats_Test = patch_feat.getUMat(cv::ACCESS_RW); temp_Test = tmp.getUMat(cv::ACCESS_RW); zf_Test = zf_Tmp.getUMat(cv::ACCESS_RW); + response_Test = resp.getUMat(cv::ACCESS_RW); } #endif @@ -90,6 +92,7 @@ struct ThreadCtx { #endif cv::Mat response = cv::Mat(3, std::vector({int(num_scales * num_angles), (int) roi.height, (int) roi.width}).data(), CV_32F); + cv::UMat response_Test; struct Max { cv::Point2i loc; From d401d6dfbdb93f521665db98fdf5ca401c551672 Mon Sep 17 00:00:00 2001 From: Your Name Date: Sat, 18 Apr 2020 13:13:18 +0200 Subject: [PATCH 094/121] =?UTF-8?q?Opraven=20m=C3=ADrn=C4=9B=20nep=C5=99es?= =?UTF-8?q?n=C3=BD=20v=C3=BDstup=20funkce=20GaussianCorrelation::operator(?= =?UTF-8?q?)?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- src/kcf.cpp | 24 ++++++++++++++++-------- 1 file changed, 16 insertions(+), 8 deletions(-) diff --git a/src/kcf.cpp b/src/kcf.cpp index 2f189eab..27dee3e5 100644 --- a/src/kcf.cpp +++ b/src/kcf.cpp @@ -1058,15 +1058,23 @@ void KCF_Tracker::GaussianCorrelation::operator()(cv::UMat &result, cv::UMat &xf DEBUG_PRINTM(ifft_res_Test); float numel_xf_inv = 1.f / (xf.cols * xf.rows * (xf.channels() / 2)); - cv::UMat plane = MatUtil::plane(0,ifft_res_Test); + + cv::Mat ifft_res_Temp = ifft_res_Test.getMat(cv::ACCESS_RW); + cv::Mat plane = MatUtil::plane(0,ifft_res_Temp); DEBUG_PRINTM(plane); - cv::UMat tempPlane = plane.clone(); - cv::multiply(tempPlane, -2, tempPlane); - cv::add(tempPlane, xf_sqr_norm_Test + yf_sqr_norm_Test, tempPlane); - cv::multiply(tempPlane, numel_xf_inv, tempPlane); - cv::max(tempPlane, 0, tempPlane); - cv::multiply(tempPlane, (-1. / (sigma * sigma)) , tempPlane); - cv::exp(tempPlane, plane); + + cv::exp(-1. / (sigma * sigma) * cv::max((xf_sqr_norm + yf_sqr_norm - 2 * MatUtil::plane(0,ifft_res_Temp)) + * numel_xf_inv, 0), plane); + +// This seems to produce slightly inaccurate results +// -------------------------------------------------- +// cv::UMat tempPlane = plane.clone(); +// cv::multiply(tempPlane, -2, tempPlane); +// cv::add(tempPlane, xf_sqr_norm_Test + yf_sqr_norm_Test, tempPlane); +// cv::multiply(tempPlane, numel_xf_inv, tempPlane); +// cv::max(tempPlane, 0, tempPlane); +// cv::multiply(tempPlane, (-1. / (sigma * sigma)) , tempPlane); +// cv::exp(tempPlane, plane); DEBUG_PRINTM(plane); kcf.fft.forward(MatUtil::plane(0,ifft_res_Test), result); From d93433d2b3ff46994a7308db88017b3b4736791e Mon Sep 17 00:00:00 2001 From: Your Name Date: Sat, 18 Apr 2020 13:33:08 +0200 Subject: [PATCH 095/121] =?UTF-8?q?P=C5=99epnuta=20prom=C4=9Bnn=C3=A1=20po?= =?UTF-8?q?dle=20kter=C3=A9=20je=20prov=C3=A1d=C4=9Bn=20tracking=20na=20te?= =?UTF-8?q?stovac=C3=AD=20verzi=20-=20Testovac=C3=AD=20a=20p=C5=AFvodn?= =?UTF-8?q?=C3=AD=20verze=20m=C3=A1=20otestovan=C3=BD=20shodn=C3=BD=20v?= =?UTF-8?q?=C3=BDstup=20i=20obsah=20prom=C4=9Bnn=C3=BDch?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- src/kcf.cpp | 12 +++--------- 1 file changed, 3 insertions(+), 9 deletions(-) diff --git a/src/kcf.cpp b/src/kcf.cpp index 27dee3e5..32ea8492 100644 --- a/src/kcf.cpp +++ b/src/kcf.cpp @@ -641,15 +641,9 @@ void ThreadCtx::track(const KCF_Tracker &kcf, cv::UMat &input_rgb, cv::UMat &inp max[i].loc = max_loc; } #else - - - // ------------------------------------------------ - // LAST CHANGE MADE HERE, continue from here... - // ------------------------------------------------ - - - // _Test EDIT HERE to change which data is used for determining best match of the tracking rectangle - cv::minMaxLoc(MatUtil::plane(0, response), &min_val, &max_val, &min_loc, &max_loc); + + // _Test EDIT HERE to change which data (response) is used for determining best match of the tracking rectangle + cv::minMaxLoc(MatUtil::plane(0, response_Test), &min_val, &max_val, &min_loc, &max_loc); DEBUG_PRINT(max_loc); DEBUG_PRINT(max_val); From 535079be62271f4dee95907c87f7e3b1f336a615 Mon Sep 17 00:00:00 2001 From: Your Name Date: Sat, 18 Apr 2020 14:50:52 +0200 Subject: [PATCH 096/121] =?UTF-8?q?KONE=C4=8CN=C3=81=20VERZE=20KONVERZE=20?= =?UTF-8?q?NA=20cv::UMat=20-=20P=C5=AFvodn=C3=AD=20prom=C4=9Bnn=C3=A9=20cv?= =?UTF-8?q?::Mat=20odstran=C4=9Bny=20a=20nahrazeny=20stejnojmenn=C3=BDmi?= =?UTF-8?q?=20cv::UMat=20-=20Testovac=C3=AD=20vol=C3=A1n=C3=AD=20pracuj?= =?UTF-8?q?=C3=ADc=C3=AD=20s=20cv::UMat=20nahrazuj=C3=AD=20p=C5=AFvodn?= =?UTF-8?q?=C3=AD=20vol=C3=A1n=C3=AD=20s=20cv::Mat=20-=20V=C5=A1echny=20v?= =?UTF-8?q?=C3=BDskyty=20postfixu=20"=5FTest"=20byly=20odstran=C4=9Bny=20z?= =?UTF-8?q?=20projektu=20-=20P=C5=99edb=C4=9B=C5=BEn=C3=A9=20testov=C3=A1n?= =?UTF-8?q?=C3=AD=20rychlosti=20zat=C3=ADm=20nevykazuje=20v=C3=BDrazn?= =?UTF-8?q?=C4=9Bj=C5=A1=C3=AD=20rozd=C3=ADl=20oproti=20origin=C3=A1lu?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- src/fft.cpp | 32 ++--------- src/fft.h | 5 -- src/fft_fftw.cpp | 61 +-------------------- src/fft_fftw.h | 10 +--- src/fft_opencv.cpp | 44 +-------------- src/fft_opencv.h | 8 +-- src/kcf.cpp | 130 ++++++++++----------------------------------- src/kcf.h | 57 ++++++-------------- src/threadctx.hpp | 24 ++++----- 9 files changed, 63 insertions(+), 308 deletions(-) diff --git a/src/fft.cpp b/src/fft.cpp index 1f2e55a9..f956059f 100644 --- a/src/fft.cpp +++ b/src/fft.cpp @@ -16,12 +16,6 @@ void Fft::init(unsigned width, unsigned height, unsigned num_of_feats, unsigned } void Fft::set_window(const cv::UMat &window) -{ - cv::Mat tempInput = window.getMat(cv::ACCESS_READ); - set_window(tempInput); -} - -void Fft::set_window(const cv::Mat &window) { assert(window.dims == 2); assert(window.size().width == int(m_width)); @@ -29,13 +23,7 @@ void Fft::set_window(const cv::Mat &window) (void)window; } -void Fft::forward(const cv::UMat &real_input, cv::UMat &complex_result){ - cv::Mat tempInput = real_input.getMat(cv::ACCESS_READ); - cv::Mat tempResult = complex_result.getMat(cv::ACCESS_READ); - forward(tempInput, tempResult); -} - -void Fft::forward(const cv::Mat &real_input, cv::Mat &complex_result) +void Fft::forward(const cv::UMat &real_input, cv::UMat &complex_result) { TRACE(""); DEBUG_PRINT(real_input); @@ -53,14 +41,7 @@ void Fft::forward(const cv::Mat &real_input, cv::Mat &complex_result) (void)complex_result; } -void Fft::forward_window(cv::UMat &patch_feats, cv::UMat &complex_result, cv::UMat &tmp){ - cv::Mat tempFeats = patch_feats.getMat(cv::ACCESS_READ); - cv::Mat tempResult = complex_result.getMat(cv::ACCESS_READ); - cv::Mat tempTmp = tmp.getMat(cv::ACCESS_READ); - forward_window(tempFeats, tempResult, tempTmp); -} - -void Fft::forward_window(cv::Mat &patch_feats, cv::Mat &complex_result, cv::Mat &tmp) +void Fft::forward_window(cv::UMat &patch_feats, cv::UMat &complex_result, cv::UMat &tmp) { assert(patch_feats.dims == 4); #ifdef BIG_BATCH @@ -87,14 +68,7 @@ void Fft::forward_window(cv::Mat &patch_feats, cv::Mat &complex_result, cv::Mat (void)tmp; } -void Fft::inverse(cv::UMat &complex_input, cv::UMat &real_result){ - cv::Mat tempInput = complex_input.getMat(cv::ACCESS_READ); - cv::Mat tempResult = real_result.getMat(cv::ACCESS_READ); - inverse(tempInput, tempResult); -} - - -void Fft::inverse(cv::Mat &complex_input, cv::Mat &real_result) +void Fft::inverse(cv::UMat &complex_input, cv::UMat &real_result) { TRACE(""); DEBUG_PRINT(complex_input); diff --git a/src/fft.h b/src/fft.h index d3770f0a..dfc158a0 100644 --- a/src/fft.h +++ b/src/fft.h @@ -18,11 +18,6 @@ class Fft { public: void init(unsigned width, unsigned height, unsigned num_of_feats, unsigned num_of_scales); - void set_window(const cv::Mat &window); - void forward(const cv::Mat &real_input, cv::Mat &complex_result); - void forward_window(cv::Mat &patch_feats, cv::Mat &complex_result, cv::Mat &tmp); - void inverse(cv::Mat &complex_input, cv::Mat &real_result); - void set_window(const cv::UMat &window); void forward(const cv::UMat &real_input, cv::UMat &complex_result); void forward_window(cv::UMat &patch_feats, cv::UMat &complex_result, cv::UMat &tmp); diff --git a/src/fft_fftw.cpp b/src/fft_fftw.cpp index cf428ff6..923b1a72 100644 --- a/src/fft_fftw.cpp +++ b/src/fft_fftw.cpp @@ -72,30 +72,10 @@ void Fftw::init(unsigned width, unsigned height, unsigned num_of_feats, unsigned #endif } -void Fftw::set_window(const cv::Mat &window) -{ - Fft::set_window(window); - m_window = window; -} - void Fftw::set_window(const cv::UMat &window) { Fft::set_window(window); - m_window_Test = window; -} - -void Fftw::forward(const cv::Mat &real_input, cv::Mat &complex_result) -{ - Fft::forward(real_input, complex_result); - - if (real_input.dims == 2) - fftwf_execute_dft_r2c(plan_f, reinterpret_cast(real_input.data), - reinterpret_cast(complex_result.ptr>(0))); -#ifdef BIG_BATCH - else - fftwf_execute_dft_r2c(plan_f_all_scales, reinterpret_cast(real_input.data), - reinterpret_cast(complex_result.ptr>(0))); -#endif + m_window = window; } void Fftw::forward(const cv::UMat &real_input, cv::UMat &complex_result) @@ -112,29 +92,6 @@ void Fftw::forward(const cv::UMat &real_input, cv::UMat &complex_result) #endif } -void Fftw::forward_window(cv::Mat &feat, cv::Mat & complex_result, cv::Mat &temp) -{ - Fft::forward_window(feat, complex_result, temp); - - for (uint i = 0; i < uint(feat.size[0]); ++i) { - for (uint j = 0; j < uint(feat.size[1]); ++j) { - cv::Mat feat_plane = MatUtil::plane(i,j,feat); - cv::Mat temp_plane = MatUtil::plane(i,j,temp); - temp_plane = feat_plane.mul(m_window); - } - } - - float *in = temp.ptr(); - fftwf_complex *out = reinterpret_cast(complex_result.ptr>(0)); - - if (feat.size[0] == 1) - fftwf_execute_dft_r2c(plan_fw, in, out); -#ifdef BIG_BATCH - else - fftwf_execute_dft_r2c(plan_fw_all_scales, in, out); -#endif -} - void Fftw::forward_window(cv::UMat &feat, cv::UMat & complex_result, cv::UMat &temp) { Fft::forward_window(feat, complex_result, temp); @@ -158,22 +115,6 @@ void Fftw::forward_window(cv::UMat &feat, cv::UMat & complex_result, cv::UMat &t #endif } -void Fftw::inverse(cv::Mat &complex_input, cv::Mat &real_result) -{ - Fft::inverse(complex_input, real_result); - - fftwf_complex *in = reinterpret_cast(complex_input.ptr>(0)); - float *out = real_result.ptr(); - - if (complex_input.channels() == 2) - fftwf_execute_dft_c2r(plan_i_1ch, in, out); -#ifdef BIG_BATCH - else - fftwf_execute_dft_c2r(plan_i_all_scales, in, out); -#endif - real_result *= 1.0 / (m_width * m_height); -} - void Fftw::inverse(cv::UMat &complex_input, cv::UMat &real_result) { Fft::inverse(complex_input, real_result); diff --git a/src/fft_fftw.h b/src/fft_fftw.h index f9d01c57..c8b8829a 100644 --- a/src/fft_fftw.h +++ b/src/fft_fftw.h @@ -13,12 +13,7 @@ class Fftw : public Fft { public: Fftw(); - void init(unsigned width, unsigned height, unsigned num_of_feats, unsigned num_of_scales); - void set_window(const cv::Mat &window); - void forward(const cv::Mat &real_input, cv::Mat &complex_result); - void forward_window(cv::Mat &feat, cv::Mat & complex_result, cv::Mat &temp); - void inverse(cv::Mat &complex_input, cv::Mat &real_result); - + void init(unsigned width, unsigned height, unsigned num_of_feats, unsigned num_of_scales); void set_window(const cv::UMat &window); void forward(const cv::UMat &real_input, cv::UMat &complex_result); void forward_window(cv::UMat &feat, cv::UMat & complex_result, cv::UMat &temp); @@ -30,8 +25,7 @@ class Fftw : public Fft fftwf_plan create_plan_inv(uint howmany) const; private: - cv::Mat m_window; - cv::Mat m_window_Test; + cv::UMat m_window; fftwf_plan plan_f = 0, plan_fw = 0, plan_i_1ch = 0; #ifdef BIG_BATCH fftwf_plan plan_f_all_scales = 0, plan_fw_all_scales = 0, plan_i_all_scales = 0; diff --git a/src/fft_opencv.cpp b/src/fft_opencv.cpp index 8fb0fb54..c0014333 100644 --- a/src/fft_opencv.cpp +++ b/src/fft_opencv.cpp @@ -8,21 +8,9 @@ void FftOpencv::init(unsigned width, unsigned height, unsigned num_of_feats, uns std::cout << "FFT: OpenCV" << std::endl; } -void FftOpencv::set_window(const cv::Mat &window) -{ - m_window = window; -} - void FftOpencv::set_window(const cv::UMat &window) { - m_window_Test = window; -} - -void FftOpencv::forward(const cv::Mat &real_input, cv::Mat &complex_result) -{ - Fft::forward(real_input, complex_result); - - cv::dft(real_input, complex_result, cv::DFT_COMPLEX_OUTPUT); + m_window = window; } void FftOpencv::forward(const cv::UMat &real_input, cv::UMat &complex_result) @@ -33,22 +21,6 @@ void FftOpencv::forward(const cv::UMat &real_input, cv::UMat &complex_result) } // Real and imag parts of complex elements from previous format are represented by 2 neighbouring channels. -void FftOpencv::forward_window(cv::Mat &feat, cv::Mat &complex_result, cv::Mat &temp) -{ - Fft::forward_window(feat, complex_result, temp); - (void) temp; - for (uint i = 0; i < uint(feat.size[0]); ++i) { - for (uint j = 0; j < uint(feat.size[1]); ++j) { - cv::Mat complex_res; - cv::Mat channel = MatUtil::plane(i, j, feat); - cv::dft(channel.mul(m_window), complex_res, cv::DFT_COMPLEX_OUTPUT); - - MatUtil::set_channel(int(0), int(2*j), complex_res, complex_result); - MatUtil::set_channel(int(1), int(2*j+1), complex_res, complex_result); - } - } -} - void FftOpencv::forward_window(cv::UMat &feat, cv::UMat &complex_result, cv::UMat &temp) { Fft::forward_window(feat, complex_result, temp); @@ -57,25 +29,13 @@ void FftOpencv::forward_window(cv::UMat &feat, cv::UMat &complex_result, cv::UMa for (uint j = 0; j < uint(feat.size[1]); ++j) { cv::UMat complex_res; cv::UMat channel = MatUtil::plane(i, j, feat); - cv::dft(channel.mul(m_window_Test), complex_res, cv::DFT_COMPLEX_OUTPUT); + cv::dft(channel.mul(m_window), complex_res, cv::DFT_COMPLEX_OUTPUT); MatUtil::set_channel(int(0), int(2*j), complex_res, complex_result); MatUtil::set_channel(int(1), int(2*j+1), complex_res, complex_result); } } } -void FftOpencv::inverse(cv::Mat &complex_input, cv::Mat &real_result) -{ - Fft::inverse(complex_input, real_result); - - assert(complex_input.channels() % 2 == 0); - for (uint i = 0; i < uint(complex_input.channels() / 2); ++i) { - cv::Mat inputChannel = MatUtil::channel_to_cv_mat(i*2, complex_input); // extract input channel matrix - cv::Mat target = MatUtil::plane(i, real_result); // select output plane - cv::dft(inputChannel, target, cv::DFT_INVERSE | cv::DFT_REAL_OUTPUT | cv::DFT_SCALE); - } -} - void FftOpencv::inverse(cv::UMat &complex_input, cv::UMat &real_result) { Fft::inverse(complex_input, real_result); diff --git a/src/fft_opencv.h b/src/fft_opencv.h index ad8ed984..b9f87e04 100644 --- a/src/fft_opencv.h +++ b/src/fft_opencv.h @@ -8,19 +8,13 @@ class FftOpencv : public Fft { public: void init(unsigned width, unsigned height, unsigned num_of_feats, unsigned num_of_scales); - void set_window(const cv::Mat &window); - void forward(const cv::Mat &real_input, cv::Mat &complex_result); - void forward_window(cv::Mat &feat, cv::Mat &complex_result, cv::Mat &temp); - void inverse(cv::Mat &complex_input, cv::Mat &real_result); - void set_window(const cv::UMat &window); void forward(const cv::UMat &real_input, cv::UMat &complex_result); void forward_window(cv::UMat &feat, cv::UMat &complex_result, cv::UMat &temp); void inverse(cv::UMat &complex_input, cv::UMat &real_result); ~FftOpencv(); private: - cv::Mat m_window; - cv::UMat m_window_Test; + cv::UMat m_window; }; #endif // FFTOPENCV_H diff --git a/src/kcf.cpp b/src/kcf.cpp index 32ea8492..0b063b9e 100644 --- a/src/kcf.cpp +++ b/src/kcf.cpp @@ -79,52 +79,35 @@ void KCF_Tracker::train(cv::UMat input_rgb, cv::UMat input_gray, double interp_f cv::Mat inputGrayTemp = input_gray.getMat(cv::ACCESS_RW); get_features(inputRgbTemp, inputGrayTemp, nullptr, p_current_center.x, p_current_center.y, p_windows_size.width, p_windows_size.height, - p_current_scale, p_current_angle).copyTo(MatUtil::scale(0, model->patch_feats)); - get_features(inputRgbTemp, inputGrayTemp, nullptr, p_current_center.x, p_current_center.y, - p_windows_size.width, p_windows_size.height, - p_current_scale, p_current_angle).getUMat(cv::ACCESS_RW).copyTo(MatUtil::scale(0, model->patch_feats_Test)); - - DEBUG_PRINT(model->patch_feats); + p_current_scale, p_current_angle).getUMat(cv::ACCESS_RW).copyTo(MatUtil::scale(0, model->patch_feats)); + + DEBUG_PRINT(model->patch_feats); fft.forward_window(model->patch_feats, model->xf, model->temp); DEBUG_PRINTM(model->xf); - model->model_xf = model->model_xf * (1. - interp_factor) + model->xf * interp_factor; + model->model_xf.getMat(cv::ACCESS_RW) = (model->model_xf.getMat(cv::ACCESS_RW) * (1. - interp_factor) + + model->xf.getMat(cv::ACCESS_RW) * interp_factor); DEBUG_PRINTM(model->model_xf); - - DEBUG_PRINT(model->patch_feats_Test); - fft.forward_window(model->patch_feats_Test, model->xf_Test, model->temp_Test); - DEBUG_PRINTM(model->xf_Test); - model->model_xf_Test.getMat(cv::ACCESS_RW) = (model->model_xf_Test.getMat(cv::ACCESS_RW) * (1. - interp_factor) + - model->xf_Test.getMat(cv::ACCESS_RW) * interp_factor); - DEBUG_PRINTM(model->model_xf_Test); if (m_use_linearkernel) { - cv::Mat xfconj = MatUtil::conj(model->xf); - model->model_alphaf_num = MatUtil::mul_matn_mat1(xfconj, model->yf); - model->model_alphaf_den = MatUtil::mul_matn_matn(model->xf, xfconj); + // Unused feature + +// cv::Mat xfconj = MatUtil::conj(model->xf); +// model->model_alphaf_num = MatUtil::mul_matn_mat1(xfconj, model->yf); +// model->model_alphaf_den = MatUtil::mul_matn_matn(model->xf, xfconj); } else { // Kernel Ridge Regression, calculate alphas (in Fourier domain) cv::Size sz(Fft::freq_size(feature_size)); - cv::Mat kf = cv::Mat(sz.height, sz.width, CV_32FC2); + cv::UMat kf = cv::UMat(sz.height, sz.width, CV_32FC2); (*gaussian_correlation)(kf, model->model_xf, model->model_xf, p_kernel_sigma, true, *this); - DEBUG_PRINTM(kf); + DEBUG_PRINTM(kf); model->model_alphaf_num = MatUtil::mul_matn_matn(model->yf, kf); - cv::Mat addedMat = MatUtil::add_scalar(kf, p_lambda); + cv::UMat addedMat = MatUtil::add_scalar(kf, p_lambda); model->model_alphaf_den = MatUtil::mul_matn_matn(kf, addedMat); - - cv::UMat kf_Test = cv::UMat(sz.height, sz.width, CV_32FC2); - (*gaussian_correlation)(kf_Test, model->model_xf_Test, model->model_xf_Test, p_kernel_sigma, true, *this); - DEBUG_PRINTM(kf_Test); - model->model_alphaf_num_Test = MatUtil::mul_matn_matn(model->yf_Test, kf_Test); - cv::UMat addedMat_Test = MatUtil::add_scalar(kf_Test, p_lambda); - model->model_alphaf_den_Test = MatUtil::mul_matn_matn(kf_Test, addedMat_Test); } model->model_alphaf = MatUtil::divide_matn_matn(model->model_alphaf_num, model->model_alphaf_den); DEBUG_PRINTM(model->model_alphaf); - - model->model_alphaf_Test = MatUtil::divide_matn_matn(model->model_alphaf_num_Test, model->model_alphaf_den_Test); - DEBUG_PRINTM(model->model_alphaf_Test); // p_model_alphaf = p_yf / (kf + p_lambda); //equation for fast training } @@ -333,19 +316,17 @@ void KCF_Tracker::init(cv::UMat &img, const cv::Rect &bbox, int fit_size_x, int * p_output_sigma_factor / p_cell_size; fft.init(feature_size.width, feature_size.height, p_num_of_feats, p_num_scales * p_num_angles); - fft.set_window(cosine_window_function(feature_size.width, feature_size.height)); fft.set_window(cosine_window_function_umat(feature_size.width, feature_size.height)); // window weights, i.e. labels cv::Mat gsl(feature_size,CV_32F); gaussian_shaped_labels(p_output_sigma, feature_size.width, feature_size.height).copyTo(gsl); - cv::UMat gsl_Test = gsl.getUMat(cv::ACCESS_RW); + cv::UMat gslUmat = gsl.getUMat(cv::ACCESS_RW); +//gaussian_shaped_labels_umat(p_output_sigma, feature_size.width, feature_size.height).copyTo(gsl); - fft.forward(gsl, model->yf); - fft.forward(gsl_Test, model->yf_Test); + fft.forward(gslUmat, model->yf); DEBUG_PRINTM(model->yf); - DEBUG_PRINTM(model->yf_Test); // train initial model train(input_rgb, input_gray, 1.0); @@ -442,8 +423,8 @@ double KCF_Tracker::findMaxReponse(uint &max_idx, cv::Point2d &new_location) con // cv::Mat max_response_map = IF_BIG_BATCH(d->threadctxs[0].response.plane(max_idx), // max_it->response.plane(0)); - cv::Mat tempResponse = IF_BIG_BATCH(cv::Mat(), max_it->response); - cv::Mat max_response_map = IF_BIG_BATCH(MatUtil::plane(max_idx, d->threadctxs[0].response), + cv::Mat tempResponse = IF_BIG_BATCH(cv::Mat(), max_it->response.getMat(cv::ACCESS_RW)); + cv::Mat max_response_map = IF_BIG_BATCH(MatUtil::plane(max_idx, d->threadctxs[0].response.getMat(cv::ACCESS_RW)), MatUtil::plane(0, tempResponse)); @@ -587,44 +568,25 @@ void ThreadCtx::track(const KCF_Tracker &kcf, cv::UMat &input_rgb, cv::UMat &inp kcf.p_windows_size.width, kcf.p_windows_size.height, kcf.p_current_scale * IF_BIG_BATCH(max.scale(i), scale), kcf.p_current_angle + IF_BIG_BATCH(max.angle(i), angle)) + .getUMat(cv::ACCESS_RW) .copyTo(MatUtil::scale(i, patch_feats)); DEBUG_PRINT(MatUtil::scale(i, patch_feats)); - - kcf.get_features(tempRgb, tempGray, &dbg_patch IF_BIG_BATCH([i],), - kcf.p_current_center.x, kcf.p_current_center.y, - kcf.p_windows_size.width, kcf.p_windows_size.height, - kcf.p_current_scale * IF_BIG_BATCH(max.scale(i), scale), - kcf.p_current_angle + IF_BIG_BATCH(max.angle(i), angle)) - .getUMat(cv::ACCESS_RW) - .copyTo(MatUtil::scale(i, patch_feats_Test)); - DEBUG_PRINT(MatUtil::scale(i, patch_feats_Test)); } kcf.fft.forward_window(patch_feats, zf, temp); DEBUG_PRINTM(zf); - kcf.fft.forward_window(patch_feats_Test, zf_Test, temp_Test); - DEBUG_PRINTM(zf_Test); - if (kcf.m_use_linearkernel) { // Unused feature } else { gaussian_correlation(kzf, zf, kcf.model->model_xf, kcf.p_kernel_sigma, false, kcf); DEBUG_PRINTM(kzf); kzf = MatUtil::mul_matn_mat1(kzf, kcf.model->model_alphaf); - - gaussian_correlation(kzf_Test, zf_Test, kcf.model->model_xf_Test, kcf.p_kernel_sigma, false, kcf); - DEBUG_PRINTM(kzf_Test); - kzf_Test = MatUtil::mul_matn_mat1(kzf_Test, kcf.model->model_alphaf_Test); } DEBUG_PRINTM(kzf); kcf.fft.inverse(kzf, response); DEBUG_PRINTM(response); - DEBUG_PRINTM(kzf_Test); - kcf.fft.inverse(kzf_Test, response_Test); - DEBUG_PRINTM(response_Test); - /* target location is at the maximum response. we must take into account the fact that, if the target doesn't move, the peak will appear at the top-left corner, not at the center (this is @@ -642,8 +604,8 @@ void ThreadCtx::track(const KCF_Tracker &kcf, cv::UMat &input_rgb, cv::UMat &inp } #else - // _Test EDIT HERE to change which data (response) is used for determining best match of the tracking rectangle - cv::minMaxLoc(MatUtil::plane(0, response_Test), &min_val, &max_val, &min_loc, &max_loc); + // EDIT HERE to change which data (response) is used for determining best match of the tracking rectangle + cv::minMaxLoc(MatUtil::plane(0, response), &min_val, &max_val, &min_loc, &max_loc); DEBUG_PRINT(max_loc); DEBUG_PRINT(max_val); @@ -988,11 +950,12 @@ cv::Mat KCF_Tracker::get_subwindow(const cv::Mat &input, int cx, int cy, int wid return patch; } -void KCF_Tracker::GaussianCorrelation::operator()(cv::Mat &result, cv::Mat &xf, cv::Mat &yf, +void KCF_Tracker::GaussianCorrelation::operator()(cv::UMat &result, cv::UMat &xf, cv::UMat &yf, double sigma, bool auto_correlation, const KCF_Tracker &kcf) { TRACE(""); DEBUG_PRINTM(xf); + xf_sqr_norm = MatUtil::sqr_norm(xf); DEBUG_PRINT(xf_sqr_norm); @@ -1004,56 +967,19 @@ void KCF_Tracker::GaussianCorrelation::operator()(cv::Mat &result, cv::Mat &xf, } DEBUG_PRINT(yf_sqr_norm); - cv::Mat conjMat = MatUtil::conj(yf); + cv::UMat conjMat = MatUtil::conj(yf); xyf = auto_correlation ? MatUtil::sqr_mag(xf) : MatUtil::mul_matn_matn(xf, conjMat); // xf.muln(yf.conj()); DEBUG_PRINTM(xyf); // ifft2 and sum over 3rd dimension, we dont care about individual channels - cv::Mat xyf_sum = MatUtil::sum_over_channels(xyf); + cv::UMat xyf_sum = MatUtil::sum_over_channels(xyf); DEBUG_PRINTM(xyf_sum); kcf.fft.inverse(xyf_sum, ifft_res); DEBUG_PRINTM(ifft_res); - float numel_xf_inv = 1.f / (xf.cols * xf.rows * (xf.channels() / 2)); - cv::Mat plane = MatUtil::plane(0,ifft_res); - DEBUG_PRINTM(plane); - cv::exp(-1. / (sigma * sigma) * cv::max((xf_sqr_norm + yf_sqr_norm - 2 * MatUtil::plane(0,ifft_res)) - * numel_xf_inv, 0), plane); - DEBUG_PRINTM(plane); - - kcf.fft.forward(MatUtil::plane(0,ifft_res), result); -} - -void KCF_Tracker::GaussianCorrelation::operator()(cv::UMat &result, cv::UMat &xf, cv::UMat &yf, - double sigma, bool auto_correlation, const KCF_Tracker &kcf) -{ - TRACE(""); - DEBUG_PRINTM(xf); - - xf_sqr_norm_Test = MatUtil::sqr_norm(xf); - DEBUG_PRINT(xf_sqr_norm_Test); - - if (auto_correlation) { - yf_sqr_norm_Test = xf_sqr_norm_Test; - } else { - DEBUG_PRINTM(yf); - yf_sqr_norm_Test = MatUtil::sqr_norm(yf); - } - DEBUG_PRINT(yf_sqr_norm_Test); - - cv::UMat conjMat = MatUtil::conj(yf); - xyf_Test = auto_correlation ? MatUtil::sqr_mag(xf) : MatUtil::mul_matn_matn(xf, conjMat); // xf.muln(yf.conj()); - DEBUG_PRINTM(xyf_Test); - - // ifft2 and sum over 3rd dimension, we dont care about individual channels - cv::UMat xyf_sum = MatUtil::sum_over_channels(xyf_Test); - DEBUG_PRINTM(xyf_sum); - kcf.fft.inverse(xyf_sum, ifft_res_Test); - DEBUG_PRINTM(ifft_res_Test); - float numel_xf_inv = 1.f / (xf.cols * xf.rows * (xf.channels() / 2)); - cv::Mat ifft_res_Temp = ifft_res_Test.getMat(cv::ACCESS_RW); + cv::Mat ifft_res_Temp = ifft_res.getMat(cv::ACCESS_RW); cv::Mat plane = MatUtil::plane(0,ifft_res_Temp); DEBUG_PRINTM(plane); @@ -1064,14 +990,14 @@ void KCF_Tracker::GaussianCorrelation::operator()(cv::UMat &result, cv::UMat &xf // -------------------------------------------------- // cv::UMat tempPlane = plane.clone(); // cv::multiply(tempPlane, -2, tempPlane); -// cv::add(tempPlane, xf_sqr_norm_Test + yf_sqr_norm_Test, tempPlane); +// cv::add(tempPlane, xf_sqr_norm + yf_sqr_norm, tempPlane); // cv::multiply(tempPlane, numel_xf_inv, tempPlane); // cv::max(tempPlane, 0, tempPlane); // cv::multiply(tempPlane, (-1. / (sigma * sigma)) , tempPlane); // cv::exp(tempPlane, plane); DEBUG_PRINTM(plane); - kcf.fft.forward(MatUtil::plane(0,ifft_res_Test), result); + kcf.fft.forward(MatUtil::plane(0,ifft_res), result); } float get_response_circular(cv::Point2i &pt, cv::Mat &response) diff --git a/src/kcf.h b/src/kcf.h index 9f3ca4ab..7d1c99b0 100644 --- a/src/kcf.h +++ b/src/kcf.h @@ -80,7 +80,6 @@ class KCF_Tracker // Init/re-init methods void init(cv::UMat & img, const cv::Rect & bbox, int fit_size_x = -1, int fit_size_y = -1); void setTrackerPose(BBox_c & bbox, cv::UMat & img, 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 @@ -136,26 +135,15 @@ class KCF_Tracker public: // Complex matrix now equals 2*k channels matrix by design - cv::Mat yf = cv::Mat::zeros((int) height, (int) width, CV_32FC2); - cv::Mat model_alphaf = cv::Mat::zeros((int) height, (int) width, CV_32FC2); - cv::Mat model_alphaf_num = cv::Mat::zeros((int) height, (int) width, CV_32FC2); - cv::Mat model_alphaf_den = cv::Mat::zeros((int) height, (int) width, CV_32FC2); - cv::Mat model_xf = cv::Mat::zeros((int) height, (int) width, CV_32FC(n_feats*2)); - cv::Mat xf = cv::Mat::zeros((int) height, (int) width, CV_32FC(n_feats*2)); - - cv::Mat patch_feats{ 4, std::vector({1, int(n_feats), feature_size.height, feature_size.width}).data(), CV_32F}; - cv::Mat temp{ 4, std::vector({1, int(n_feats), feature_size.height, feature_size.width}).data(), CV_32F}; - - - cv::UMat yf_Test = cv::UMat::zeros((int) height, (int) width, CV_32FC2); - cv::UMat model_alphaf_Test = cv::UMat::zeros((int) height, (int) width, CV_32FC2); - cv::UMat model_alphaf_num_Test = cv::UMat::zeros((int) height, (int) width, CV_32FC2); - cv::UMat model_alphaf_den_Test = cv::UMat::zeros((int) height, (int) width, CV_32FC2); - cv::UMat model_xf_Test; - cv::UMat xf_Test; - - cv::UMat patch_feats_Test{ 4, std::vector({1, int(n_feats), feature_size.height, feature_size.width}).data(), CV_32F}; - cv::UMat temp_Test{ 4, std::vector({1, int(n_feats), feature_size.height, feature_size.width}).data(), CV_32F}; + cv::UMat yf = cv::UMat::zeros((int) height, (int) width, CV_32FC2); + cv::UMat model_alphaf = cv::UMat::zeros((int) height, (int) width, CV_32FC2); + cv::UMat model_alphaf_num = cv::UMat::zeros((int) height, (int) width, CV_32FC2); + cv::UMat model_alphaf_den = cv::UMat::zeros((int) height, (int) width, CV_32FC2); + cv::UMat model_xf; + cv::UMat xf; + + cv::UMat patch_feats{ 4, std::vector({1, int(n_feats), feature_size.height, feature_size.width}).data(), CV_32F}; + cv::UMat temp{ 4, std::vector({1, int(n_feats), feature_size.height, feature_size.width}).data(), CV_32F}; Model(cv::Size feature_size, uint _n_feats) @@ -166,8 +154,8 @@ class KCF_Tracker cv::Mat model_xf_temp = cv::Mat::zeros((int) height, (int) width, CV_32FC(n_feats*2)); cv::Mat xf_temp = cv::Mat::zeros((int) height, (int) width, CV_32FC(n_feats*2)); - model_xf_Test = model_xf_temp.getUMat(cv::ACCESS_RW); - xf_Test = xf_temp.getUMat(cv::ACCESS_RW); + model_xf = model_xf_temp.getUMat(cv::ACCESS_RW); + xf = xf_temp.getUMat(cv::ACCESS_RW); } }; @@ -178,29 +166,18 @@ class KCF_Tracker GaussianCorrelation(uint num_scales, uint num_feats, cv::Size size) { cv::Size temp = Fft::freq_size(size); - xyf = cv::Mat(3, std::vector({(int) num_scales, temp.height, temp.width}).data(), CV_32FC(num_feats*2)); - ifft_res = cv::Mat(3, std::vector({(int) num_scales, size.height, size.width}).data(), CV_32F); - k = cv::Mat(3, std::vector({(int) num_scales, size.height, size.width}).data(), CV_32F); - - xyf_Test = cv::UMat(3, std::vector({(int) num_scales, temp.height, temp.width}).data(), CV_32FC(num_feats*2)); - ifft_res_Test = cv::UMat(3, std::vector({(int) num_scales, size.height, size.width}).data(), CV_32F); - k_Test = cv::UMat(3, std::vector({(int) num_scales, size.height, size.width}).data(), CV_32F); + xyf = cv::UMat(3, std::vector({(int) num_scales, temp.height, temp.width}).data(), CV_32FC(num_feats*2)); + ifft_res = cv::UMat(3, std::vector({(int) num_scales, size.height, size.width}).data(), CV_32F); + k = cv::UMat(3, std::vector({(int) num_scales, size.height, size.width}).data(), CV_32F); } - void operator()(cv::Mat &result, cv::Mat &xf, cv::Mat &yf, double sigma, bool auto_correlation, const KCF_Tracker &kcf); void operator()(cv::UMat &result, cv::UMat &xf, cv::UMat &yf, double sigma, bool auto_correlation, const KCF_Tracker &kcf); private: float xf_sqr_norm; float yf_sqr_norm; - cv::Mat xyf; - cv::Mat ifft_res; - cv::Mat k; - - float xf_sqr_norm_Test; - float yf_sqr_norm_Test; - cv::UMat xyf_Test; - cv::UMat ifft_res_Test; - cv::UMat k_Test; + cv::UMat xyf; + cv::UMat ifft_res; + cv::UMat k; }; //helping functions diff --git a/src/threadctx.hpp b/src/threadctx.hpp index 7376fe9d..abf499fa 100644 --- a/src/threadctx.hpp +++ b/src/threadctx.hpp @@ -55,10 +55,10 @@ struct ThreadCtx { cv::Mat tmp{ 4, std::vector({ int(num_scales * num_angles), int(num_features), roi.height, roi.width}).data(), CV_32F}; cv::Mat zf_Tmp = cv::Mat::zeros((int) freq_size.height, (int) freq_size.width, CV_32FC(num_features*2)); cv::Mat resp = cv::Mat::zeros(3, std::vector({int(num_scales * num_angles), (int) roi.height, (int) roi.width}).data(), CV_32F); - patch_feats_Test = patch_feat.getUMat(cv::ACCESS_RW); - temp_Test = tmp.getUMat(cv::ACCESS_RW); - zf_Test = zf_Tmp.getUMat(cv::ACCESS_RW); - response_Test = resp.getUMat(cv::ACCESS_RW); + patch_feats = patch_feat.getUMat(cv::ACCESS_RW); + temp = tmp.getUMat(cv::ACCESS_RW); + zf = zf_Tmp.getUMat(cv::ACCESS_RW); + response = resp.getUMat(cv::ACCESS_RW); } #endif @@ -73,15 +73,10 @@ struct ThreadCtx { uint num_angles; cv::Size freq_size = Fft::freq_size(roi); - cv::Mat patch_feats{ 4, std::vector({ int(num_scales * num_angles), int(num_features), roi.height, roi.width}).data(), CV_32F}; - cv::Mat temp{ 4, std::vector({ int(num_scales * num_angles), int(num_features), roi.height, roi.width}).data(), CV_32F}; - cv::Mat zf = cv::Mat::zeros((int) freq_size.height, (int) freq_size.width, CV_32FC(num_features*2)); - cv::Mat kzf = cv::Mat::zeros((int) freq_size.height, (int) freq_size.width, CV_32FC2); - - cv::UMat patch_feats_Test; - cv::UMat temp_Test; - cv::UMat zf_Test; - cv::UMat kzf_Test = cv::UMat::zeros((int) freq_size.height, (int) freq_size.width, CV_32FC2); + cv::UMat patch_feats; + cv::UMat temp; + cv::UMat zf; + cv::UMat kzf = cv::UMat::zeros((int) freq_size.height, (int) freq_size.width, CV_32FC2); KCF_Tracker::GaussianCorrelation gaussian_correlation{num_scales * num_angles, num_features, roi}; @@ -91,8 +86,7 @@ struct ThreadCtx { std::future async_res; #endif - cv::Mat response = cv::Mat(3, std::vector({int(num_scales * num_angles), (int) roi.height, (int) roi.width}).data(), CV_32F); - cv::UMat response_Test; + cv::UMat response; struct Max { cv::Point2i loc; From 4d84a337cd0d9b1a366c83c2f25ede7484433640 Mon Sep 17 00:00:00 2001 From: Your Name Date: Mon, 20 Apr 2020 15:12:20 +0200 Subject: [PATCH 097/121] =?UTF-8?q?MatUtil::sqrNorm()=20byla=20odstran?= =?UTF-8?q?=C4=9Bna=20ve=20prosp=C4=9Bch=20OpenCV=20implementace?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- src/kcf.cpp | 101 ++++++++++++++++++++++++++++++++++++-------------- src/kcf.h | 4 +- src/matutil.h | 70 +++++++++++++++++----------------- 3 files changed, 111 insertions(+), 64 deletions(-) diff --git a/src/kcf.cpp b/src/kcf.cpp index 0b063b9e..a6a5ef30 100644 --- a/src/kcf.cpp +++ b/src/kcf.cpp @@ -9,6 +9,9 @@ #include "debug.h" #include #include +#include +#include +#include #ifdef OPENMP #include @@ -130,37 +133,79 @@ void KCF_Tracker::init(cv::UMat &img, const cv::Rect &bbox, int fit_size_x, int // DEBUG_PRINTM(test2); // cv::UMat test = test2.getUMat(cv::ACCESS_RW); // DEBUG_PRINTM(test); -// cv::UMat test = cv::UMat(3, std::vector({2, 2, 2}).data(), CV_32FC2, float(5)); -// cv::UMat testPl = cv::UMat(test.size[1], test.size[2], test.type(), test.ptr(0)); - +// std::vector dims = std::vector({2, 2, 2}); +// std::vector dims2 = std::vector({2, 2, 2}); +// cv::Mat test = cv::Mat(dims, CV_32FC2); +// cv::Mat testAdd = cv::Mat(dims2, CV_32FC2); +// +// cv::UMat testPl = cv::UMat(test.size[1], test.size[2], test.type(), test.getMat(cv::ACCESS_RW).ptr(0)); +// // //// cv::Mat_> testComplex = cv::Mat_>(test2); // -// test.getMat(cv::ACCESS_WRITE).ptr(0)[0] = float(1); -// test.getMat(cv::ACCESS_WRITE).ptr(0)[1] = float(2); -// test.getMat(cv::ACCESS_WRITE).ptr(0)[2] = float(3); -// test.getMat(cv::ACCESS_WRITE).ptr(0)[3] = float(4); -// test.getMat(cv::ACCESS_WRITE).ptr(0)[4] = float(5); -// test.getMat(cv::ACCESS_WRITE).ptr(0)[5] = float(6); -// test.getMat(cv::ACCESS_WRITE).ptr(0)[6] = float(7); -// test.getMat(cv::ACCESS_WRITE).ptr(0)[7] = float(8); -// test.getMat(cv::ACCESS_WRITE).ptr(1)[0] = float(9); -// test.getMat(cv::ACCESS_WRITE).ptr(1)[1] = float(10); -// test.getMat(cv::ACCESS_WRITE).ptr(1)[2] = float(11); -// test.getMat(cv::ACCESS_WRITE).ptr(1)[3] = float(12); -// test.getMat(cv::ACCESS_WRITE).ptr(1)[4] = float(13); -// test.getMat(cv::ACCESS_WRITE).ptr(1)[5] = float(14); -// test.getMat(cv::ACCESS_WRITE).ptr(1)[6] = float(15); -// test.getMat(cv::ACCESS_WRITE).ptr(1)[7] = float(16); - - +// test.ptr(0)[0] = float(1); +// test.ptr(0)[1] = float(2); +// test.ptr(0)[2] = float(3); +// test.ptr(0)[3] = float(4); +// test.ptr(0)[4] = float(5); +// test.ptr(0)[5] = float(6); +// test.ptr(0)[6] = float(7); +// test.ptr(0)[7] = float(8); +// test.ptr(1)[0] = float(9); +// test.ptr(1)[1] = float(10); +// test.ptr(1)[2] = float(11); +// test.ptr(1)[3] = float(12); +// test.ptr(1)[4] = float(13); +// test.ptr(1)[5] = float(14); +// test.ptr(1)[6] = float(15); +// test.ptr(1)[7] = float(16); +// +// testAdd.ptr(0)[0] = float(1); +// testAdd.ptr(0)[1] = float(1); +// testAdd.ptr(0)[2] = float(1); +// testAdd.ptr(0)[3] = float(1); +// testAdd.ptr(0)[4] = float(1); +// testAdd.ptr(0)[5] = float(1); +// testAdd.ptr(0)[6] = float(1); +// testAdd.ptr(0)[7] = float(1); +// testAdd.ptr(1)[0] = float(1); +// testAdd.ptr(1)[1] = float(1); +// testAdd.ptr(1)[2] = float(1); +// testAdd.ptr(1)[3] = float(1); +// testAdd.ptr(1)[4] = float(1); +// testAdd.ptr(1)[5] = float(1); +// testAdd.ptr(1)[6] = float(1); +// testAdd.ptr(1)[7] = float(1); +// +// cv::GMat in; +// cv::GMat inAdd; +// cv::GMat out = cv::gapi::add(in,inAdd); +// cv::GComputation ac(cv::GIn(in, inAdd), cv::GOut(out)); +// // -// cv::Mat matTest = cv::Mat(test.size[1], test.size[2], test.type(), test.getMat(cv::ACCESS_READ).ptr(1)); -// cv::UMat testPl = matTest.getUMat(cv::ACCESS_RW); -// cv::UMat test2 = cv::UMat(2,2,CV_32FC2,float(6)); +// cv::Mat tmp1 = cv::Mat(2, 2, CV_32FC2, test.ptr(0)); +// cv::Mat tmp2 = cv::Mat(2, 2, CV_32FC2, testAdd.ptr(0)); +// cv::Mat tmp3 = cv::Mat::zeros(2, 2, CV_32FC2); +// +// DEBUG_PRINTM(tmp3); +// ac.apply(cv::gin(tmp1,tmp2), cv::gout(tmp3)); +// DEBUG_PRINTM(tmp1); +// DEBUG_PRINTM(tmp2); +// DEBUG_PRINTM(tmp3); +// +// cv::Mat tmp4 = test.getMat(cv::ACCESS_WRITE); +// cv::Mat tmp5 = testAdd.getMat(cv::ACCESS_WRITE); +// std::vector dims3 = std::vector({2, 2, 2}); +// cv::Mat tmp6 = cv::Mat(dims3, CV_32FC2); // DEBUG_PRINTM(test); -// DEBUG_PRINTM(testPl); -// DEBUG_PRINTM(test2); +// DEBUG_PRINTM(testAdd); +// DEBUG_PRINTM(tmp6); +// ac.apply(cv::gin(test,testAdd), cv::gout(tmp6)); +// DEBUG_PRINTM(test); +// DEBUG_PRINTM(testAdd); +// DEBUG_PRINTM(tmp6); +// +// // return; // // int from_to[] = { 0,0 }; @@ -956,14 +1001,14 @@ void KCF_Tracker::GaussianCorrelation::operator()(cv::UMat &result, cv::UMat &xf TRACE(""); DEBUG_PRINTM(xf); - xf_sqr_norm = MatUtil::sqr_norm(xf); + xf_sqr_norm = (cv::norm(xf , cv::NORM_L2SQR) / static_cast(xf.rows * xf.cols)); DEBUG_PRINT(xf_sqr_norm); if (auto_correlation) { yf_sqr_norm = xf_sqr_norm; } else { DEBUG_PRINTM(yf); - yf_sqr_norm = MatUtil::sqr_norm(yf); + yf_sqr_norm = (cv::norm(yf , cv::NORM_L2SQR) / static_cast(yf.rows * yf.cols)); } DEBUG_PRINT(yf_sqr_norm); diff --git a/src/kcf.h b/src/kcf.h index 7d1c99b0..4b3ceafd 100644 --- a/src/kcf.h +++ b/src/kcf.h @@ -173,8 +173,8 @@ class KCF_Tracker void operator()(cv::UMat &result, cv::UMat &xf, cv::UMat &yf, double sigma, bool auto_correlation, const KCF_Tracker &kcf); private: - float xf_sqr_norm; - float yf_sqr_norm; + double xf_sqr_norm; + double yf_sqr_norm; cv::UMat xyf; cv::UMat ifft_res; cv::UMat k; diff --git a/src/matutil.h b/src/matutil.h index c23d5712..a45ce12a 100644 --- a/src/matutil.h +++ b/src/matutil.h @@ -88,43 +88,45 @@ static void set_channel(int idxFrom, int idxTo, cv::UMat &source, cv::UMat &targ } /* + * REPLACED BY OPENCV IMPLEMENTATION + * ------------------------------------ * Computes sum of results from formula ((real)^2 + (imag)^2) * for every complex element of the input matrix. **/ -static float sqr_norm(const cv::Mat &host) -{ - assert(host.channels() % 2 == 0); - float sum_sqr_norm = 0; - - for (int row = 0; row < host.rows; ++row){ - for (int col = 0; col < host.cols; ++col){ - for (int ch = 0; ch < host.channels() / 2; ++ch){ - std::complex cpxVal = host.ptr>(row)[(host.channels() / 2)*col + ch]; - sum_sqr_norm += cpxVal.real() * cpxVal.real() + cpxVal.imag() * cpxVal.imag(); - } - } - } - sum_sqr_norm = sum_sqr_norm / static_cast(host.rows * host.cols); - return sum_sqr_norm; -} -static float sqr_norm(const cv::UMat &host) -{ - assert(host.channels() % 2 == 0); - float sum_sqr_norm = 0; - cv::Mat tempHost = host.getMat(cv::ACCESS_READ); - - for (int row = 0; row < host.rows; ++row){ - for (int col = 0; col < host.cols; ++col){ - for (int ch = 0; ch < host.channels() / 2; ++ch){ - std::complex cpxVal = tempHost.ptr>(row) - [(host.channels() / 2)*col + ch]; - sum_sqr_norm += cpxVal.real() * cpxVal.real() + cpxVal.imag() * cpxVal.imag(); - } - } - } - sum_sqr_norm = sum_sqr_norm / static_cast(host.rows * host.cols); - return sum_sqr_norm; -} +//static double sqr_norm(const cv::Mat &host) +//{ +// assert(host.channels() % 2 == 0); +// double sum_sqr_norm = 0; +// +// for (int row = 0; row < host.rows; ++row){ +// for (int col = 0; col < host.cols; ++col){ +// for (int ch = 0; ch < host.channels() / 2; ++ch){ +// std::complex cpxVal = host.ptr>(row)[(host.channels() / 2)*col + ch]; +// sum_sqr_norm += cpxVal.real() * cpxVal.real() + cpxVal.imag() * cpxVal.imag(); +// } +// } +// } +// sum_sqr_norm = sum_sqr_norm / static_cast(host.rows * host.cols); +// return sum_sqr_norm; +//} +//static float sqr_norm(const cv::UMat &host) +//{ +// assert(host.channels() % 2 == 0); +// float sum_sqr_norm = 0; +// cv::Mat tempHost = host.getMat(cv::ACCESS_READ); +// +// for (int row = 0; row < host.rows; ++row){ +// for (int col = 0; col < host.cols; ++col){ +// for (int ch = 0; ch < host.channels() / 2; ++ch){ +// std::complex cpxVal = tempHost.ptr>(row) +// [(host.channels() / 2)*col + ch]; +// sum_sqr_norm += cpxVal.real() * cpxVal.real() + cpxVal.imag() * cpxVal.imag(); +// } +// } +// } +// sum_sqr_norm = sum_sqr_norm / static_cast(host.rows * host.cols); +// return sum_sqr_norm; +//} /* * Sum of channel values for each point of input matrix From 6937808d3ebc977fa5263603e309d360edd4cd1f Mon Sep 17 00:00:00 2001 From: Your Name Date: Mon, 20 Apr 2020 17:01:35 +0200 Subject: [PATCH 098/121] =?UTF-8?q?MatUtil::mat=5Fconst=5Foperator()=20od?= =?UTF-8?q?=20te=C4=8F=20iteruje=20pomoc=C3=AD=20cv::Mat.forEach()=20-=20n?= =?UTF-8?q?a=20t=C3=A9to=20funkci=20jsou=20z=C3=A1visl=C3=A9=20funkce=20sq?= =?UTF-8?q?r=5Fmag(),=20conj()=20a=20add=5Fscalar()=20-=20podle=20zdroj?= =?UTF-8?q?=C5=AF=20na=20internetu=20tato=20zm=C4=9Bna=20zrychl=C3=AD=20pr?= =?UTF-8?q?=C5=AFb=C4=9Bh=20v=C5=A1ech=20t=C4=9Bchto=20funkc=C3=AD=20zhrub?= =?UTF-8?q?a=205-n=C3=A1sobn=C4=9B?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- src/kcf.cpp | 51 +++++++++++++++++++++++---------------------------- src/matutil.h | 37 ++++++++++--------------------------- 2 files changed, 33 insertions(+), 55 deletions(-) diff --git a/src/kcf.cpp b/src/kcf.cpp index a6a5ef30..f6ab7d22 100644 --- a/src/kcf.cpp +++ b/src/kcf.cpp @@ -134,9 +134,9 @@ void KCF_Tracker::init(cv::UMat &img, const cv::Rect &bbox, int fit_size_x, int // cv::UMat test = test2.getUMat(cv::ACCESS_RW); // DEBUG_PRINTM(test); // std::vector dims = std::vector({2, 2, 2}); -// std::vector dims2 = std::vector({2, 2, 2}); + std::vector dims2 = std::vector({2, 2, 2}); // cv::Mat test = cv::Mat(dims, CV_32FC2); -// cv::Mat testAdd = cv::Mat(dims2, CV_32FC2); + cv::Mat testAdd = cv::Mat(dims2, CV_32FC2); // // cv::UMat testPl = cv::UMat(test.size[1], test.size[2], test.type(), test.getMat(cv::ACCESS_RW).ptr(0)); // @@ -160,22 +160,26 @@ void KCF_Tracker::init(cv::UMat &img, const cv::Rect &bbox, int fit_size_x, int // test.ptr(1)[6] = float(15); // test.ptr(1)[7] = float(16); // -// testAdd.ptr(0)[0] = float(1); -// testAdd.ptr(0)[1] = float(1); -// testAdd.ptr(0)[2] = float(1); -// testAdd.ptr(0)[3] = float(1); -// testAdd.ptr(0)[4] = float(1); -// testAdd.ptr(0)[5] = float(1); -// testAdd.ptr(0)[6] = float(1); -// testAdd.ptr(0)[7] = float(1); -// testAdd.ptr(1)[0] = float(1); -// testAdd.ptr(1)[1] = float(1); -// testAdd.ptr(1)[2] = float(1); -// testAdd.ptr(1)[3] = float(1); -// testAdd.ptr(1)[4] = float(1); -// testAdd.ptr(1)[5] = float(1); -// testAdd.ptr(1)[6] = float(1); -// testAdd.ptr(1)[7] = float(1); + testAdd.ptr(0)[0] = float(1); + testAdd.ptr(0)[1] = float(1); + testAdd.ptr(0)[2] = float(1); + testAdd.ptr(0)[3] = float(1); + testAdd.ptr(0)[4] = float(1); + testAdd.ptr(0)[5] = float(1); + testAdd.ptr(0)[6] = float(1); + testAdd.ptr(0)[7] = float(1); + testAdd.ptr(1)[0] = float(1); + testAdd.ptr(1)[1] = float(1); + testAdd.ptr(1)[2] = float(1); + testAdd.ptr(1)[3] = float(1); + testAdd.ptr(1)[4] = float(1); + testAdd.ptr(1)[5] = float(1); + testAdd.ptr(1)[6] = float(1); + testAdd.ptr(1)[7] = float(1); + + testAdd.forEach< std::complex >([](std::complex &c, const int * position) { c += 2; (void)position;}); + DEBUG_PRINTM(testAdd); + return; // // cv::GMat in; // cv::GMat inAdd; @@ -1030,16 +1034,7 @@ void KCF_Tracker::GaussianCorrelation::operator()(cv::UMat &result, cv::UMat &xf cv::exp(-1. / (sigma * sigma) * cv::max((xf_sqr_norm + yf_sqr_norm - 2 * MatUtil::plane(0,ifft_res_Temp)) * numel_xf_inv, 0), plane); - -// This seems to produce slightly inaccurate results -// -------------------------------------------------- -// cv::UMat tempPlane = plane.clone(); -// cv::multiply(tempPlane, -2, tempPlane); -// cv::add(tempPlane, xf_sqr_norm + yf_sqr_norm, tempPlane); -// cv::multiply(tempPlane, numel_xf_inv, tempPlane); -// cv::max(tempPlane, 0, tempPlane); -// cv::multiply(tempPlane, (-1. / (sigma * sigma)) , tempPlane); -// cv::exp(tempPlane, plane); + DEBUG_PRINTM(plane); kcf.fft.forward(MatUtil::plane(0,ifft_res), result); diff --git a/src/matutil.h b/src/matutil.h index a45ce12a..fa62aabd 100644 --- a/src/matutil.h +++ b/src/matutil.h @@ -194,20 +194,19 @@ static cv::UMat channel_to_cv_mat(int channel_id, cv::UMat &host){ * Returns complex matrix, where every element is result of formula (hostElem.real() )^2 + (hostElem.imag() )^2 **/ static cv::Mat sqr_mag(cv::Mat &host){ - return mat_const_operator([](std::complex &c) { c = c.real() * c.real() + c.imag() * c.imag(); }, host); + return mat_const_operator([](std::complex &c, const int * position) { c = c.real() * c.real() + c.imag() * c.imag(); (void)position;}, host); } static cv::UMat sqr_mag(cv::UMat &host){ - return mat_const_operator([](std::complex &c) { c = c.real() * c.real() + c.imag() * c.imag(); }, host); + return mat_const_operator([](std::complex &c, const int * position) { c = c.real() * c.real() + c.imag() * c.imag(); (void)position;}, host); } - /* * Returns copy of input complex matrix, where every imaginary value is inverted **/ static cv::Mat conj(cv::Mat &host){ - return mat_const_operator([](std::complex &c) { c = std::complex(c.real(), -c.imag()); }, host); + return mat_const_operator([](std::complex &c, const int * position) { c = std::complex(c.real(), -c.imag()); (void)position;}, host); } static cv::UMat conj(cv::UMat &host){ - return mat_const_operator([](std::complex &c) { c = std::complex(c.real(), -c.imag()); }, host); + return mat_const_operator([](std::complex &c, const int * position) { c = std::complex(c.real(), -c.imag()); (void)position;}, host); } /* @@ -234,10 +233,10 @@ static cv::UMat mul_matn_matn(cv::UMat &host, cv::UMat &other){ * Returns result of element wise addition to complex matrix **/ static cv::Mat add_scalar(cv::Mat &host, const float &val){ - return mat_const_operator([&val](std::complex &c) { c += val; }, host); + return mat_const_operator([&val](std::complex &c, const int * position) { c += val; (void)position;}, host); } static cv::UMat add_scalar(cv::UMat &host, const float &val){ - return mat_const_operator([&val](std::complex &c) { c += val; }, host); + return mat_const_operator([&val](std::complex &c, const int * position) { c += val; (void)position;}, host); } /* @@ -254,33 +253,17 @@ static cv::UMat divide_matn_matn(cv::UMat &host, cv::UMat &other){ * Helper function to iterate through an input complex matrix. * Creates copy of the matrix, executes supplied function on each element, then returns the copy. **/ -static cv::Mat mat_const_operator(const std::function &)> &op, cv::Mat &host){ +static cv::Mat mat_const_operator(const std::function &, const int *)> &op, cv::Mat &host){ assert(host.channels() % 2 == 0); cv::Mat result = host.clone(); - for (int i = 0; i < result.rows; ++i) { - for (int j = 0; j < result.cols; ++j){ - for (int k = 0; k < result.channels() / 2 ; ++k){ - std::complex cpxVal = result.ptr>(i)[(result.channels() / 2)*j + k]; - op(cpxVal); - result.ptr>(i)[(result.channels() / 2)*j + k] = cpxVal; - } - } - } + result.forEach< std::complex >(op); return result; } -static cv::UMat mat_const_operator(const std::function &)> &op, cv::UMat &host){ +static cv::UMat mat_const_operator(const std::function &, const int *)> &op, cv::UMat &host){ assert(host.channels() % 2 == 0); cv::UMat result = host.clone(); cv::Mat tempResult = result.getMat(cv::ACCESS_RW); - for (int i = 0; i < tempResult.rows; ++i) { - for (int j = 0; j < tempResult.cols; ++j){ - for (int k = 0; k < tempResult.channels() / 2 ; ++k){ - std::complex cpxVal = tempResult.ptr>(i)[(tempResult.channels() / 2)*j + k]; - op(cpxVal); - tempResult.ptr>(i)[(tempResult.channels() / 2)*j + k] = cpxVal; - } - } - } + tempResult.forEach< std::complex >(op); return result; } From c8b38c73390566216cf154d4364b4d8c8db4cd44 Mon Sep 17 00:00:00 2001 From: Your Name Date: Mon, 20 Apr 2020 17:02:20 +0200 Subject: [PATCH 099/121] =?UTF-8?q?Zakomentov=C3=A1n=20testovac=C3=AD=20bl?= =?UTF-8?q?ok.?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- src/kcf.cpp | 44 ++++++++++++++++++++++---------------------- 1 file changed, 22 insertions(+), 22 deletions(-) diff --git a/src/kcf.cpp b/src/kcf.cpp index f6ab7d22..c98ce826 100644 --- a/src/kcf.cpp +++ b/src/kcf.cpp @@ -134,9 +134,9 @@ void KCF_Tracker::init(cv::UMat &img, const cv::Rect &bbox, int fit_size_x, int // cv::UMat test = test2.getUMat(cv::ACCESS_RW); // DEBUG_PRINTM(test); // std::vector dims = std::vector({2, 2, 2}); - std::vector dims2 = std::vector({2, 2, 2}); +// std::vector dims2 = std::vector({2, 2, 2}); // cv::Mat test = cv::Mat(dims, CV_32FC2); - cv::Mat testAdd = cv::Mat(dims2, CV_32FC2); +// cv::Mat testAdd = cv::Mat(dims2, CV_32FC2); // // cv::UMat testPl = cv::UMat(test.size[1], test.size[2], test.type(), test.getMat(cv::ACCESS_RW).ptr(0)); // @@ -160,26 +160,26 @@ void KCF_Tracker::init(cv::UMat &img, const cv::Rect &bbox, int fit_size_x, int // test.ptr(1)[6] = float(15); // test.ptr(1)[7] = float(16); // - testAdd.ptr(0)[0] = float(1); - testAdd.ptr(0)[1] = float(1); - testAdd.ptr(0)[2] = float(1); - testAdd.ptr(0)[3] = float(1); - testAdd.ptr(0)[4] = float(1); - testAdd.ptr(0)[5] = float(1); - testAdd.ptr(0)[6] = float(1); - testAdd.ptr(0)[7] = float(1); - testAdd.ptr(1)[0] = float(1); - testAdd.ptr(1)[1] = float(1); - testAdd.ptr(1)[2] = float(1); - testAdd.ptr(1)[3] = float(1); - testAdd.ptr(1)[4] = float(1); - testAdd.ptr(1)[5] = float(1); - testAdd.ptr(1)[6] = float(1); - testAdd.ptr(1)[7] = float(1); - - testAdd.forEach< std::complex >([](std::complex &c, const int * position) { c += 2; (void)position;}); - DEBUG_PRINTM(testAdd); - return; +// testAdd.ptr(0)[0] = float(1); +// testAdd.ptr(0)[1] = float(1); +// testAdd.ptr(0)[2] = float(1); +// testAdd.ptr(0)[3] = float(1); +// testAdd.ptr(0)[4] = float(1); +// testAdd.ptr(0)[5] = float(1); +// testAdd.ptr(0)[6] = float(1); +// testAdd.ptr(0)[7] = float(1); +// testAdd.ptr(1)[0] = float(1); +// testAdd.ptr(1)[1] = float(1); +// testAdd.ptr(1)[2] = float(1); +// testAdd.ptr(1)[3] = float(1); +// testAdd.ptr(1)[4] = float(1); +// testAdd.ptr(1)[5] = float(1); +// testAdd.ptr(1)[6] = float(1); +// testAdd.ptr(1)[7] = float(1); +// +// testAdd.forEach< std::complex >([](std::complex &c, const int * position) { c += 2; (void)position;}); +// DEBUG_PRINTM(testAdd); +// return; // // cv::GMat in; // cv::GMat inAdd; From e9e4deda440f8146fe525155d409e01f4c51761a Mon Sep 17 00:00:00 2001 From: Your Name Date: Mon, 20 Apr 2020 19:49:57 +0200 Subject: [PATCH 100/121] =?UTF-8?q?Implementace=20Mat.forEach()=20zakoment?= =?UTF-8?q?ov=C3=A1na,=20chybn=C3=BD=20v=C3=BDstup?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- src/kcf.cpp | 6 +---- src/matutil.h | 63 +++++++++++++++++++++++++++++++++++++++++++-------- 2 files changed, 54 insertions(+), 15 deletions(-) diff --git a/src/kcf.cpp b/src/kcf.cpp index c98ce826..aa00c3af 100644 --- a/src/kcf.cpp +++ b/src/kcf.cpp @@ -176,10 +176,6 @@ void KCF_Tracker::init(cv::UMat &img, const cv::Rect &bbox, int fit_size_x, int // testAdd.ptr(1)[5] = float(1); // testAdd.ptr(1)[6] = float(1); // testAdd.ptr(1)[7] = float(1); -// -// testAdd.forEach< std::complex >([](std::complex &c, const int * position) { c += 2; (void)position;}); -// DEBUG_PRINTM(testAdd); -// return; // // cv::GMat in; // cv::GMat inAdd; @@ -1034,7 +1030,7 @@ void KCF_Tracker::GaussianCorrelation::operator()(cv::UMat &result, cv::UMat &xf cv::exp(-1. / (sigma * sigma) * cv::max((xf_sqr_norm + yf_sqr_norm - 2 * MatUtil::plane(0,ifft_res_Temp)) * numel_xf_inv, 0), plane); - + DEBUG_PRINTM(plane); kcf.fft.forward(MatUtil::plane(0,ifft_res), result); diff --git a/src/matutil.h b/src/matutil.h index fa62aabd..565ea122 100644 --- a/src/matutil.h +++ b/src/matutil.h @@ -194,19 +194,21 @@ static cv::UMat channel_to_cv_mat(int channel_id, cv::UMat &host){ * Returns complex matrix, where every element is result of formula (hostElem.real() )^2 + (hostElem.imag() )^2 **/ static cv::Mat sqr_mag(cv::Mat &host){ - return mat_const_operator([](std::complex &c, const int * position) { c = c.real() * c.real() + c.imag() * c.imag(); (void)position;}, host); +// return mat_const_operator_Test([](std::complex &c, const int * position) { c = c.real() * c.real() + c.imag() * c.imag(); (void)position;}, host); + return mat_const_operator([](std::complex &c) { c = c.real() * c.real() + c.imag() * c.imag(); }, host); } static cv::UMat sqr_mag(cv::UMat &host){ - return mat_const_operator([](std::complex &c, const int * position) { c = c.real() * c.real() + c.imag() * c.imag(); (void)position;}, host); +// return mat_const_operator_Test([](std::complex &c, const int * position) { c = c.real() * c.real() + c.imag() * c.imag(); (void)position;}, host); + return mat_const_operator([](std::complex &c) { c = c.real() * c.real() + c.imag() * c.imag(); }, host); } /* * Returns copy of input complex matrix, where every imaginary value is inverted **/ static cv::Mat conj(cv::Mat &host){ - return mat_const_operator([](std::complex &c, const int * position) { c = std::complex(c.real(), -c.imag()); (void)position;}, host); + return mat_const_operator([](std::complex &c) { c = std::complex(c.real(), -c.imag()); }, host); } static cv::UMat conj(cv::UMat &host){ - return mat_const_operator([](std::complex &c, const int * position) { c = std::complex(c.real(), -c.imag()); (void)position;}, host); + return mat_const_operator([](std::complex &c) { c = std::complex(c.real(), -c.imag()); }, host); } /* @@ -233,10 +235,10 @@ static cv::UMat mul_matn_matn(cv::UMat &host, cv::UMat &other){ * Returns result of element wise addition to complex matrix **/ static cv::Mat add_scalar(cv::Mat &host, const float &val){ - return mat_const_operator([&val](std::complex &c, const int * position) { c += val; (void)position;}, host); + return mat_const_operator([&val](std::complex &c) { c += val; }, host); } static cv::UMat add_scalar(cv::UMat &host, const float &val){ - return mat_const_operator([&val](std::complex &c, const int * position) { c += val; (void)position;}, host); + return mat_const_operator([&val](std::complex &c) { c += val; }, host); } /* @@ -253,20 +255,61 @@ static cv::UMat divide_matn_matn(cv::UMat &host, cv::UMat &other){ * Helper function to iterate through an input complex matrix. * Creates copy of the matrix, executes supplied function on each element, then returns the copy. **/ -static cv::Mat mat_const_operator(const std::function &, const int *)> &op, cv::Mat &host){ +static cv::Mat mat_const_operator(const std::function &)> &op, cv::Mat &host){ assert(host.channels() % 2 == 0); + assert(host.rows > 0); + assert(host.cols > 0); cv::Mat result = host.clone(); - result.forEach< std::complex >(op); + for (int i = 0; i < result.rows; ++i) { + for (int j = 0; j < result.cols; ++j){ + for (int k = 0; k < result.channels() / 2 ; ++k){ + std::complex cpxVal = result.ptr>(i)[(result.channels() / 2)*j + k]; +// DEBUG_PRINTM(cpxVal); + op(cpxVal); +// DEBUG_PRINTM(cpxVal); +// DEBUG_PRINTM("did"); + result.ptr>(i)[(result.channels() / 2)*j + k] = cpxVal; + } + } + } return result; } -static cv::UMat mat_const_operator(const std::function &, const int *)> &op, cv::UMat &host){ +static cv::UMat mat_const_operator(const std::function &)> &op, cv::UMat &host){ assert(host.channels() % 2 == 0); + assert(host.rows > 0); + assert(host.cols > 0); cv::UMat result = host.clone(); cv::Mat tempResult = result.getMat(cv::ACCESS_RW); - tempResult.forEach< std::complex >(op); + for (int i = 0; i < tempResult.rows; ++i) { + for (int j = 0; j < tempResult.cols; ++j){ + for (int k = 0; k < tempResult.channels() / 2 ; ++k){ + std::complex cpxVal = tempResult.ptr>(i)[(tempResult.channels() / 2)*j + k]; + op(cpxVal); + tempResult.ptr>(i)[(tempResult.channels() / 2)*j + k] = cpxVal; + } + } + } return result; } +//static cv::Mat mat_const_operator_Test(const std::function &, const int *)> &op, cv::Mat &host){ +// assert(host.channels() % 2 == 0); +// assert(host.rows > 0); +// assert(host.cols > 0); +// cv::Mat result = host.clone(); +// result.forEach< std::complex >(op); +// return result; +//} +//static cv::UMat mat_const_operator_Test(const std::function &, const int *)> &op, cv::UMat &host){ +// assert(host.channels() % 2 == 0); +// assert(host.rows > 0); +// assert(host.cols > 0); +// cv::UMat result = host.clone(); +// cv::Mat tempResult = result.getMat(cv::ACCESS_RW); +// tempResult.forEach< std::complex >(op); +// return result; +//} + /* * Helper function to iterate through n-channeled and single-channeled complex matrixes. * Creates copy of the n-channeled matrix, executes supplied function on each element of it, then returns the copy. From b59631985acaf506433d9f1ba82dbfcc5ffb5708 Mon Sep 17 00:00:00 2001 From: Your Name Date: Wed, 22 Apr 2020 18:43:25 +0200 Subject: [PATCH 101/121] =?UTF-8?q?Implementace=20Mat.forEach()=20opravena?= =?UTF-8?q?=20a=20otestov=C3=A1na=20-=20probl=C3=A9m=20byl=20v=20typov?= =?UTF-8?q?=C3=A9m=20argumentu=20forEach(),=20kter=C3=BD=20p=C5=99istupova?= =?UTF-8?q?l=20k=20dat=C5=AFm=20nespr=C3=A1vn=C3=BDm=20zp=C5=AFsobem=20-?= =?UTF-8?q?=20vy=C5=99e=C5=A1eno=20konverz=C3=AD=20pracov=C3=A1van=C3=A9?= =?UTF-8?q?=20matice=20na=20cv::=5FMat<=20std::complex=20>=20a=20vy?= =?UTF-8?q?pu=C5=A1t=C4=9Bn=C3=ADm=20typov=C3=A9ho=20argumentu=20forEach()?= =?UTF-8?q?=20-=20prozat=C3=ADm=20implementov=C3=A1no=20pouze=20na=20funkc?= =?UTF-8?q?=C3=ADch=20pou=C5=BE=C3=ADvaj=C3=ADc=C3=ADch=20mat=5Fconst=5Fop?= =?UTF-8?q?erator(),=20dal=C5=A1=C3=AD=20budou=20n=C3=A1sledovat=20-=20Cel?= =?UTF-8?q?=C3=BD=20program=20v=C5=A1ak=20u=C5=BE=20te=C4=8F=20pracuje=20m?= =?UTF-8?q?nohem,=20mnohem=20rychleji?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- src/kcf.cpp | 15 ++++++++-- src/matutil.h | 76 ++++++++++----------------------------------------- 2 files changed, 27 insertions(+), 64 deletions(-) diff --git a/src/kcf.cpp b/src/kcf.cpp index aa00c3af..62676bef 100644 --- a/src/kcf.cpp +++ b/src/kcf.cpp @@ -135,8 +135,8 @@ void KCF_Tracker::init(cv::UMat &img, const cv::Rect &bbox, int fit_size_x, int // DEBUG_PRINTM(test); // std::vector dims = std::vector({2, 2, 2}); // std::vector dims2 = std::vector({2, 2, 2}); -// cv::Mat test = cv::Mat(dims, CV_32FC2); -// cv::Mat testAdd = cv::Mat(dims2, CV_32FC2); +// cv::Mat test = cv::Mat(3, dims.data(), CV_32FC2); +// cv::Mat testAdd = cv::Mat(3, dims2.data(), CV_32FC2); // // cv::UMat testPl = cv::UMat(test.size[1], test.size[2], test.type(), test.getMat(cv::ACCESS_RW).ptr(0)); // @@ -176,6 +176,15 @@ void KCF_Tracker::init(cv::UMat &img, const cv::Rect &bbox, int fit_size_x, int // testAdd.ptr(1)[5] = float(1); // testAdd.ptr(1)[6] = float(1); // testAdd.ptr(1)[7] = float(1); +// +// std::vector dims3 = std::vector({2, 2, 2}); +// cv::Mat plan = MatUtil::plane(0,test); +// cv::Mat testComplex = MatUtil::rowToMat(0,plan); +// +// DEBUG_PRINTM(test); +// DEBUG_PRINTM(testAdd); +// DEBUG_PRINTM(testComplex); +// return; // // cv::GMat in; // cv::GMat inAdd; @@ -1015,7 +1024,7 @@ void KCF_Tracker::GaussianCorrelation::operator()(cv::UMat &result, cv::UMat &xf cv::UMat conjMat = MatUtil::conj(yf); xyf = auto_correlation ? MatUtil::sqr_mag(xf) : MatUtil::mul_matn_matn(xf, conjMat); // xf.muln(yf.conj()); DEBUG_PRINTM(xyf); - + // ifft2 and sum over 3rd dimension, we dont care about individual channels cv::UMat xyf_sum = MatUtil::sum_over_channels(xyf); DEBUG_PRINTM(xyf_sum); diff --git a/src/matutil.h b/src/matutil.h index 565ea122..17c401f7 100644 --- a/src/matutil.h +++ b/src/matutil.h @@ -193,22 +193,20 @@ static cv::UMat channel_to_cv_mat(int channel_id, cv::UMat &host){ /* * Returns complex matrix, where every element is result of formula (hostElem.real() )^2 + (hostElem.imag() )^2 **/ -static cv::Mat sqr_mag(cv::Mat &host){ -// return mat_const_operator_Test([](std::complex &c, const int * position) { c = c.real() * c.real() + c.imag() * c.imag(); (void)position;}, host); - return mat_const_operator([](std::complex &c) { c = c.real() * c.real() + c.imag() * c.imag(); }, host); -} static cv::UMat sqr_mag(cv::UMat &host){ -// return mat_const_operator_Test([](std::complex &c, const int * position) { c = c.real() * c.real() + c.imag() * c.imag(); (void)position;}, host); - return mat_const_operator([](std::complex &c) { c = c.real() * c.real() + c.imag() * c.imag(); }, host); + return mat_const_operator([](std::complex &c, const int * position) { + c = c.real() * c.real() + c.imag() * c.imag(); + (void)position; + }, host); } /* * Returns copy of input complex matrix, where every imaginary value is inverted **/ -static cv::Mat conj(cv::Mat &host){ - return mat_const_operator([](std::complex &c) { c = std::complex(c.real(), -c.imag()); }, host); -} static cv::UMat conj(cv::UMat &host){ - return mat_const_operator([](std::complex &c) { c = std::complex(c.real(), -c.imag()); }, host); + return mat_const_operator([](std::complex &c, const int * position) { + c = std::complex(c.real(), -c.imag()); + (void)position; + }, host); } /* @@ -234,11 +232,11 @@ static cv::UMat mul_matn_matn(cv::UMat &host, cv::UMat &other){ /* * Returns result of element wise addition to complex matrix **/ -static cv::Mat add_scalar(cv::Mat &host, const float &val){ - return mat_const_operator([&val](std::complex &c) { c += val; }, host); -} static cv::UMat add_scalar(cv::UMat &host, const float &val){ - return mat_const_operator([&val](std::complex &c) { c += val; }, host); + return mat_const_operator([&val](std::complex &c, const int * position) { + c += val; + (void)position; + }, host); } /* @@ -255,61 +253,17 @@ static cv::UMat divide_matn_matn(cv::UMat &host, cv::UMat &other){ * Helper function to iterate through an input complex matrix. * Creates copy of the matrix, executes supplied function on each element, then returns the copy. **/ -static cv::Mat mat_const_operator(const std::function &)> &op, cv::Mat &host){ - assert(host.channels() % 2 == 0); - assert(host.rows > 0); - assert(host.cols > 0); - cv::Mat result = host.clone(); - for (int i = 0; i < result.rows; ++i) { - for (int j = 0; j < result.cols; ++j){ - for (int k = 0; k < result.channels() / 2 ; ++k){ - std::complex cpxVal = result.ptr>(i)[(result.channels() / 2)*j + k]; -// DEBUG_PRINTM(cpxVal); - op(cpxVal); -// DEBUG_PRINTM(cpxVal); -// DEBUG_PRINTM("did"); - result.ptr>(i)[(result.channels() / 2)*j + k] = cpxVal; - } - } - } - return result; -} -static cv::UMat mat_const_operator(const std::function &)> &op, cv::UMat &host){ +static cv::UMat mat_const_operator(const std::function &, const int *)> &op, cv::UMat &host){ assert(host.channels() % 2 == 0); assert(host.rows > 0); assert(host.cols > 0); cv::UMat result = host.clone(); cv::Mat tempResult = result.getMat(cv::ACCESS_RW); - for (int i = 0; i < tempResult.rows; ++i) { - for (int j = 0; j < tempResult.cols; ++j){ - for (int k = 0; k < tempResult.channels() / 2 ; ++k){ - std::complex cpxVal = tempResult.ptr>(i)[(tempResult.channels() / 2)*j + k]; - op(cpxVal); - tempResult.ptr>(i)[(tempResult.channels() / 2)*j + k] = cpxVal; - } - } - } + cv::Mat_< std::complex > cpxMat = cv::Mat_< std::complex >(tempResult); + cpxMat.forEach(op); return result; } -//static cv::Mat mat_const_operator_Test(const std::function &, const int *)> &op, cv::Mat &host){ -// assert(host.channels() % 2 == 0); -// assert(host.rows > 0); -// assert(host.cols > 0); -// cv::Mat result = host.clone(); -// result.forEach< std::complex >(op); -// return result; -//} -//static cv::UMat mat_const_operator_Test(const std::function &, const int *)> &op, cv::UMat &host){ -// assert(host.channels() % 2 == 0); -// assert(host.rows > 0); -// assert(host.cols > 0); -// cv::UMat result = host.clone(); -// cv::Mat tempResult = result.getMat(cv::ACCESS_RW); -// tempResult.forEach< std::complex >(op); -// return result; -//} - /* * Helper function to iterate through n-channeled and single-channeled complex matrixes. * Creates copy of the n-channeled matrix, executes supplied function on each element of it, then returns the copy. From bdc51fffae50ea73f5dd0db85f2f49e9e3f4e1fc Mon Sep 17 00:00:00 2001 From: Your Name Date: Wed, 22 Apr 2020 20:45:10 +0200 Subject: [PATCH 102/121] =?UTF-8?q?Implementov=C3=A1na=20GAPI=20implementa?= =?UTF-8?q?ce=20pro=20funkci=20MatUtil::add=5Fscalar()=20-=20vypad=C3=A1?= =?UTF-8?q?=20to=20=C5=BEe=20GAPI=20bal=C3=ADky=20p=C5=99=C3=ADjmaj=C3=AD?= =?UTF-8?q?=20jako=20vstupn=C3=AD=20argument=20tak=C3=A9=20typ=20cv::Mat?= =?UTF-8?q?=5F<=20std::complex=20>=20-=20GAPI=20operace=20vykon?= =?UTF-8?q?=C3=A1van=C3=A9=20nad=20takto=20p=C5=99edan=C3=BDmi=20vstupy=20?= =?UTF-8?q?se=20z=C5=99ejm=C4=9B=20chovaj=C3=AD=20spr=C3=A1vn=C3=BDm=20zp?= =?UTF-8?q?=C5=AFsobem,=20tzn.=20je=20pou=C5=BEita=20artimetika=20std::com?= =?UTF-8?q?plex=20-=20p=C5=AFvodn=C3=AD=20implementace=20forEach()?= =?UTF-8?q?=20je=20uchov=C3=A1na=20pro=20pozd=C4=9Bj=C5=A1=C3=AD=20porovn?= =?UTF-8?q?=C3=A1n=C3=AD=20v=C3=BDkon=C5=AF=20obou=20funkc=C3=AD?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- src/kcf.cpp | 14 ++++++++++-- src/matutil.h | 63 ++++++++++++++++++--------------------------------- 2 files changed, 34 insertions(+), 43 deletions(-) diff --git a/src/kcf.cpp b/src/kcf.cpp index 62676bef..2fb1f4f2 100644 --- a/src/kcf.cpp +++ b/src/kcf.cpp @@ -176,10 +176,20 @@ void KCF_Tracker::init(cv::UMat &img, const cv::Rect &bbox, int fit_size_x, int // testAdd.ptr(1)[5] = float(1); // testAdd.ptr(1)[6] = float(1); // testAdd.ptr(1)[7] = float(1); -// +//// // std::vector dims3 = std::vector({2, 2, 2}); // cv::Mat plan = MatUtil::plane(0,test); -// cv::Mat testComplex = MatUtil::rowToMat(0,plan); +// cv::Mat_< std::complex > cpxMat = cv::Mat_< std::complex >(plan); +// cv::Mat_< std::complex > cpxMat2; +// +// cv::GMat in; +// cv::GMat out = cv::gapi::addC(in,10); +// cv::GComputation ac(in, out); +// ac.apply(cpxMat, cpxMat2); +// DEBUG_PRINTM(test); +// DEBUG_PRINTM(cpxMat); +// DEBUG_PRINTM(cpxMat2); +// return; // // DEBUG_PRINTM(test); // DEBUG_PRINTM(testAdd); diff --git a/src/matutil.h b/src/matutil.h index 17c401f7..d3b44c51 100644 --- a/src/matutil.h +++ b/src/matutil.h @@ -6,6 +6,9 @@ #include #include "debug.h" #include +#include +#include +#include class MatUtil{ public: @@ -87,47 +90,6 @@ static void set_channel(int idxFrom, int idxTo, cv::UMat &source, cv::UMat &targ cv::mixChannels( &convSrc, 1, &convTgt, 1, from_to, 1 ); } -/* - * REPLACED BY OPENCV IMPLEMENTATION - * ------------------------------------ - * Computes sum of results from formula ((real)^2 + (imag)^2) - * for every complex element of the input matrix. -**/ -//static double sqr_norm(const cv::Mat &host) -//{ -// assert(host.channels() % 2 == 0); -// double sum_sqr_norm = 0; -// -// for (int row = 0; row < host.rows; ++row){ -// for (int col = 0; col < host.cols; ++col){ -// for (int ch = 0; ch < host.channels() / 2; ++ch){ -// std::complex cpxVal = host.ptr>(row)[(host.channels() / 2)*col + ch]; -// sum_sqr_norm += cpxVal.real() * cpxVal.real() + cpxVal.imag() * cpxVal.imag(); -// } -// } -// } -// sum_sqr_norm = sum_sqr_norm / static_cast(host.rows * host.cols); -// return sum_sqr_norm; -//} -//static float sqr_norm(const cv::UMat &host) -//{ -// assert(host.channels() % 2 == 0); -// float sum_sqr_norm = 0; -// cv::Mat tempHost = host.getMat(cv::ACCESS_READ); -// -// for (int row = 0; row < host.rows; ++row){ -// for (int col = 0; col < host.cols; ++col){ -// for (int ch = 0; ch < host.channels() / 2; ++ch){ -// std::complex cpxVal = tempHost.ptr>(row) -// [(host.channels() / 2)*col + ch]; -// sum_sqr_norm += cpxVal.real() * cpxVal.real() + cpxVal.imag() * cpxVal.imag(); -// } -// } -// } -// sum_sqr_norm = sum_sqr_norm / static_cast(host.rows * host.cols); -// return sum_sqr_norm; -//} - /* * Sum of channel values for each point of input matrix * becomes a new point in the new matrix. @@ -233,6 +195,25 @@ static cv::UMat mul_matn_matn(cv::UMat &host, cv::UMat &other){ * Returns result of element wise addition to complex matrix **/ static cv::UMat add_scalar(cv::UMat &host, const float &val){ + cv::Mat tempMat = host.getMat(cv::ACCESS_RW); + cv::Mat_< std::complex > cpxMatIn = cv::Mat_< std::complex >(tempMat); + cv::Mat_< std::complex > cpxMatOut; + + cv::GMat in; + cv::GMat out = cv::gapi::addC(in,val); + cv::GComputation ac(in, out); + ac.apply(cpxMatIn, cpxMatOut); + + cv::UMat result = cpxMatOut.getUMat(cv::ACCESS_RW); + return result; +} + +/* + * Returns result of element wise addition to complex matrix. + * Produces same result as add_scalar() with great speed, but uses parallel processing through CPU instead of GPU. + * Left in the code to compare its speed against GAPI implementation. +**/ +static cv::UMat add_scalar_cpu(cv::UMat &host, const float &val){ return mat_const_operator([&val](std::complex &c, const int * position) { c += val; (void)position; From bc5aefa3e01f475aa0bcd697ab5156d94c27b293 Mon Sep 17 00:00:00 2001 From: Your Name Date: Thu, 23 Apr 2020 21:55:05 +0200 Subject: [PATCH 103/121] =?UTF-8?q?Konverze=20BGR2Gray()=20a=20resize()=20?= =?UTF-8?q?ve=20funkci=20KCF=5FTracker::init()=20na=20form=C3=A1t=20GAPI?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- src/kcf.cpp | 33 ++++++++++++++++++++++----------- 1 file changed, 22 insertions(+), 11 deletions(-) diff --git a/src/kcf.cpp b/src/kcf.cpp index 2fb1f4f2..627f9e41 100644 --- a/src/kcf.cpp +++ b/src/kcf.cpp @@ -293,25 +293,36 @@ void KCF_Tracker::init(cv::UMat &img, const cv::Rect &bbox, int fit_size_x, int p_init_pose.cx = x1 + p_init_pose.w / 2.; p_init_pose.cy = y1 + p_init_pose.h / 2.; - cv::UMat input_gray, input_rgb = img.clone(); - - if (img.channels() == 3) { - cv::cvtColor(img, input_gray, cv::COLOR_BGR2GRAY); - input_gray.convertTo(input_gray, CV_32FC1); - } else - img.convertTo(input_gray, CV_32FC1); - cv::Mat tempGray = input_gray.getMat(cv::ACCESS_RW); + cv::UMat input_rgb = img.clone(); cv::Mat tempRgb = input_rgb.getMat(cv::ACCESS_RW); + cv::Mat tempGray; + + cv::GMat inRgb; + cv::GMat outGray; + if (img.channels() == 3) { + outGray = cv::gapi::BGR2Gray(inRgb); + cv::GMat tempGapiGray = cv::gapi::convertTo(outGray, CV_32FC1); + outGray = tempGapiGray; + } else { + outGray = cv::gapi::convertTo(inRgb, CV_32FC1); + } + cv::GComputation cvtToGray(inRgb, outGray); + cvtToGray.apply(tempRgb, tempGray); + cv::UMat input_gray = tempGray.getUMat(cv::ACCESS_RW); + // don't need too large image if (p_init_pose.w * p_init_pose.h > 100. * 100.) { std::cout << "resizing image by factor of " << 1 / p_downscale_factor << std::endl; p_resize_image = true; p_init_pose.scale(p_downscale_factor); - cv::resize(tempGray, tempGray, cv::Size(0, 0), p_downscale_factor, p_downscale_factor, cv::INTER_AREA); - cv::resize(tempRgb, tempRgb, cv::Size(0, 0), p_downscale_factor, p_downscale_factor, cv::INTER_AREA); + cv::GMat inRgb2; + cv::GMat inGray2; + cv::GMat outRgb2 = cv::gapi::resize(inRgb2, cv::Size(0, 0),p_downscale_factor, p_downscale_factor, cv::INTER_AREA); + cv::GMat outGray2 = cv::gapi::resize(inGray2, cv::Size(0, 0),p_downscale_factor, p_downscale_factor, cv::INTER_AREA); + cv::GComputation resizeBoth(cv::GIn(inRgb2,inGray2), cv::GOut(outRgb2, outGray2)); + resizeBoth.apply(cv::gin(tempRgb, tempGray) , cv::gout(tempRgb, tempGray)); } - // compute win size + fit to fhog cell size p_windows_size.width = round(p_init_pose.w * (1. + p_padding) / p_cell_size) * p_cell_size; From 6d16c14cc81764c6a9c290bb14974fadbb148eb1 Mon Sep 17 00:00:00 2001 From: Your Name Date: Thu, 23 Apr 2020 22:25:37 +0200 Subject: [PATCH 104/121] =?UTF-8?q?Konverze=20BGR2Gray()=20a=20resizeImgs(?= =?UTF-8?q?)=20ve=20funkci=20KCF=5FTracker::track()=20na=20form=C3=A1t=20G?= =?UTF-8?q?API?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- src/kcf.cpp | 42 ++++++++++++++++++++++++------------------ src/kcf.h | 1 - 2 files changed, 24 insertions(+), 19 deletions(-) diff --git a/src/kcf.cpp b/src/kcf.cpp index 627f9e41..d6f2d88d 100644 --- a/src/kcf.cpp +++ b/src/kcf.cpp @@ -441,21 +441,17 @@ double KCF_Tracker::getFilterResponse() const return this->max_response; } -void KCF_Tracker::resizeImgs(cv::Mat &input_rgb, cv::Mat &input_gray) -{ - if (p_resize_image) { - cv::resize(input_gray, input_gray, cv::Size(0, 0), p_downscale_factor, p_downscale_factor, cv::INTER_AREA); - cv::resize(input_rgb, input_rgb, cv::Size(0, 0), p_downscale_factor, p_downscale_factor, cv::INTER_AREA); - } -} void KCF_Tracker::resizeImgs(cv::UMat &input_rgb, cv::UMat &input_gray) { - cv::Mat tempGray = input_gray.getMat(cv::ACCESS_RW); - cv::Mat tempRgb = input_rgb.getMat(cv::ACCESS_RW); - if (p_resize_image) { - cv::resize(tempGray, tempGray, cv::Size(0, 0), p_downscale_factor, p_downscale_factor, cv::INTER_AREA); - cv::resize(tempRgb, tempRgb, cv::Size(0, 0), p_downscale_factor, p_downscale_factor, cv::INTER_AREA); + cv::Mat tempGray = input_gray.getMat(cv::ACCESS_RW); + cv::Mat tempRgb = input_rgb.getMat(cv::ACCESS_RW); + cv::GMat inRgb; + cv::GMat inGray; + cv::GMat outRgb = cv::gapi::resize(inRgb, cv::Size(0, 0),p_downscale_factor, p_downscale_factor, cv::INTER_AREA); + cv::GMat outGray = cv::gapi::resize(inGray, cv::Size(0, 0),p_downscale_factor, p_downscale_factor, cv::INTER_AREA); + cv::GComputation resizeBoth(cv::GIn(inRgb,inGray), cv::GOut(outRgb, outGray)); + resizeBoth.apply(cv::gin(tempRgb, tempGray) , cv::gout(tempRgb, tempGray)); } } @@ -570,13 +566,23 @@ void KCF_Tracker::track(cv::UMat &img) __dbgTracer.debug = m_debug; TRACE(""); - cv::UMat input_gray, input_rgb = img.clone(); + cv::UMat input_rgb = img.clone(); + cv::Mat tempRgb = input_rgb.getMat(cv::ACCESS_RW); + cv::Mat tempGray; + + cv::GMat inRgb; + cv::GMat outGray; if (img.channels() == 3) { - cv::cvtColor(img, input_gray, cv::COLOR_BGR2GRAY); - input_gray.convertTo(input_gray, CV_32FC1); - } else - img.convertTo(input_gray, CV_32FC1); - + outGray = cv::gapi::BGR2Gray(inRgb); + cv::GMat tempGapiGray = cv::gapi::convertTo(outGray, CV_32FC1); + outGray = tempGapiGray; + } else { + outGray = cv::gapi::convertTo(inRgb, CV_32FC1); + } + cv::GComputation cvtToGray(inRgb, outGray); + cvtToGray.apply(tempRgb, tempGray); + cv::UMat input_gray = tempGray.getUMat(cv::ACCESS_RW); + // don't need too large image resizeImgs(input_rgb, input_gray); diff --git a/src/kcf.h b/src/kcf.h index 4b3ceafd..fc2c02d5 100644 --- a/src/kcf.h +++ b/src/kcf.h @@ -193,7 +193,6 @@ class KCF_Tracker 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 resizeImgs(cv::UMat &input_rgb, cv::UMat &input_gray); void train(cv::UMat input_rgb, cv::UMat input_gray, double interp_factor); double findMaxReponse(uint &max_idx, cv::Point2d &new_location) const; From 8bd2e6d3dade5af2d08aaa18cf1d2511a5f17f8a Mon Sep 17 00:00:00 2001 From: Your Name Date: Thu, 23 Apr 2020 22:42:21 +0200 Subject: [PATCH 105/121] =?UTF-8?q?Odstran=C4=9Bna=20redundantn=C3=AD=20fu?= =?UTF-8?q?nkce=20cosine=5Fwindow=5Ffunction=5Fumat()?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- src/kcf.cpp | 16 +--------------- src/kcf.h | 1 - 2 files changed, 1 insertion(+), 16 deletions(-) diff --git a/src/kcf.cpp b/src/kcf.cpp index d6f2d88d..295ed597 100644 --- a/src/kcf.cpp +++ b/src/kcf.cpp @@ -391,7 +391,7 @@ void KCF_Tracker::init(cv::UMat &img, const cv::Rect &bbox, int fit_size_x, int * p_output_sigma_factor / p_cell_size; fft.init(feature_size.width, feature_size.height, p_num_of_feats, p_num_scales * p_num_angles); - fft.set_window(cosine_window_function_umat(feature_size.width, feature_size.height)); + fft.set_window(cosine_window_function(feature_size.width, feature_size.height).getUMat(cv::ACCESS_RW)); // window weights, i.e. labels cv::Mat gsl(feature_size,CV_32F); @@ -950,20 +950,6 @@ cv::Mat KCF_Tracker::cosine_window_function(int dim1, int dim2) return ret; } -cv::UMat KCF_Tracker::cosine_window_function_umat(int dim1, int dim2) -{ - cv::Mat m1(1, dim1, CV_32FC1), m2(dim2, 1, CV_32FC1); - double N_inv = 1. / (static_cast(dim1) - 1.); - for (int i = 0; i < dim1; ++i) - m1.at(i) = float(0.5 * (1. - std::cos(2. * CV_PI * static_cast(i) * N_inv))); - N_inv = 1. / (static_cast(dim2) - 1.); - for (int i = 0; i < dim2; ++i) - m2.at(i) = float(0.5 * (1. - std::cos(2. * CV_PI * static_cast(i) * N_inv))); - cv::Mat tempMat = m2 * m1; - cv::UMat ret = tempMat.getUMat(cv::ACCESS_RW); - return ret; -} - // Returns sub-window of image input centered at [cx, cy] coordinates), // with size [width, height]. If any pixels are outside of the image, // they will replicate the values at the borders. diff --git a/src/kcf.h b/src/kcf.h index fc2c02d5..76d2b401 100644 --- a/src/kcf.h +++ b/src/kcf.h @@ -189,7 +189,6 @@ class KCF_Tracker cv::Mat circshift(const cv::Mat &patch, int x_rot, int y_rot) const; cv::UMat circshift(const cv::UMat &patch, int x_rot, int y_rot) const; cv::Mat cosine_window_function(int dim1, int dim2); - cv::UMat cosine_window_function_umat(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); From 35ec955b669b45d3fc4de7c35af271c82599640d Mon Sep 17 00:00:00 2001 From: Your Name Date: Thu, 23 Apr 2020 23:25:08 +0200 Subject: [PATCH 106/121] =?UTF-8?q?V=C3=BDpo=C4=8Det=20typu=20MatExpr=20ve?= =?UTF-8?q?=20funkci=20GaussianCorrelation()=20byl=20=C4=8D=C3=A1ste=C4=8D?= =?UTF-8?q?n=C4=9B=20p=C5=99eveden=20do=20GAPI=20implementace?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- src/kcf.cpp | 11 +++++++++-- 1 file changed, 9 insertions(+), 2 deletions(-) diff --git a/src/kcf.cpp b/src/kcf.cpp index 295ed597..c59c6d70 100644 --- a/src/kcf.cpp +++ b/src/kcf.cpp @@ -1050,8 +1050,15 @@ void KCF_Tracker::GaussianCorrelation::operator()(cv::UMat &result, cv::UMat &xf cv::Mat plane = MatUtil::plane(0,ifft_res_Temp); DEBUG_PRINTM(plane); - cv::exp(-1. / (sigma * sigma) * cv::max((xf_sqr_norm + yf_sqr_norm - 2 * MatUtil::plane(0,ifft_res_Temp)) - * numel_xf_inv, 0), plane); + cv::Mat matExpr; + cv::GMat in; + cv::GMat inTemp = cv::gapi::mulC(in, -2); + cv::GMat inTemp2 = cv::gapi::addC(inTemp, xf_sqr_norm + yf_sqr_norm); + cv::GMat out = cv::gapi::mulC(inTemp2, numel_xf_inv); + cv::GComputation getMaxArg(in, out); + getMaxArg.apply(plane,matExpr); + + cv::exp(-1. / (sigma * sigma) * cv::max(matExpr, 0), plane); DEBUG_PRINTM(plane); From 26f62b44900bab41defa276db46711c1441488fa Mon Sep 17 00:00:00 2001 From: Your Name Date: Thu, 23 Apr 2020 23:48:40 +0200 Subject: [PATCH 107/121] =?UTF-8?q?V=C3=BDpo=C4=8Det=20typu=20MatExpr=20ve?= =?UTF-8?q?=20funkci=20train()=20byl=20p=C5=99eveden=20do=20GAPI=20impleme?= =?UTF-8?q?ntace?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- src/kcf.cpp | 14 ++++++++++++-- 1 file changed, 12 insertions(+), 2 deletions(-) diff --git a/src/kcf.cpp b/src/kcf.cpp index c59c6d70..1eb0d1c0 100644 --- a/src/kcf.cpp +++ b/src/kcf.cpp @@ -87,8 +87,18 @@ void KCF_Tracker::train(cv::UMat input_rgb, cv::UMat input_gray, double interp_f DEBUG_PRINT(model->patch_feats); fft.forward_window(model->patch_feats, model->xf, model->temp); DEBUG_PRINTM(model->xf); - model->model_xf.getMat(cv::ACCESS_RW) = (model->model_xf.getMat(cv::ACCESS_RW) * (1. - interp_factor) + - model->xf.getMat(cv::ACCESS_RW) * interp_factor); + + cv::Mat tempModelXf = model->model_xf.getMat(cv::ACCESS_RW); + cv::Mat tempXf = model->xf.getMat(cv::ACCESS_RW); + + cv::GMat in; + cv::GMat in2; + cv::GMat tempIn = cv::gapi::mulC(in, (1. - interp_factor)); + cv::GMat tempIn2 = cv::gapi::mulC(in2, interp_factor); + cv::GMat out = cv::gapi::add(tempIn, tempIn2); + cv::GComputation mulAdd(cv::GIn(in, in2), cv::GOut(out)); + mulAdd.apply(cv::gin(tempModelXf, tempXf), cv::gout(tempModelXf)); + DEBUG_PRINTM(model->model_xf); From 1044aec3b899331d535b279ef041a13d49cf874f Mon Sep 17 00:00:00 2001 From: Your Name Date: Fri, 24 Apr 2020 00:26:29 +0200 Subject: [PATCH 108/121] =?UTF-8?q?Konvertov=C3=A1no=20vol=C3=A1n=C3=AD=20?= =?UTF-8?q?cv::resize()=20ve=20funkci=20get=5Ffeatures()=20na=20GAPI=20imp?= =?UTF-8?q?plementaci?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- src/kcf.cpp | 16 ++++++++++++---- 1 file changed, 12 insertions(+), 4 deletions(-) diff --git a/src/kcf.cpp b/src/kcf.cpp index 1eb0d1c0..1bdac65a 100644 --- a/src/kcf.cpp +++ b/src/kcf.cpp @@ -716,14 +716,18 @@ cv::Mat KCF_Tracker::get_features(cv::Mat &input_rgb, cv::Mat &input_gray, cv::M cv::Mat patch_gray = get_subwindow(input_gray, cx, cy, scaled.width, scaled.height, angle); cv::Mat patch_rgb = get_subwindow(input_rgb, cx, cy, scaled.width, scaled.height, angle); + cv::GMat rszIn; + cv::GMat rszOut; // resize to default size if (scaled.area() > fit_size.area()) { // if we downsample use INTER_AREA interpolation // note: this is just a guess - we may downsample in X and upsample in Y (or vice versa) - cv::resize(patch_gray, patch_gray, fit_size, 0., 0., cv::INTER_AREA); + rszOut = cv::gapi::resize(rszIn, fit_size, 0., 0., cv::INTER_AREA); } else { - cv::resize(patch_gray, patch_gray, fit_size, 0., 0., cv::INTER_LINEAR); + rszOut = cv::gapi::resize(rszIn, fit_size, 0., 0., cv::INTER_LINEAR); } + cv::GComputation resizeFit(rszIn, rszOut); + resizeFit.apply(patch_gray, patch_gray); // get hog(Histogram of Oriented Gradients) features std::vector hog_feat = FHoG::extract(patch_gray, 2, p_cell_size, 9); @@ -732,12 +736,16 @@ cv::Mat KCF_Tracker::get_features(cv::Mat &input_rgb, cv::Mat &input_gray, cv::M std::vector color_feat; if ((m_use_color || m_use_cnfeat) && input_rgb.channels() == 3) { // resize to default size + cv::GMat rszIn2; + cv::GMat rszOut2; if (scaled.area() > (fit_size / p_cell_size).area()) { // if we downsample use INTER_AREA interpolation - cv::resize(patch_rgb, patch_rgb, fit_size / p_cell_size, 0., 0., cv::INTER_AREA); + rszOut2 = cv::gapi::resize(rszIn2, fit_size / p_cell_size, 0., 0., cv::INTER_AREA); } else { - cv::resize(patch_rgb, patch_rgb, fit_size / p_cell_size, 0., 0., cv::INTER_LINEAR); + rszOut2 = cv::gapi::resize(rszIn2, fit_size / p_cell_size, 0., 0., cv::INTER_LINEAR); } + cv::GComputation resizeFitCell(rszIn2, rszOut2); + resizeFitCell.apply(patch_rgb, patch_rgb); } if (dbg_patch) From 15d492335138db76d183cff4501af224bde0265f Mon Sep 17 00:00:00 2001 From: Your Name Date: Sun, 26 Apr 2020 19:16:15 +0200 Subject: [PATCH 109/121] =?UTF-8?q?Funkce=20MatUtil::sum=5Fover=5Fchannels?= =?UTF-8?q?()=20nyn=C3=AD=20pou=C5=BE=C3=ADv=C3=A1=20paraleln=C3=AD=20fore?= =?UTF-8?q?ach().=20-=20GAPI=20nepou=C5=BEito,=20neposkytuje=20n=C3=A1stro?= =?UTF-8?q?je=20pot=C5=99ebn=C3=A9=20ke=20konverzi=20t=C3=A9to=20funkce=20?= =?UTF-8?q?-=20otestov=C3=A1no=20na=20shodu=20v=C3=BDsledk=C5=AF=20-=20ryc?= =?UTF-8?q?hlej=C5=A1=C3=AD=20zpracov=C3=A1n=C3=AD?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- src/kcf.cpp | 18 +++++++++++++++++- src/matutil.h | 38 ++++++++++++++------------------------ 2 files changed, 31 insertions(+), 25 deletions(-) diff --git a/src/kcf.cpp b/src/kcf.cpp index 1bdac65a..40d20770 100644 --- a/src/kcf.cpp +++ b/src/kcf.cpp @@ -153,6 +153,9 @@ void KCF_Tracker::init(cv::UMat &img, const cv::Rect &bbox, int fit_size_x, int // //// cv::Mat_> testComplex = cv::Mat_>(test2); // +// +// cv::UMat testOrig = cv::UMat(2, 2, CV_32FC4); +// cv::Mat test = testOrig.getMat(cv::ACCESS_RW); // test.ptr(0)[0] = float(1); // test.ptr(0)[1] = float(2); // test.ptr(0)[2] = float(3); @@ -161,6 +164,19 @@ void KCF_Tracker::init(cv::UMat &img, const cv::Rect &bbox, int fit_size_x, int // test.ptr(0)[5] = float(6); // test.ptr(0)[6] = float(7); // test.ptr(0)[7] = float(8); +// test.ptr(0)[8] = float(9); +// test.ptr(0)[9] = float(10); +// test.ptr(0)[10] = float(11); +// test.ptr(0)[11] = float(12); +// test.ptr(0)[12] = float(13); +// test.ptr(0)[13] = float(14); +// test.ptr(0)[14] = float(15); +// test.ptr(0)[15] = float(16); +// DEBUG_PRINTM(test); +// cv::UMat test2 = MatUtil::sum_over_channels_foreach(testOrig); +// DEBUG_PRINTM(test2); +// return; +// // test.ptr(1)[0] = float(9); // test.ptr(1)[1] = float(10); // test.ptr(1)[2] = float(11); @@ -1058,7 +1074,7 @@ void KCF_Tracker::GaussianCorrelation::operator()(cv::UMat &result, cv::UMat &xf // ifft2 and sum over 3rd dimension, we dont care about individual channels cv::UMat xyf_sum = MatUtil::sum_over_channels(xyf); - DEBUG_PRINTM(xyf_sum); + DEBUG_PRINTM(xyf_sum); kcf.fft.inverse(xyf_sum, ifft_res); DEBUG_PRINTM(ifft_res); diff --git a/src/matutil.h b/src/matutil.h index d3b44c51..9e836b54 100644 --- a/src/matutil.h +++ b/src/matutil.h @@ -94,36 +94,26 @@ static void set_channel(int idxFrom, int idxTo, cv::UMat &source, cv::UMat &targ * Sum of channel values for each point of input matrix * becomes a new point in the new matrix. **/ -static cv::Mat sum_over_channels(cv::Mat &host) -{ - assert(host.channels() % 2 == 0); - cv::Mat result(host.rows, host.cols, CV_32FC2); - for (int row = 0; row < host.rows; ++row) - for (int col = 0; col < host.cols; ++col){ - std::complex acc = 0; - for (int ch = 0; ch < host.channels() / 2; ++ch){ - acc += host.ptr>(row)[(host.channels() / 2)*col + ch]; - } - result.ptr>(row)[col] = acc; - } - return result; -} static cv::UMat sum_over_channels(cv::UMat &host) { assert(host.channels() % 2 == 0); - cv::UMat result(host.rows, host.cols, CV_32FC2); + assert(host.rows > 0); + assert(host.cols > 0); + cv::Mat tempHost = host.getMat(cv::ACCESS_RW); - cv::Mat tempResult = result.getMat(cv::ACCESS_RW); + cv::Mat result = cv::Mat::zeros(tempHost.rows, tempHost.cols, CV_32FC2); + cv::Mat_< std::complex > cpxMat = cv::Mat_< std::complex >(result); - for (int row = 0; row < host.rows; ++row) - for (int col = 0; col < host.cols; ++col){ - std::complex acc = 0; - for (int ch = 0; ch < host.channels() / 2; ++ch){ - acc += tempHost.ptr>(row)[(host.channels() / 2)*col + ch]; - } - tempResult.ptr>(row)[col] = acc; + cpxMat.forEach([&tempHost](std::complex &c, const int * position) { + std::complex acc = 0; + int rowVal = *position; + int colVal = *(position +1); + for (int ch = 0; ch < tempHost.channels() / 2; ++ch){ + acc += tempHost.ptr>(rowVal)[(tempHost.channels() / 2)*(colVal) + ch]; } - return result; + c = acc; + }); + return result.getUMat(cv::ACCESS_RW); } From b24cbe23b927c7a71f075a8d2f3ce4b11e8806ee Mon Sep 17 00:00:00 2001 From: Your Name Date: Sun, 26 Apr 2020 19:23:04 +0200 Subject: [PATCH 110/121] =?UTF-8?q?Odstran=C4=9Bny=20n=C4=9Bkter=C3=A9=20r?= =?UTF-8?q?edundantn=C3=AD=20cv::Mat=20funkce=20v=20MatUtil?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- src/matutil.h | 16 ---------------- 1 file changed, 16 deletions(-) diff --git a/src/matutil.h b/src/matutil.h index 9e836b54..98c9a55b 100644 --- a/src/matutil.h +++ b/src/matutil.h @@ -73,13 +73,6 @@ static cv::UMat scale(uint scale, cv::UMat &host) { * are next to each other in the internal array (1 pixel = continuous block). * Previous format saved all pixel values of each channel next to each other. **/ -static void set_channel(int idxFrom, int idxTo, cv::Mat &source, cv::Mat &target) -{ - assert(idxTo < target.channels()); - assert(idxFrom < source.channels()); - int from_to[] = { idxFrom,idxTo }; - cv::mixChannels( &source, 1, &target, 1, from_to, 1 ); -} static void set_channel(int idxFrom, int idxTo, cv::UMat &source, cv::UMat &target) { assert(idxTo < target.channels()); @@ -121,15 +114,6 @@ static cv::UMat sum_over_channels(cv::UMat &host) * Extracts two channels from input, and sets them as data of resulting new matrix. * Presumes format where two neighbouring channels of input make one complex value. **/ -static cv::Mat channel_to_cv_mat(int channel_id, cv::Mat &host){ - cv::Mat result(host.rows, host.cols, CV_32FC2); - int from_to[] = { channel_id, 0 }; - cv::mixChannels(&host,1,&result,1,from_to,1); - int from_to2[] = { (channel_id + 1), 1 }; - cv::mixChannels(&host,1,&result,1,from_to2,1); - return result; -} - static cv::UMat channel_to_cv_mat(int channel_id, cv::UMat &host){ cv::UMat result(host.rows, host.cols, CV_32FC2); cv::Mat tempHost = host.getMat(cv::ACCESS_RW); From dfe0d7a581e5ff721aa01077e1b92e8511bfc561 Mon Sep 17 00:00:00 2001 From: Your Name Date: Sun, 26 Apr 2020 19:39:35 +0200 Subject: [PATCH 111/121] =?UTF-8?q?Odstran=C4=9Bny=20n=C4=9Bkter=C3=A9=20r?= =?UTF-8?q?edundantn=C3=AD=20cv::Mat=20funkce=20v=20MatUtil=20(part=202)?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- src/matutil.h | 9 --------- 1 file changed, 9 deletions(-) diff --git a/src/matutil.h b/src/matutil.h index 98c9a55b..50947023 100644 --- a/src/matutil.h +++ b/src/matutil.h @@ -148,9 +148,6 @@ static cv::UMat conj(cv::UMat &host){ /* * Returns result of element wise multiplication between n-channeled and single-channeled complex matrixes **/ -static cv::Mat mul_matn_mat1(cv::Mat &host, cv::Mat &other){ - return matn_mat1_operator([](std::complex &c_lhs, const std::complex &c_rhs) { c_lhs *= c_rhs; }, host, other); -} static cv::UMat mul_matn_mat1(cv::UMat &host, cv::UMat &other){ return matn_mat1_operator([](std::complex &c_lhs, const std::complex &c_rhs) { c_lhs *= c_rhs; }, host, other); } @@ -158,9 +155,6 @@ static cv::UMat mul_matn_mat1(cv::UMat &host, cv::UMat &other){ /* * Returns result of element wise multiplication between two n-channeled complex matrixes **/ -static cv::Mat mul_matn_matn(cv::Mat &host, cv::Mat &other){ - return mat_mat_operator([](std::complex &c_lhs, const std::complex &c_rhs) { c_lhs *= c_rhs; }, host, other); -} static cv::UMat mul_matn_matn(cv::UMat &host, cv::UMat &other){ return mat_mat_operator([](std::complex &c_lhs, const std::complex &c_rhs) { c_lhs *= c_rhs; }, host, other); } @@ -197,9 +191,6 @@ static cv::UMat add_scalar_cpu(cv::UMat &host, const float &val){ /* * Returns result of element wise division between two n-channeled complex matrixes **/ -static cv::Mat divide_matn_matn(cv::Mat &host, cv::Mat &other){ - return mat_mat_operator([](std::complex &c_lhs, const std::complex &c_rhs) { c_lhs /= c_rhs; }, host, other); -} static cv::UMat divide_matn_matn(cv::UMat &host, cv::UMat &other){ return mat_mat_operator([](std::complex &c_lhs, const std::complex &c_rhs) { c_lhs /= c_rhs; }, host, other); } From ad9898f5e4f015f2368c7931a77db32319ed71fe Mon Sep 17 00:00:00 2001 From: Your Name Date: Sun, 26 Apr 2020 21:21:15 +0200 Subject: [PATCH 112/121] =?UTF-8?q?Konvertov=C3=A1na=20funkce=20MatUtil::m?= =?UTF-8?q?ul=5Fmatn=5Fmatn()=20na=20paraleln=C3=AD=20foreach()=20-=20tato?= =?UTF-8?q?=20konverze=20m=C3=A1=20shodn=C3=BD=20v=C3=BDstup=20s=20p=C5=AF?= =?UTF-8?q?vodn=C3=AD=20funkc=C3=AD=20-=20naps=C3=A1na=20tak=C3=A9=20konve?= =?UTF-8?q?rze=20GAPI=20t=C3=A9to=20funkce,=20kter=C3=A1=20v=C5=A1ak=20NEM?= =?UTF-8?q?=C3=81=20shodn=C3=BD=20v=C3=BDstup=20s=20p=C5=AFvodn=C3=AD=20fu?= =?UTF-8?q?nkc=C3=AD,=20ale=20li=C5=A1=C3=AD=20se=20pouze=20na=20imagin?= =?UTF-8?q?=C3=A1rn=C3=ADch=20pozic=C3=ADch,=20a=20pouze=20o=20drobn=C3=A9?= =?UTF-8?q?=20hodnoty=20-=20p=C5=99edpokl=C3=A1d=C3=A1m=20chybu=20knihovny?= =?UTF-8?q?=20GAPI,=20ponech=C3=A1v=C3=A1m=20v=20k=C3=B3du=20pro=20pozd?= =?UTF-8?q?=C4=9Bj=C5=A1=C3=AD=20pou=C5=BEit=C3=AD?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- src/matutil.h | 76 +++++++++++++++++++++++++-------------------------- 1 file changed, 37 insertions(+), 39 deletions(-) diff --git a/src/matutil.h b/src/matutil.h index 50947023..f132a7a4 100644 --- a/src/matutil.h +++ b/src/matutil.h @@ -156,7 +156,43 @@ static cv::UMat mul_matn_mat1(cv::UMat &host, cv::UMat &other){ * Returns result of element wise multiplication between two n-channeled complex matrixes **/ static cv::UMat mul_matn_matn(cv::UMat &host, cv::UMat &other){ - return mat_mat_operator([](std::complex &c_lhs, const std::complex &c_rhs) { c_lhs *= c_rhs; }, host, other); + assert(host.channels() % 2 == 0); + assert(other.channels() == host.channels()); + assert(other.cols == host.cols); + assert(other.rows == host.rows); + + cv::Mat tempHost = host.getMat(cv::ACCESS_RW); + cv::Mat tempOther = other.getMat(cv::ACCESS_RW); + cv::Mat result = cv::Mat::zeros(tempHost.rows, tempHost.cols, tempHost.type()); + cv::Mat_< std::complex > cpxRes = cv::Mat_< std::complex >(result); + cv::Mat_< std::complex > cpxHost = cv::Mat_< std::complex >(tempHost); + cv::Mat_< std::complex > cpxOther = cv::Mat_< std::complex >(tempOther); + + cpxRes.forEach([&cpxHost, &cpxOther](std::complex &c, const int * position) { + int rowVal = *position; + int colVal = *(position +1); + std::complex cpxValHost = cpxHost.ptr>(rowVal)[colVal]; + std::complex cpxValOther = cpxOther.ptr>(rowVal)[colVal]; + c = cpxValHost * cpxValOther; + }); + return result.getUMat(cv::ACCESS_RW); +} + +static cv::UMat mul_matn_matn_gapi(cv::UMat &host, cv::UMat &other){ + cv::Mat temphost = host.getMat(cv::ACCESS_RW); + cv::Mat tempother = other.getMat(cv::ACCESS_RW); + cv::Mat_< std::complex > cpxMatIn = cv::Mat_< std::complex >(temphost); + cv::Mat_< std::complex > cpxMatIn2 = cv::Mat_< std::complex >(tempother); + cv::Mat_< std::complex > cpxMatOut; + + cv::GMat in; + cv::GMat in2; + cv::GMat out = cv::gapi::mul(in, in2); + cv::GComputation ac(in, in2, out); + ac.apply(cpxMatIn, cpxMatIn2, cpxMatOut); + + cv::UMat result = cpxMatOut.getUMat(cv::ACCESS_RW); + return result; } /* @@ -215,25 +251,6 @@ static cv::UMat mat_const_operator(const std::function * Creates copy of the n-channeled matrix, executes supplied function on each element of it, then returns the copy. * No matter which channel, each point of the n-channeled copy will be processed by its corresponding point in the other matrix. **/ -static cv::Mat matn_mat1_operator(void (*op)(std::complex &, const std::complex &), cv::Mat &host, cv::Mat &other){ - assert(host.channels() % 2 == 0); - assert(other.channels() == 2); - assert(other.cols == host.cols); - assert(other.rows == host.rows); - - cv::Mat result = host.clone(); - for (int i = 0; i < result.rows; ++i) { - for (int j = 0; j < result.cols; ++j){ - for (int k = 0; k < result.channels() / 2 ; ++k){ - std::complex cpxValOther = other.ptr>(i)[j]; - std::complex cpxValHost = result.ptr>(i)[(result.channels() / 2)*j + k]; - op(cpxValHost, cpxValOther); - result.ptr>(i)[(result.channels() / 2)*j + k] = cpxValHost; - } - } - } - return result; -} static cv::UMat matn_mat1_operator(void (*op)(std::complex &, const std::complex &), cv::UMat &host, cv::UMat &other){ assert(host.channels() % 2 == 0); assert(other.channels() == 2); @@ -263,25 +280,6 @@ static cv::UMat matn_mat1_operator(void (*op)(std::complex &, const std:: * Every value in the first matrix will be processed with its corresponding value in the other matrix, * both channel and coordinate wise. **/ -static cv::Mat mat_mat_operator(void (*op)(std::complex &, const std::complex &), cv::Mat &host, cv::Mat &other){ - assert(host.channels() % 2 == 0); - assert(other.channels() == host.channels()); - assert(other.cols == host.cols); - assert(other.rows == host.rows); - - cv::Mat result = host.clone(); - for (int i = 0; i < result.rows; ++i) { - for (int j = 0; j < result.cols; ++j){ - for (int k = 0; k < result.channels() / 2 ; ++k){ - std::complex cpxValHost = result.ptr>(i)[(result.channels() / 2)*j + k]; - std::complex cpxValOther = other.ptr>(i)[(other.channels() / 2)*j + k]; - op(cpxValHost, cpxValOther); - result.ptr>(i)[(result.channels() / 2)*j + k] = cpxValHost; - } - } - } - return result; -} static cv::UMat mat_mat_operator(void (*op)(std::complex &, const std::complex &), cv::UMat &host, cv::UMat &other){ assert(host.channels() % 2 == 0); assert(other.channels() == host.channels()); From 9e3fc1b1d88d6ec8f50fede2438db9825dbb3c62 Mon Sep 17 00:00:00 2001 From: Your Name Date: Sun, 26 Apr 2020 21:52:06 +0200 Subject: [PATCH 113/121] =?UTF-8?q?Konvertov=C3=A1na=20funkce=20MatUtil::d?= =?UTF-8?q?ivide=5Fmatn=5Fmatn()=20na=20paraleln=C3=AD=20foreach()=20-=20h?= =?UTF-8?q?lavn=C3=AD=20t=C4=9Blo=20t=C3=A9to=20funkce=20a=20mul=5Fmatn=5F?= =?UTF-8?q?matn()=20p=C5=99esunuto=20do=20mat=5Fmat=5Foperator()?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- src/matutil.h | 53 +++++++++++++++++---------------------------------- 1 file changed, 18 insertions(+), 35 deletions(-) diff --git a/src/matutil.h b/src/matutil.h index f132a7a4..4fcf6d8f 100644 --- a/src/matutil.h +++ b/src/matutil.h @@ -156,26 +156,7 @@ static cv::UMat mul_matn_mat1(cv::UMat &host, cv::UMat &other){ * Returns result of element wise multiplication between two n-channeled complex matrixes **/ static cv::UMat mul_matn_matn(cv::UMat &host, cv::UMat &other){ - assert(host.channels() % 2 == 0); - assert(other.channels() == host.channels()); - assert(other.cols == host.cols); - assert(other.rows == host.rows); - - cv::Mat tempHost = host.getMat(cv::ACCESS_RW); - cv::Mat tempOther = other.getMat(cv::ACCESS_RW); - cv::Mat result = cv::Mat::zeros(tempHost.rows, tempHost.cols, tempHost.type()); - cv::Mat_< std::complex > cpxRes = cv::Mat_< std::complex >(result); - cv::Mat_< std::complex > cpxHost = cv::Mat_< std::complex >(tempHost); - cv::Mat_< std::complex > cpxOther = cv::Mat_< std::complex >(tempOther); - - cpxRes.forEach([&cpxHost, &cpxOther](std::complex &c, const int * position) { - int rowVal = *position; - int colVal = *(position +1); - std::complex cpxValHost = cpxHost.ptr>(rowVal)[colVal]; - std::complex cpxValOther = cpxOther.ptr>(rowVal)[colVal]; - c = cpxValHost * cpxValOther; - }); - return result.getUMat(cv::ACCESS_RW); + return mat_mat_operator([](std::complex &c_lhs, const std::complex &c_rhs) { c_lhs *= c_rhs; }, host, other); } static cv::UMat mul_matn_matn_gapi(cv::UMat &host, cv::UMat &other){ @@ -280,26 +261,28 @@ static cv::UMat matn_mat1_operator(void (*op)(std::complex &, const std:: * Every value in the first matrix will be processed with its corresponding value in the other matrix, * both channel and coordinate wise. **/ -static cv::UMat mat_mat_operator(void (*op)(std::complex &, const std::complex &), cv::UMat &host, cv::UMat &other){ +static cv::UMat mat_mat_operator(const std::function &, std::complex &)> &op, cv::UMat &host, cv::UMat &other){ assert(host.channels() % 2 == 0); assert(other.channels() == host.channels()); assert(other.cols == host.cols); assert(other.rows == host.rows); - cv::UMat result = host.clone(); - cv::Mat tempResult = result.getMat(cv::ACCESS_RW); - cv::Mat tempOther = other.getMat(cv::ACCESS_READ); - for (int i = 0; i < result.rows; ++i) { - for (int j = 0; j < result.cols; ++j){ - for (int k = 0; k < result.channels() / 2 ; ++k){ - std::complex cpxValHost = tempResult.ptr>(i)[(tempResult.channels() / 2)*j + k]; - std::complex cpxValOther = tempOther.ptr>(i)[(tempOther.channels() / 2)*j + k]; - op(cpxValHost, cpxValOther); - tempResult.ptr>(i)[(tempResult.channels() / 2)*j + k] = cpxValHost; - } - } - } - return result; + cv::Mat tempHost = host.getMat(cv::ACCESS_RW); + cv::Mat tempOther = other.getMat(cv::ACCESS_RW); + cv::Mat result = cv::Mat::zeros(tempHost.rows, tempHost.cols, tempHost.type()); + cv::Mat_< std::complex > cpxRes = cv::Mat_< std::complex >(result); + cv::Mat_< std::complex > cpxHost = cv::Mat_< std::complex >(tempHost); + cv::Mat_< std::complex > cpxOther = cv::Mat_< std::complex >(tempOther); + + cpxRes.forEach([&cpxHost, &cpxOther, &op](std::complex &c, const int * position) { + int rowVal = *position; + int colVal = *(position +1); + std::complex cpxValHost = cpxHost.ptr>(rowVal)[colVal]; + std::complex cpxValOther = cpxOther.ptr>(rowVal)[colVal]; + op(cpxValHost, cpxValOther); + c = cpxValHost; + }); + return result.getUMat(cv::ACCESS_RW); } }; From 51f5d0275700dd5f38209850bd87194e96c6651f Mon Sep 17 00:00:00 2001 From: Your Name Date: Sun, 26 Apr 2020 23:11:01 +0200 Subject: [PATCH 114/121] =?UTF-8?q?KONE=C4=8CN=C3=81=20KONVERZE=20NA=20IMP?= =?UTF-8?q?LEMENTACI=20cv::GMat.=20-=20funkce=20mul=5Fmatn=5Fmat1()=20byla?= =?UTF-8?q?=20jako=20posledn=C3=AD=20konvertov=C3=A1na=20na=20paraleln?= =?UTF-8?q?=C3=AD=20foreach()=20-=20bohu=C5=BEel,=20GAPI=20ve=20verzi=20Op?= =?UTF-8?q?enCV=204.1.1=20nen=C3=AD=20schopn=C3=A1=20spr=C3=A1vn=C4=9B=20p?= =?UTF-8?q?racovat=20s=20maticemi=20obsahuj=C3=ADc=C3=ADmi=20komplexn?= =?UTF-8?q?=C3=AD=20=C4=8D=C3=ADsla=20-=20GAPI=20byla=20implementov=C3=A1n?= =?UTF-8?q?a=20na=20konverz=C3=ADch=20barevn=C3=A9ho=20form=C3=A1tu,=20kon?= =?UTF-8?q?verz=C3=ADch=20typu=20matic,=20zm=C4=9Bny=20velikosti=20a=20kla?= =?UTF-8?q?sick=C3=BDch=20matematick=C3=BDch=20v=C3=BDrazech=20-=20GAPI=20?= =?UTF-8?q?nebyla=20implementov=C3=A1na=20z=20v=C4=9Bt=C5=A1=C3=AD=20?= =?UTF-8?q?=C4=8D=C3=A1sti=20na=20funkc=C3=ADch=20MatUtil.=20Tam=20kde=20t?= =?UTF-8?q?o=20=C5=A1lo=20byly=20vytvo=C5=99eny=20zakomentovan=C3=A9=20fun?= =?UTF-8?q?kce=20pou=C5=BE=C3=ADvaj=C3=ADc=C3=AD=20GAPI,=20kter=C3=A9=20v?= =?UTF-8?q?=C5=A1ak=20zat=C3=ADm=20nebudou=20spolehliv=C4=9B=20vykazovat?= =?UTF-8?q?=20spr=C3=A1vn=C3=A9=20v=C3=BDstupy=20(dokud=20nebude=20p=C5=99?= =?UTF-8?q?id=C3=A1na=20oprava=20OpenCV)=20-=20Funkce=20MatUtil=20byly=20m?= =?UTF-8?q?=C3=ADsto=20toho=20zrychleny=20implementac=C3=AD=20cv::Mat.fore?= =?UTF-8?q?ach(),=20kter=C3=A1=20pou=C5=BE=C3=ADv=C3=A1=20paraleln=C3=AD?= =?UTF-8?q?=20zpracov=C3=A1n=C3=AD=20dat?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit - Testování programu ukázalo, že aplikace je nyní opravdu zřetelně rychlejší --- src/matutil.h | 122 ++++++++++++++++++++++++++++++-------------------- 1 file changed, 74 insertions(+), 48 deletions(-) diff --git a/src/matutil.h b/src/matutil.h index 4fcf6d8f..a985573c 100644 --- a/src/matutil.h +++ b/src/matutil.h @@ -159,52 +159,57 @@ static cv::UMat mul_matn_matn(cv::UMat &host, cv::UMat &other){ return mat_mat_operator([](std::complex &c_lhs, const std::complex &c_rhs) { c_lhs *= c_rhs; }, host, other); } -static cv::UMat mul_matn_matn_gapi(cv::UMat &host, cv::UMat &other){ - cv::Mat temphost = host.getMat(cv::ACCESS_RW); - cv::Mat tempother = other.getMat(cv::ACCESS_RW); - cv::Mat_< std::complex > cpxMatIn = cv::Mat_< std::complex >(temphost); - cv::Mat_< std::complex > cpxMatIn2 = cv::Mat_< std::complex >(tempother); - cv::Mat_< std::complex > cpxMatOut; - - cv::GMat in; - cv::GMat in2; - cv::GMat out = cv::gapi::mul(in, in2); - cv::GComputation ac(in, in2, out); - ac.apply(cpxMatIn, cpxMatIn2, cpxMatOut); - - cv::UMat result = cpxMatOut.getUMat(cv::ACCESS_RW); - return result; -} - /* - * Returns result of element wise addition to complex matrix + * NOT YET IMPLEMENTED IN OPENCV 4.1.1 + * Same result as mul_matn_matn(), but uses GPU instead of CPU for computation **/ -static cv::UMat add_scalar(cv::UMat &host, const float &val){ - cv::Mat tempMat = host.getMat(cv::ACCESS_RW); - cv::Mat_< std::complex > cpxMatIn = cv::Mat_< std::complex >(tempMat); - cv::Mat_< std::complex > cpxMatOut; - - cv::GMat in; - cv::GMat out = cv::gapi::addC(in,val); - cv::GComputation ac(in, out); - ac.apply(cpxMatIn, cpxMatOut); - - cv::UMat result = cpxMatOut.getUMat(cv::ACCESS_RW); - return result; -} +//static cv::UMat mul_matn_matn_gapi(cv::UMat &host, cv::UMat &other){ +// cv::Mat temphost = host.getMat(cv::ACCESS_RW); +// cv::Mat tempother = other.getMat(cv::ACCESS_RW); +// cv::Mat_< std::complex > cpxMatIn = cv::Mat_< std::complex >(temphost); +// cv::Mat_< std::complex > cpxMatIn2 = cv::Mat_< std::complex >(tempother); +// cv::Mat_< std::complex > cpxMatOut; +// +// cv::GMat in; +// cv::GMat in2; +// cv::GMat out = cv::gapi::mul(in, in2); +// cv::GComputation ac(in, in2, out); +// ac.apply(cpxMatIn, cpxMatIn2, cpxMatOut); +// +// cv::UMat result = cpxMatOut.getUMat(cv::ACCESS_RW); +// return result; +//} /* - * Returns result of element wise addition to complex matrix. - * Produces same result as add_scalar() with great speed, but uses parallel processing through CPU instead of GPU. - * Left in the code to compare its speed against GAPI implementation. + * Returns result of element wise addition to complex matrix **/ -static cv::UMat add_scalar_cpu(cv::UMat &host, const float &val){ +static cv::UMat add_scalar(cv::UMat &host, const float &val){ return mat_const_operator([&val](std::complex &c, const int * position) { c += val; (void)position; }, host); } +/* + * WARNING: returns correct output, but relies on unintended functionality + * of OpenCV 4.1.1 (usually cant process complex numbers) + * Same result as add_scalar(), but uses GPU instead of CPU for computation +**/ +//static cv::UMat add_scalar_gapi(cv::UMat &host, const float &val){ +// cv::Mat tempMat = host.getMat(cv::ACCESS_RW); +// cv::Mat_< std::complex > cpxMatIn = cv::Mat_< std::complex >(tempMat); +// cv::Mat_< std::complex > cpxMatOut; +// +// cv::GMat in; +// cv::GMat out = cv::gapi::addC(in,val); +// cv::GComputation ac(in, out); +// ac.apply(cpxMatIn, cpxMatOut); +// +// cv::UMat result = cpxMatOut.getUMat(cv::ACCESS_RW); +// return result; +//} + + /* * Returns result of element wise division between two n-channeled complex matrixes **/ @@ -212,6 +217,27 @@ static cv::UMat divide_matn_matn(cv::UMat &host, cv::UMat &other){ return mat_mat_operator([](std::complex &c_lhs, const std::complex &c_rhs) { c_lhs /= c_rhs; }, host, other); } +/* + * NOT YET IMPLEMENTED IN OPENCV 4.1.1 + * Same result as divide_matn_matn(), but uses GPU instead of CPU for computation +**/ +//static cv::UMat divide_matn_matn_gapi(cv::UMat &host, cv::UMat &other){ +// cv::Mat temphost = host.getMat(cv::ACCESS_RW); +// cv::Mat tempother = other.getMat(cv::ACCESS_RW); +// cv::Mat_< std::complex > cpxMatIn = cv::Mat_< std::complex >(temphost); +// cv::Mat_< std::complex > cpxMatIn2 = cv::Mat_< std::complex >(tempother); +// cv::Mat_< std::complex > cpxMatOut; +// +// cv::GMat in; +// cv::GMat in2; +// cv::GMat out = cv::gapi::div(in,in2, 1.0); +// cv::GComputation ac(in, in2, out); +// ac.apply(cpxMatIn, cpxMatIn2, cpxMatOut); +// +// cv::UMat result = cpxMatOut.getUMat(cv::ACCESS_RW); +// return result; +//} + /* * Helper function to iterate through an input complex matrix. * Creates copy of the matrix, executes supplied function on each element, then returns the copy. @@ -238,20 +264,20 @@ static cv::UMat matn_mat1_operator(void (*op)(std::complex &, const std:: assert(other.cols == host.cols); assert(other.rows == host.rows); - cv::UMat result = host.clone(); - cv::Mat tempResult = result.getMat(cv::ACCESS_RW); - cv::Mat tempOther = other.getMat(cv::ACCESS_READ); - for (int i = 0; i < result.rows; ++i) { - for (int j = 0; j < result.cols; ++j){ - for (int k = 0; k < result.channels() / 2 ; ++k){ - std::complex cpxValOther = tempOther.ptr>(i)[j]; - std::complex cpxValHost = tempResult.ptr>(i)[(tempResult.channels() / 2)*j + k]; - op(cpxValHost, cpxValOther); - tempResult.ptr>(i)[(tempResult.channels() / 2)*j + k] = cpxValHost; - } + cv::Mat tempHost = host.getMat(cv::ACCESS_RW); + cv::Mat result = cv::Mat::zeros(tempHost.rows, tempHost.cols, tempHost.type()); + cv::Mat_< std::complex > cpxMat = cv::Mat_< std::complex >(other.getMat(cv::ACCESS_RW)); + + cpxMat.forEach([&tempHost, &result, &op](std::complex &c, const int * position) { + int rowVal = *position; + int colVal = *(position +1); + for (int k = 0; k < result.channels() / 2 ; ++k){ + std::complex cpxValHost = tempHost.ptr>(rowVal)[(tempHost.channels() / 2)*colVal + k]; + op(cpxValHost,c); + result.ptr>(rowVal)[(result.channels() / 2)*colVal + k] = cpxValHost; } - } - return result; + }); + return result.getUMat(cv::ACCESS_RW); } From d6d756afcca828fbc0e9651ab8a6e918e101d6ef Mon Sep 17 00:00:00 2001 From: Your Name Date: Wed, 29 Apr 2020 21:32:35 +0200 Subject: [PATCH 115/121] =?UTF-8?q?Dokon=C4=8Dena=20konverze=20Fourierov?= =?UTF-8?q?=C3=BDch=20transformac=C3=AD=20v=20fft=5Fopencv.cpp=20-=20Ke=20?= =?UTF-8?q?konverzi=20pou=C5=BEit=20Kernel=20API,=20v=C5=A1e=20implementov?= =?UTF-8?q?=C3=A1no=20ve=20stejn=C3=A9m=20souboru=20-=20Implementace=20Ker?= =?UTF-8?q?nel=20API=20opat=C5=99ena=20koment=C3=A1=C5=99i=20ohledn=C4=9B?= =?UTF-8?q?=20syntaxe=20a=20fungov=C3=A1n=C3=AD=20-=20P=C5=AFvodn=C3=AD=20?= =?UTF-8?q?funkce=20zachov=C3=A1ny=20s=20postfixem=20"=5Fcpu"=20za=20jejic?= =?UTF-8?q?h=20jm=C3=A9nem=20-=20Nov=C3=A9=20funkce=20pou=C5=BE=C3=ADvaj?= =?UTF-8?q?=C3=AD=20op=C4=9Bt=20cv::dft(),=20ale=20v=20kontextu=20GAPI=20-?= =?UTF-8?q?=20M=C4=9B=C5=99en=C3=AD=20bohu=C5=BEel=20vykazuj=C3=AD=202=20a?= =?UTF-8?q?=C5=BE=203=20n=C3=A1sobn=C3=A9=20zpomalen=C3=AD=20v=C5=A1ech=20?= =?UTF-8?q?upraven=C3=BDch=20funkc=C3=AD?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- src/fft_opencv.cpp | 155 +++++++++++++++++++++++++++++++++++++++++++-- src/fft_opencv.h | 4 ++ src/kcf.cpp | 5 ++ 3 files changed, 157 insertions(+), 7 deletions(-) diff --git a/src/fft_opencv.cpp b/src/fft_opencv.cpp index c0014333..0fa5d227 100644 --- a/src/fft_opencv.cpp +++ b/src/fft_opencv.cpp @@ -1,6 +1,76 @@ #include "fft_opencv.h" #include "matutil.h" #include "debug.h" +#include +#include +#include +#include + + +// Declared interface of GAPI function named GDft, +// to be later implemented by custom code to perform Fourier transformation. +// +// Implementation of function outMeta() is required by Kernel API, +// and its purpose is to describe input and output data of the function to be implemented. +// +// Matrices are accepted and returned as metadata type cv::GMatDesc, +// which describe these matrices. +G_TYPED_KERNEL(GDft, + , + "org.opencv2.core.dft_gapi") +{ + static cv::GMatDesc // output type of function, descriptor of output GMat + outMeta(cv::GMatDesc in, // argument of function, descriptor of input GMat + int flags // argument of function, flag to be used in cv::dft() + ) + { + // This describes output of the custom function, + // specifically that it should be the same as input, but with 1 or 2 channels. + if (flags == cv::DFT_COMPLEX_OUTPUT){ + return in.withType(CV_32F, 2); + } + return in.withType(CV_32F, 1); + } +}; + +// This is implementation of interface GDft, stored in kernel named GCPUDft +// This function uses cv::dft() function to achieve the same result in GAPI context. +// +// Unfortunately, cv::dft() changes address of inner pointer in the output matrix, +// which triggers memory reallocation error in Kernel API. +// +// To avoid the problem, it is required to either use function that +// does not reallocate inner pointer of the output matrix, or do the operation on empty clone, +// and then replace the values in the original. +// +// For now, cv::Mat.foreach() will be used to more efficiently implement the latter of these solutions. +GAPI_OCV_KERNEL(GCPUDft, GDft) +{ + static void + run(const cv::Mat &in, // in - derived from GMat + const int flags, + cv::Mat &out) // out - derived from GMat (retval) + { + cv::Mat cpyMat = cv::Mat::zeros(out.rows, out.cols, out.type()); + cv::dft(in, cpyMat, flags); + + if (flags == cv::DFT_COMPLEX_OUTPUT){ + cv::Mat_< std::complex > cpxCopyMat = cv::Mat_< std::complex >(cpyMat); + cv::Mat_< std::complex > cpxOutMat = cv::Mat_< std::complex >(out); + cpxCopyMat.forEach([&cpxOutMat](std::complex &c, const int * position) { + int rowVal = *position; + int colVal = *(position +1); + cpxOutMat.ptr>(rowVal)[colVal] = c; + }); + } else { + cpyMat.forEach([&out](float &c, const int * position) { + int rowVal = *position; + int colVal = *(position +1); + out.ptr(rowVal)[colVal] = c; + }); + } + } +}; void FftOpencv::init(unsigned width, unsigned height, unsigned num_of_feats, unsigned num_of_scales) { @@ -13,15 +83,31 @@ void FftOpencv::set_window(const cv::UMat &window) m_window = window; } -void FftOpencv::forward(const cv::UMat &real_input, cv::UMat &complex_result) +void FftOpencv::forward_cpu(const cv::UMat &real_input, cv::UMat &complex_result) { Fft::forward(real_input, complex_result); - + cv::dft(real_input, complex_result, cv::DFT_COMPLEX_OUTPUT); } -// Real and imag parts of complex elements from previous format are represented by 2 neighbouring channels. -void FftOpencv::forward_window(cv::UMat &feat, cv::UMat &complex_result, cv::UMat &temp) +void FftOpencv::forward(const cv::UMat &real_input, cv::UMat &complex_result) +{ + Fft::forward(real_input, complex_result); + + cv::Mat inputMat = real_input.getMat(cv::ACCESS_RW); + cv::Mat outputMat = complex_result.getMat(cv::ACCESS_RW); + + cv::GMat in; + cv::GMat out; + out = GDft::on(in, cv::DFT_COMPLEX_OUTPUT); + cv::GComputation fourierFwd(in, out); + cv::gapi::GKernelPackage kernelPkg = cv::gapi::GKernelPackage(); + kernelPkg.include(); + fourierFwd.apply(inputMat, outputMat, cv::compile_args(kernelPkg)); +} + +// Real and imag parts of complex elements from previous ComplexMat format are represented by 2 neighbouring channels. +void FftOpencv::forward_window_cpu(cv::UMat &feat, cv::UMat &complex_result, cv::UMat &temp) { Fft::forward_window(feat, complex_result, temp); (void) temp; @@ -36,16 +122,71 @@ void FftOpencv::forward_window(cv::UMat &feat, cv::UMat &complex_result, cv::UMa } } -void FftOpencv::inverse(cv::UMat &complex_input, cv::UMat &real_result) +void FftOpencv::forward_window(cv::UMat &feat, cv::UMat &complex_result, cv::UMat &temp) +{ + Fft::forward_window(feat, complex_result, temp); + (void) temp; + + cv::GMat in; + cv::GMat out; + out = GDft::on(in, cv::DFT_COMPLEX_OUTPUT); + cv::GComputation fourierFwdWin(in, out); + cv::gapi::GKernelPackage kernelPkg = cv::gapi::GKernelPackage(); + kernelPkg.include(); + + cv::Mat matComplex_res; + cv::UMat channel; + cv::Mat matChannel; + cv::UMat complex_res; + for (uint i = 0; i < uint(feat.size[0]); ++i) { + for (uint j = 0; j < uint(feat.size[1]); ++j) { + channel = MatUtil::plane(i, j, feat); + matChannel = channel.getMat(cv::ACCESS_RW).mul(m_window); + fourierFwdWin.apply(matChannel, matComplex_res, cv::compile_args(kernelPkg)); + complex_res = matComplex_res.getUMat(cv::ACCESS_RW); + MatUtil::set_channel(int(0), int(2*j), complex_res, complex_result); + MatUtil::set_channel(int(1), int(2*j+1), complex_res, complex_result); + } + } +} + +void FftOpencv::inverse_cpu(cv::UMat &complex_input, cv::UMat &real_result) { Fft::inverse(complex_input, real_result); assert(complex_input.channels() % 2 == 0); + cv::UMat inputChannel; + cv::UMat target; for (uint i = 0; i < uint(complex_input.channels() / 2); ++i) { - cv::UMat inputChannel = MatUtil::channel_to_cv_mat(i*2, complex_input); // extract input channel matrix - cv::UMat target = MatUtil::plane(i, real_result); // select output plane + inputChannel = MatUtil::channel_to_cv_mat(i*2, complex_input); // extract input channel matrix + target = MatUtil::plane(i, real_result); // select output plane cv::dft(inputChannel, target, cv::DFT_INVERSE | cv::DFT_REAL_OUTPUT | cv::DFT_SCALE); } } +void FftOpencv::inverse(cv::UMat &complex_input, cv::UMat &real_result) +{ + Fft::inverse(complex_input, real_result); + + cv::GMat in; + cv::GMat out; + out = GDft::on(in, cv::DFT_INVERSE | cv::DFT_REAL_OUTPUT | cv::DFT_SCALE); + cv::GComputation fourierInv(in, out); + cv::gapi::GKernelPackage kernelPkg = cv::gapi::GKernelPackage(); + kernelPkg.include(); + + cv::UMat inputChannel; + cv::UMat target; + cv::Mat matInputChannel; + cv::Mat matTarget; + assert(complex_input.channels() % 2 == 0); + for (uint i = 0; i < uint(complex_input.channels() / 2); ++i) { + inputChannel = MatUtil::channel_to_cv_mat(i*2, complex_input); // extract input channel matrix + target = MatUtil::plane(i, real_result); // select output plane + matInputChannel = inputChannel.getMat(cv::ACCESS_RW); + matTarget = target.getMat(cv::ACCESS_RW); + fourierInv.apply(matInputChannel, matTarget, cv::compile_args(kernelPkg)); + } +} + FftOpencv::~FftOpencv() {} diff --git a/src/fft_opencv.h b/src/fft_opencv.h index b9f87e04..848e5b60 100644 --- a/src/fft_opencv.h +++ b/src/fft_opencv.h @@ -12,6 +12,10 @@ class FftOpencv : public Fft void forward(const cv::UMat &real_input, cv::UMat &complex_result); void forward_window(cv::UMat &feat, cv::UMat &complex_result, cv::UMat &temp); void inverse(cv::UMat &complex_input, cv::UMat &real_result); + + void forward_cpu(const cv::UMat &real_input, cv::UMat &complex_result); + void forward_window_cpu(cv::UMat &feat, cv::UMat &complex_result, cv::UMat &temp); + void inverse_cpu(cv::UMat &complex_input, cv::UMat &real_result); ~FftOpencv(); private: cv::UMat m_window; diff --git a/src/kcf.cpp b/src/kcf.cpp index 40d20770..6593c3f7 100644 --- a/src/kcf.cpp +++ b/src/kcf.cpp @@ -12,6 +12,7 @@ #include #include #include +#include #ifdef OPENMP #include @@ -154,6 +155,10 @@ void KCF_Tracker::init(cv::UMat &img, const cv::Rect &bbox, int fit_size_x, int //// cv::Mat_> testComplex = cv::Mat_>(test2); // // +// double time_profile_counter = cv::getCPUTickCount(); +// time_profile_counter = cv::getCPUTickCount() - time_profile_counter; +// std::cout << " Speed : " << time_profile_counter/((double)cvGetTickFrequency()*1000) << "ms." << std::endl; +// // cv::UMat testOrig = cv::UMat(2, 2, CV_32FC4); // cv::Mat test = testOrig.getMat(cv::ACCESS_RW); // test.ptr(0)[0] = float(1); From 964f2588d6d63481b2a7ab4e69582411e795660a Mon Sep 17 00:00:00 2001 From: Your Name Date: Thu, 30 Apr 2020 00:33:48 +0200 Subject: [PATCH 116/121] =?UTF-8?q?Funkce=20Fftw::forward()=20byla=20konve?= =?UTF-8?q?rtov=C3=A1na=20na=20GAPI?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- src/fft_fftw.cpp | 109 ++++++++++++++++++++++++++++++++++++++++++++++- src/fft_fftw.h | 2 + 2 files changed, 109 insertions(+), 2 deletions(-) diff --git a/src/fft_fftw.cpp b/src/fft_fftw.cpp index 923b1a72..afe56bb8 100644 --- a/src/fft_fftw.cpp +++ b/src/fft_fftw.cpp @@ -6,6 +6,91 @@ #include #endif +#include +#include +#include +#include + + +// Declared interface of GAPI function named GDft, +// to be later implemented by custom code to perform Fourier transformation. +// +// Implementation of function outMeta() is required by Kernel API, +// and its purpose is to describe input and output data of the function to be implemented. +// +// Matrices are accepted and returned as metadata type cv::GMatDesc, +// which describe these matrices. +#ifdef BIG_BATCH +G_TYPED_KERNEL(GFftw, + , + "org.opencv2.core.fftw_gapi") +#else +G_TYPED_KERNEL(GFftw, + , + "org.opencv2.core.fftw_gapi") +#endif +{ + static cv::GMatDesc // output type of function, descriptor of output GMat + outMeta(cv::GMatDesc in, // argument of function, descriptor of input GMat + fftwf_plan /*planA*/, // argument of function, plan of transformation to execute + #ifdef BIG_BATCH + fftwf_plan /*planB*/, // argument of function, plan of transformation to execute in case of BIG_BATCH + #endif + int flag, // argument of function, 1=forward, 2=forward_window, 3=inverse + cv::Size size + ) + { + // This describes output of the custom function, + // specifically that it should be the same as input, but with 1 or 2 channels, + // and with supplied size. + if (flag == 1 || flag == 2){ + return in.withSize(size).withType(CV_32F, 2); + } + return in.withSize(size).withType(CV_32F, 1); + } +}; + +GAPI_OCV_KERNEL(GCPUFftw, GFftw) +{ + static void + run(const cv::Mat &in, // in - derived from GMat + const fftwf_plan &planA, + #ifdef BIG_BATCH + const fftwf_plan &planB, + #endif + const int flag, + cv::Size size, + cv::Mat &out) // out - derived from GMat (retval) + { + (void)size; + switch (flag){ + case 1: + if (in.dims == 2) + DEBUG_PRINTM(in); + DEBUG_PRINTM(out); + fftwf_execute_dft_r2c(planA, reinterpret_cast(in.data), + reinterpret_cast(out.ptr>(0))); + DEBUG_PRINTM(in); + DEBUG_PRINTM(out); + #ifdef BIG_BATCH + else + fftwf_execute_dft_r2c(planB, reinterpret_cast(in.data), + reinterpret_cast(out.ptr>(0))); + #endif + break; + case 2: + + break; + default: // flag == 3 + + break; + } + + } +}; + + + Fftw::Fftw(){} fftwf_plan Fftw::create_plan_fwd(uint howmany) const @@ -78,7 +163,7 @@ void Fftw::set_window(const cv::UMat &window) m_window = window; } -void Fftw::forward(const cv::UMat &real_input, cv::UMat &complex_result) +void Fftw::forward_cpu(const cv::UMat &real_input, cv::UMat &complex_result) { Fft::forward(real_input, complex_result); @@ -92,6 +177,26 @@ void Fftw::forward(const cv::UMat &real_input, cv::UMat &complex_result) #endif } +void Fftw::forward(const cv::UMat &real_input, cv::UMat &complex_result) +{ + Fft::forward(real_input, complex_result); + + cv::Mat inputMat = real_input.getMat(cv::ACCESS_RW); + cv::Mat outputMat = complex_result.getMat(cv::ACCESS_RW); + + cv::GMat in; + cv::GMat out; + out = GFftw::on(in, plan_f, + #ifdef BIG_BATCH + plan_f_all_scales, + #endif + 1, cv::Size(outputMat.cols,outputMat.rows)); + cv::GComputation fourierFwd(in, out); + cv::gapi::GKernelPackage kernelPkg = cv::gapi::GKernelPackage(); + kernelPkg.include(); + fourierFwd.apply(inputMat, outputMat, cv::compile_args(kernelPkg)); +} + void Fftw::forward_window(cv::UMat &feat, cv::UMat & complex_result, cv::UMat &temp) { Fft::forward_window(feat, complex_result, temp); @@ -128,7 +233,7 @@ void Fftw::inverse(cv::UMat &complex_input, cv::UMat &real_result) else fftwf_execute_dft_c2r(plan_i_all_scales, in, out); #endif - real_result *= 1.0 / (m_width * m_height); + real_result.getMat(cv::ACCESS_RW) *= 1.0 / (m_width * m_height); } Fftw::~Fftw() diff --git a/src/fft_fftw.h b/src/fft_fftw.h index c8b8829a..3bf0f104 100644 --- a/src/fft_fftw.h +++ b/src/fft_fftw.h @@ -18,6 +18,8 @@ class Fftw : public Fft void forward(const cv::UMat &real_input, cv::UMat &complex_result); void forward_window(cv::UMat &feat, cv::UMat & complex_result, cv::UMat &temp); void inverse(cv::UMat &complex_input, cv::UMat &real_result); + + void forward_cpu(const cv::UMat &real_input, cv::UMat &complex_result); ~Fftw(); protected: From 041c2faf28d0e8fc60b23c333dfe1c29a89bea84 Mon Sep 17 00:00:00 2001 From: Your Name Date: Thu, 30 Apr 2020 17:31:48 +0200 Subject: [PATCH 117/121] =?UTF-8?q?Funkce=20Fftw::forward=5Fwindow()=20byl?= =?UTF-8?q?a=20konvertov=C3=A1na=20na=20GAPI=20-=20z=20n=C4=9Bjak=C3=A9ho?= =?UTF-8?q?=20d=C5=AFvodu=20doch=C3=A1z=C3=AD=20ke=20korupci=20dat=20ve=20?= =?UTF-8?q?v=C5=A1ech=20Fourierov=C3=BDch=20funkc=C3=ADch,=20a=20to=20v?= =?UTF-8?q?=C4=8Detn=C4=9B=20p=C5=AFvodn=C3=AD=20implementace=20-=20po=20p?= =?UTF-8?q?=C5=99epnut=C3=AD=20na=20implementaci=20OpenCV=20program=20fung?= =?UTF-8?q?uje=20bez=20probl=C3=A9m=C5=AF=20-=20p=C5=99edpokl=C3=A1d=C3=A1?= =?UTF-8?q?m=20jedno=20z=20n=C3=A1sleduj=C3=ADc=C3=ADho:=20=09->=20p=C5=AF?= =?UTF-8?q?vodn=C3=AD=20implementace=20v=20origin=C3=A1le=20nefungovala=20?= =?UTF-8?q?=09->=20fungovala,=20ale=20pod=20jinou=20verz=C3=AD=20knihovny?= =?UTF-8?q?=20fftw3=20=09->=20n=C4=9Bkter=C3=A1=20z=20m=C3=BDch=20p=C5=99e?= =?UTF-8?q?dchoz=C3=ADch=20=C3=BAprav=20zm=C4=9Bnila=20form=C3=A1t=20input?= =?UTF-8?q?u?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- src/fft_fftw.cpp | 120 +++++++++++++++++++++++++++-------------------- src/fft_fftw.h | 2 + 2 files changed, 72 insertions(+), 50 deletions(-) diff --git a/src/fft_fftw.cpp b/src/fft_fftw.cpp index afe56bb8..43c8c4ff 100644 --- a/src/fft_fftw.cpp +++ b/src/fft_fftw.cpp @@ -20,30 +20,23 @@ // // Matrices are accepted and returned as metadata type cv::GMatDesc, // which describe these matrices. -#ifdef BIG_BATCH -G_TYPED_KERNEL(GFftw, - , - "org.opencv2.core.fftw_gapi") -#else G_TYPED_KERNEL(GFftw, - , + ,int)>, "org.opencv2.core.fftw_gapi") -#endif { - static cv::GMatDesc // output type of function, descriptor of output GMat - outMeta(cv::GMatDesc in, // argument of function, descriptor of input GMat - fftwf_plan /*planA*/, // argument of function, plan of transformation to execute - #ifdef BIG_BATCH - fftwf_plan /*planB*/, // argument of function, plan of transformation to execute in case of BIG_BATCH - #endif - int flag, // argument of function, 1=forward, 2=forward_window, 3=inverse - cv::Size size + static cv::GMatDesc // output type of function, descriptor of output GMat + outMeta(cv::GMatDesc in, // argument of function, descriptor of input GMat + fftwf_plan /*plan*/, // argument of function, plan of transformation to execute + int flag, // argument of function, 1=forward OR forward_window, 2=inverse + cv::Size size, // argument of function, how big will be the resulting matrix + std::vector /*inputDims*/, // argument of function, how big was the input matrix before reformatting + int /*channels*/ // argument of function, how many channels in the output matrix before reformatting ) { // This describes output of the custom function, // specifically that it should be the same as input, but with 1 or 2 channels, // and with supplied size. - if (flag == 1 || flag == 2){ + if (flag == 1){ return in.withSize(size).withType(CV_32F, 2); } return in.withSize(size).withType(CV_32F, 1); @@ -53,38 +46,28 @@ G_TYPED_KERNEL(GFftw, GAPI_OCV_KERNEL(GCPUFftw, GFftw) { static void - run(const cv::Mat &in, // in - derived from GMat - const fftwf_plan &planA, - #ifdef BIG_BATCH - const fftwf_plan &planB, - #endif - const int flag, - cv::Size size, - cv::Mat &out) // out - derived from GMat (retval) + run(const cv::Mat &in, // in - derived from GMat + const fftwf_plan &plan, + int flag, + cv::Size size, + std::vector inputDims, + int channels, + cv::Mat &out) // out - derived from GMat (retval) { (void)size; - switch (flag){ - case 1: - if (in.dims == 2) - DEBUG_PRINTM(in); - DEBUG_PRINTM(out); - fftwf_execute_dft_r2c(planA, reinterpret_cast(in.data), - reinterpret_cast(out.ptr>(0))); - DEBUG_PRINTM(in); - DEBUG_PRINTM(out); - #ifdef BIG_BATCH - else - fftwf_execute_dft_r2c(planB, reinterpret_cast(in.data), + (void)flag; + + if (inputDims.size() > 0){ + // returning the input/output matices into their original shapes for processing + cv::Mat resizedInputMat = cv::Mat(inputDims.size(), inputDims.data(),in.type(),reinterpret_cast(in.data)); + cv::Mat resizedOutputMat = cv::Mat(out.rows, out.cols / (channels /2),CV_32FC(channels), out.ptr(0)); + fftwf_execute_dft_r2c(plan, reinterpret_cast(resizedInputMat.data), + reinterpret_cast(resizedOutputMat.ptr>(0))); + } else { + fftwf_execute_dft_r2c(plan, reinterpret_cast(in.data), reinterpret_cast(out.ptr>(0))); - #endif - break; - case 2: - - break; - default: // flag == 3 - - break; } + } }; @@ -186,18 +169,19 @@ void Fftw::forward(const cv::UMat &real_input, cv::UMat &complex_result) cv::GMat in; cv::GMat out; - out = GFftw::on(in, plan_f, - #ifdef BIG_BATCH - plan_f_all_scales, - #endif - 1, cv::Size(outputMat.cols,outputMat.rows)); + if (real_input.dims == 2) + out = GFftw::on(in, plan_f, 1, cv::Size(outputMat.cols,outputMat.rows), std::vector(), 0); + #ifdef BIG_BATCH + else + out = GFftw::on(in, plan_f_all_scales, 1, cv::Size(outputMat.cols,outputMat.rows), std::vector(), 0); + #endif cv::GComputation fourierFwd(in, out); cv::gapi::GKernelPackage kernelPkg = cv::gapi::GKernelPackage(); kernelPkg.include(); fourierFwd.apply(inputMat, outputMat, cv::compile_args(kernelPkg)); } -void Fftw::forward_window(cv::UMat &feat, cv::UMat & complex_result, cv::UMat &temp) +void Fftw::forward_window_cpu(cv::UMat &feat, cv::UMat & complex_result, cv::UMat &temp) { Fft::forward_window(feat, complex_result, temp); @@ -220,6 +204,42 @@ void Fftw::forward_window(cv::UMat &feat, cv::UMat & complex_result, cv::UMat &t #endif } +void Fftw::forward_window(cv::UMat &feat, cv::UMat & complex_result, cv::UMat &temp) +{ + Fft::forward_window(feat, complex_result, temp); + + for (uint i = 0; i < uint(feat.size[0]); ++i) { + for (uint j = 0; j < uint(feat.size[1]); ++j) { + cv::UMat feat_plane = MatUtil::plane(i,j,feat); + cv::UMat temp_plane = MatUtil::plane(i,j,temp); + temp_plane = feat_plane.mul(m_window); + } + } + cv::Mat preInputMat = temp.getMat(cv::ACCESS_RW); + cv::Mat preOutputMat = complex_result.getMat(cv::ACCESS_RW); + // Cant feed multidimensional or multichanneled matrices to GAPI, so some reformatting is needed + cv::Mat inputMat = cv::Mat(preInputMat.size[0] * preInputMat.size[1] * preInputMat.size[2], preInputMat.size[3], + preInputMat.type(),preInputMat.ptr()); + cv::Mat outputMat = cv::Mat(preOutputMat.rows, preOutputMat.cols * (preOutputMat.channels() / 2), + CV_32FC2, preOutputMat.ptr()); + cv::GMat in; + cv::GMat out; + if (feat.size[0] == 1) + out = GFftw::on(in, plan_fw, 1, cv::Size(outputMat.cols,outputMat.rows), + std::vector({preInputMat.size[0], preInputMat.size[1], preInputMat.size[2], preInputMat.size[3]}), + preOutputMat.channels()); + #ifdef BIG_BATCH + else + out = GFftw::on(in, plan_fw_all_scales, 1, cv::Size(outputMat.cols,outputMat.rows), + std::vector({preInputMat.size[0], preInputMat.size[1], preInputMat.size[2], preInputMat.size[3]}), + preOutputMat.channels()); + #endif + cv::GComputation fourierFwdWin(in, out); + cv::gapi::GKernelPackage kernelPkg = cv::gapi::GKernelPackage(); + kernelPkg.include(); + fourierFwdWin.apply(inputMat, outputMat, cv::compile_args(kernelPkg)); +} + void Fftw::inverse(cv::UMat &complex_input, cv::UMat &real_result) { Fft::inverse(complex_input, real_result); diff --git a/src/fft_fftw.h b/src/fft_fftw.h index 3bf0f104..c60a52ef 100644 --- a/src/fft_fftw.h +++ b/src/fft_fftw.h @@ -20,6 +20,8 @@ class Fftw : public Fft void inverse(cv::UMat &complex_input, cv::UMat &real_result); void forward_cpu(const cv::UMat &real_input, cv::UMat &complex_result); + void forward_window_cpu(cv::UMat &feat, cv::UMat & complex_result, cv::UMat &temp); + ~Fftw(); protected: From 7e14736cfd57fe1ec79e869ca4df810ace07f9e3 Mon Sep 17 00:00:00 2001 From: Your Name Date: Fri, 1 May 2020 03:00:33 +0200 Subject: [PATCH 118/121] =?UTF-8?q?Opravena=20rozbit=C3=A1=20implementace?= =?UTF-8?q?=20p=C5=AFvodn=C3=AD=20funkce=20Fftw::forward=5Fwindow()=20-=20?= =?UTF-8?q?d=C5=AFvod=20pro=C4=8D=20ComplexMat=20d=C3=A1val=20v=C5=A1echny?= =?UTF-8?q?=20hodnoty=20ka=C5=BEd=C3=A9ho=20kan=C3=A1lu=20do=20jednoho=20c?= =?UTF-8?q?elistv=C3=A9ho=20bloku=20je=20pravd=C4=9Bpodon=C4=9B=20kv=C5=AF?= =?UTF-8?q?li=20t=C3=A9to=20funkci=20-=20z=20pohledu=20implementace=20fftw?= =?UTF-8?q?=20je=20prostor=20v=20matici=20kam=20zapsat=20zpracovanou=20sub?= =?UTF-8?q?matici=20celistv=C3=BDm=20blokem,=20a=20sou=C4=8Dasn=C4=9B=20je?= =?UTF-8?q?dn=C3=ADm=20kan=C3=A1lem=20matice=20-=20fftw=20zapisuje=20v?= =?UTF-8?q?=C3=BDsledn=C3=A9=20submatice=20postupn=C4=9B=20za=20sebou=20do?= =?UTF-8?q?=20datov=C3=A9ho=20prostoru,=20na=20kter=C3=BD=20dostal=20ve=20?= =?UTF-8?q?vstupn=C3=ADm=20argumentu=20ukazatel=20-=20V=20cv::Mat=20jsou?= =?UTF-8?q?=20hodnoty=20jednoho=20kan=C3=A1lu=20rozd=C4=9Bleny=20na=20pozi?= =?UTF-8?q?ce=20ka=C5=BEd=C3=A9ho=20bodu=20v=20matici,=20co=C5=BE=20zp?= =?UTF-8?q?=C5=AFsobovalo=20chybnou=20reprezentaci=20dat=20po=20z=C3=A1pis?= =?UTF-8?q?u=20stylem=20fftw?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit - Původní implementace Fftw::forward_window() nyní dokáže správně pracovat s datovým typem cv::Mat místo ComplexMat --- src/fft_fftw.cpp | 25 +++++++++++-------------- 1 file changed, 11 insertions(+), 14 deletions(-) diff --git a/src/fft_fftw.cpp b/src/fft_fftw.cpp index 43c8c4ff..b574a687 100644 --- a/src/fft_fftw.cpp +++ b/src/fft_fftw.cpp @@ -146,7 +146,7 @@ void Fftw::set_window(const cv::UMat &window) m_window = window; } -void Fftw::forward_cpu(const cv::UMat &real_input, cv::UMat &complex_result) +void Fftw::forward(const cv::UMat &real_input, cv::UMat &complex_result) { Fft::forward(real_input, complex_result); @@ -160,7 +160,7 @@ void Fftw::forward_cpu(const cv::UMat &real_input, cv::UMat &complex_result) #endif } -void Fftw::forward(const cv::UMat &real_input, cv::UMat &complex_result) +void Fftw::forward_cpu(const cv::UMat &real_input, cv::UMat &complex_result) { Fft::forward(real_input, complex_result); @@ -181,30 +181,27 @@ void Fftw::forward(const cv::UMat &real_input, cv::UMat &complex_result) fourierFwd.apply(inputMat, outputMat, cv::compile_args(kernelPkg)); } -void Fftw::forward_window_cpu(cv::UMat &feat, cv::UMat & complex_result, cv::UMat &temp) +void Fftw::forward_window(cv::UMat &feat, cv::UMat & complex_result, cv::UMat &temp) { Fft::forward_window(feat, complex_result, temp); + cv::UMat tempRes; for (uint i = 0; i < uint(feat.size[0]); ++i) { for (uint j = 0; j < uint(feat.size[1]); ++j) { cv::UMat feat_plane = MatUtil::plane(i,j,feat); cv::UMat temp_plane = MatUtil::plane(i,j,temp); temp_plane = feat_plane.mul(m_window); + + tempRes = cv::UMat::zeros(complex_result.rows, complex_result.cols, CV_32FC2); + fftwf_execute_dft_r2c(plan_f, reinterpret_cast(temp_plane.getMat(cv::ACCESS_RW).data), + reinterpret_cast(tempRes.getMat(cv::ACCESS_RW).ptr>(0))); + MatUtil::set_channel(0, int(j * 2), tempRes, complex_result); + MatUtil::set_channel(1, int(j * 2 + 1), tempRes, complex_result); } } - - float *in = temp.getMat(cv::ACCESS_RW).ptr(); - fftwf_complex *out = reinterpret_cast(complex_result.getMat(cv::ACCESS_RW).ptr>(0)); - - if (feat.size[0] == 1) - fftwf_execute_dft_r2c(plan_fw, in, out); -#ifdef BIG_BATCH - else - fftwf_execute_dft_r2c(plan_fw_all_scales, in, out); -#endif } -void Fftw::forward_window(cv::UMat &feat, cv::UMat & complex_result, cv::UMat &temp) +void Fftw::forward_window_cpu(cv::UMat &feat, cv::UMat & complex_result, cv::UMat &temp) { Fft::forward_window(feat, complex_result, temp); From 7619052f8a12082aface77087515ed78ebcff7f8 Mon Sep 17 00:00:00 2001 From: Your Name Date: Fri, 1 May 2020 03:37:30 +0200 Subject: [PATCH 119/121] =?UTF-8?q?GAPI=20implementace=20Fftw::forward=5Fw?= =?UTF-8?q?indow=20byla=20opravena=20do=20funk=C4=8Dn=C3=AD=20podoby=20-?= =?UTF-8?q?=20vypu=C5=A1t=C4=9Bny=20nadbyte=C4=8Dn=C3=A9=20argumenty=20a?= =?UTF-8?q?=20p=C5=99eform=C3=A1tov=C3=A1n=C3=AD=20v=20GAPI=20funkci?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- src/fft_fftw.cpp | 92 +++++++++++++++++++++++++----------------------- 1 file changed, 47 insertions(+), 45 deletions(-) diff --git a/src/fft_fftw.cpp b/src/fft_fftw.cpp index b574a687..3d84e2b4 100644 --- a/src/fft_fftw.cpp +++ b/src/fft_fftw.cpp @@ -21,16 +21,14 @@ // Matrices are accepted and returned as metadata type cv::GMatDesc, // which describe these matrices. G_TYPED_KERNEL(GFftw, - ,int)>, + , "org.opencv2.core.fftw_gapi") { static cv::GMatDesc // output type of function, descriptor of output GMat outMeta(cv::GMatDesc in, // argument of function, descriptor of input GMat fftwf_plan /*plan*/, // argument of function, plan of transformation to execute int flag, // argument of function, 1=forward OR forward_window, 2=inverse - cv::Size size, // argument of function, how big will be the resulting matrix - std::vector /*inputDims*/, // argument of function, how big was the input matrix before reformatting - int /*channels*/ // argument of function, how many channels in the output matrix before reformatting + cv::Size size // argument of function, how big will be the resulting matrix ) { // This describes output of the custom function, @@ -50,23 +48,23 @@ GAPI_OCV_KERNEL(GCPUFftw, GFftw) const fftwf_plan &plan, int flag, cv::Size size, - std::vector inputDims, - int channels, cv::Mat &out) // out - derived from GMat (retval) { (void)size; (void)flag; - if (inputDims.size() > 0){ - // returning the input/output matices into their original shapes for processing - cv::Mat resizedInputMat = cv::Mat(inputDims.size(), inputDims.data(),in.type(),reinterpret_cast(in.data)); - cv::Mat resizedOutputMat = cv::Mat(out.rows, out.cols / (channels /2),CV_32FC(channels), out.ptr(0)); - fftwf_execute_dft_r2c(plan, reinterpret_cast(resizedInputMat.data), - reinterpret_cast(resizedOutputMat.ptr>(0))); - } else { - fftwf_execute_dft_r2c(plan, reinterpret_cast(in.data), + fftwf_execute_dft_r2c(plan, reinterpret_cast(in.data), reinterpret_cast(out.ptr>(0))); - } + +// if (inputDims.size() > 0){ +// // returning the input/output matices into their original shapes for processing +// cv::Mat resizedInputMat = cv::Mat(inputDims.size(), inputDims.data(),in.type(),reinterpret_cast(in.data)); +// cv::Mat resizedOutputMat = cv::Mat(out.rows, out.cols / (channels /2),CV_32FC(channels), out.ptr(0)); +// fftwf_execute_dft_r2c(plan, reinterpret_cast(resizedInputMat.data), +// reinterpret_cast(resizedOutputMat.ptr>(0))); +// } else { +// +// } } @@ -146,7 +144,7 @@ void Fftw::set_window(const cv::UMat &window) m_window = window; } -void Fftw::forward(const cv::UMat &real_input, cv::UMat &complex_result) +void Fftw::forward_cpu(const cv::UMat &real_input, cv::UMat &complex_result) { Fft::forward(real_input, complex_result); @@ -160,7 +158,7 @@ void Fftw::forward(const cv::UMat &real_input, cv::UMat &complex_result) #endif } -void Fftw::forward_cpu(const cv::UMat &real_input, cv::UMat &complex_result) +void Fftw::forward(const cv::UMat &real_input, cv::UMat &complex_result) { Fft::forward(real_input, complex_result); @@ -170,10 +168,10 @@ void Fftw::forward_cpu(const cv::UMat &real_input, cv::UMat &complex_result) cv::GMat in; cv::GMat out; if (real_input.dims == 2) - out = GFftw::on(in, plan_f, 1, cv::Size(outputMat.cols,outputMat.rows), std::vector(), 0); + out = GFftw::on(in, plan_f, 1, cv::Size(outputMat.cols,outputMat.rows)); #ifdef BIG_BATCH else - out = GFftw::on(in, plan_f_all_scales, 1, cv::Size(outputMat.cols,outputMat.rows), std::vector(), 0); + out = GFftw::on(in, plan_f_all_scales, 1, cv::Size(outputMat.cols,outputMat.rows)); #endif cv::GComputation fourierFwd(in, out); cv::gapi::GKernelPackage kernelPkg = cv::gapi::GKernelPackage(); @@ -181,7 +179,7 @@ void Fftw::forward_cpu(const cv::UMat &real_input, cv::UMat &complex_result) fourierFwd.apply(inputMat, outputMat, cv::compile_args(kernelPkg)); } -void Fftw::forward_window(cv::UMat &feat, cv::UMat & complex_result, cv::UMat &temp) +void Fftw::forward_window_cpu(cv::UMat &feat, cv::UMat & complex_result, cv::UMat &temp) { Fft::forward_window(feat, complex_result, temp); @@ -193,48 +191,52 @@ void Fftw::forward_window(cv::UMat &feat, cv::UMat & complex_result, cv::UMat &t temp_plane = feat_plane.mul(m_window); tempRes = cv::UMat::zeros(complex_result.rows, complex_result.cols, CV_32FC2); - fftwf_execute_dft_r2c(plan_f, reinterpret_cast(temp_plane.getMat(cv::ACCESS_RW).data), + if (feat.size[0] == 1) + fftwf_execute_dft_r2c(plan_f, reinterpret_cast(temp_plane.getMat(cv::ACCESS_RW).data), + reinterpret_cast(tempRes.getMat(cv::ACCESS_RW).ptr>(0))); + #ifdef BIG_BATCH + else + fftwf_execute_dft_r2c(plan_fw_all_scales, reinterpret_cast(temp_plane.getMat(cv::ACCESS_RW).data), reinterpret_cast(tempRes.getMat(cv::ACCESS_RW).ptr>(0))); + #endif MatUtil::set_channel(0, int(j * 2), tempRes, complex_result); MatUtil::set_channel(1, int(j * 2 + 1), tempRes, complex_result); } } } -void Fftw::forward_window_cpu(cv::UMat &feat, cv::UMat & complex_result, cv::UMat &temp) +void Fftw::forward_window(cv::UMat &feat, cv::UMat & complex_result, cv::UMat &temp) { Fft::forward_window(feat, complex_result, temp); - for (uint i = 0; i < uint(feat.size[0]); ++i) { - for (uint j = 0; j < uint(feat.size[1]); ++j) { - cv::UMat feat_plane = MatUtil::plane(i,j,feat); - cv::UMat temp_plane = MatUtil::plane(i,j,temp); - temp_plane = feat_plane.mul(m_window); - } - } - cv::Mat preInputMat = temp.getMat(cv::ACCESS_RW); - cv::Mat preOutputMat = complex_result.getMat(cv::ACCESS_RW); - // Cant feed multidimensional or multichanneled matrices to GAPI, so some reformatting is needed - cv::Mat inputMat = cv::Mat(preInputMat.size[0] * preInputMat.size[1] * preInputMat.size[2], preInputMat.size[3], - preInputMat.type(),preInputMat.ptr()); - cv::Mat outputMat = cv::Mat(preOutputMat.rows, preOutputMat.cols * (preOutputMat.channels() / 2), - CV_32FC2, preOutputMat.ptr()); cv::GMat in; cv::GMat out; if (feat.size[0] == 1) - out = GFftw::on(in, plan_fw, 1, cv::Size(outputMat.cols,outputMat.rows), - std::vector({preInputMat.size[0], preInputMat.size[1], preInputMat.size[2], preInputMat.size[3]}), - preOutputMat.channels()); + out = GFftw::on(in, plan_f, 1, cv::Size(complex_result.cols, complex_result.rows)); #ifdef BIG_BATCH else - out = GFftw::on(in, plan_fw_all_scales, 1, cv::Size(outputMat.cols,outputMat.rows), - std::vector({preInputMat.size[0], preInputMat.size[1], preInputMat.size[2], preInputMat.size[3]}), - preOutputMat.channels()); + out = GFftw::on(in, plan_f_all_scales, 1, cv::Size(complex_result.cols,complex_result.rows)); #endif - cv::GComputation fourierFwdWin(in, out); + cv::GComputation fourierFwd(in, out); cv::gapi::GKernelPackage kernelPkg = cv::gapi::GKernelPackage(); - kernelPkg.include(); - fourierFwdWin.apply(inputMat, outputMat, cv::compile_args(kernelPkg)); + kernelPkg.include(); + + cv::UMat tempRes; + for (uint i = 0; i < uint(feat.size[0]); ++i) { + for (uint j = 0; j < uint(feat.size[1]); ++j) { + cv::UMat feat_plane = MatUtil::plane(i,j,feat); + cv::UMat temp_plane = MatUtil::plane(i,j,temp); + temp_plane = feat_plane.mul(m_window); + + tempRes = cv::UMat::zeros(complex_result.rows, complex_result.cols, CV_32FC2); + cv::Mat inputMat = temp_plane.getMat(cv::ACCESS_RW); + cv::Mat outputMat = tempRes.getMat(cv::ACCESS_RW); + fourierFwd.apply(inputMat, outputMat, cv::compile_args(kernelPkg)); + + MatUtil::set_channel(0, int(j * 2), tempRes, complex_result); + MatUtil::set_channel(1, int(j * 2 + 1), tempRes, complex_result); + } + } } void Fftw::inverse(cv::UMat &complex_input, cv::UMat &real_result) From dc377c1d638dd5eb86e374df6690fcc57705ee62 Mon Sep 17 00:00:00 2001 From: Your Name Date: Fri, 1 May 2020 04:23:16 +0200 Subject: [PATCH 120/121] =?UTF-8?q?[FINAL]=20->=20DOKON=C4=8CENA=20KONVERZ?= =?UTF-8?q?E=20FOURIEROV=C3=9DCH=20TRANSFORMAC=C3=8D=20V=20KONTEXTU=20ROZH?= =?UTF-8?q?RAN=C3=8D=20GAPI=20-=20implementace=20CUDA=20byla=20vynech?= =?UTF-8?q?=C3=A1na=20na=20z=C3=A1klad=C4=9B=20dohody=20s=20vedouc=C3=ADm?= =?UTF-8?q?=20pr=C3=A1ce=20-=20deklarov=C3=A1ny=20nov=C3=A9=20GAPI=20funkc?= =?UTF-8?q?e=20pomoc=C3=AD=20Kernel=20API,=20a=20implementov=C3=A1ny=20pom?= =?UTF-8?q?oc=C3=AD=20funkc=C3=AD=20knihoven=20v=20dan=C3=A9m=20buildu=20-?= =?UTF-8?q?=20nov=C3=A9=20GAPI=20funkce=20otestov=C3=A1ny=20na=20shodnost?= =?UTF-8?q?=20v=C3=BDstupu=20a=20funk=C4=8Dnost=20-=20velk=C3=A1=20=C4=8D?= =?UTF-8?q?=C3=A1st=20funkc=C3=AD=20je=20bohu=C5=BEel=20pomalej=C5=A1?= =?UTF-8?q?=C3=AD=20ne=C5=BE=20p=C5=AFvodn=C3=AD=20implementace?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- src/fft_fftw.cpp | 47 +++++++++++++++++++++++++++++++---------------- src/fft_fftw.h | 1 + 2 files changed, 32 insertions(+), 16 deletions(-) diff --git a/src/fft_fftw.cpp b/src/fft_fftw.cpp index 3d84e2b4..d43ae035 100644 --- a/src/fft_fftw.cpp +++ b/src/fft_fftw.cpp @@ -51,22 +51,14 @@ GAPI_OCV_KERNEL(GCPUFftw, GFftw) cv::Mat &out) // out - derived from GMat (retval) { (void)size; - (void)flag; - - fftwf_execute_dft_r2c(plan, reinterpret_cast(in.data), + if (flag == 1){ + fftwf_execute_dft_r2c(plan, reinterpret_cast(in.data), reinterpret_cast(out.ptr>(0))); - -// if (inputDims.size() > 0){ -// // returning the input/output matices into their original shapes for processing -// cv::Mat resizedInputMat = cv::Mat(inputDims.size(), inputDims.data(),in.type(),reinterpret_cast(in.data)); -// cv::Mat resizedOutputMat = cv::Mat(out.rows, out.cols / (channels /2),CV_32FC(channels), out.ptr(0)); -// fftwf_execute_dft_r2c(plan, reinterpret_cast(resizedInputMat.data), -// reinterpret_cast(resizedOutputMat.ptr>(0))); -// } else { -// -// } - - + } else if (flag == 2) { + fftwf_execute_dft_c2r(plan, + reinterpret_cast(in.data), + out.ptr()); + } } }; @@ -239,7 +231,7 @@ void Fftw::forward_window(cv::UMat &feat, cv::UMat & complex_result, cv::UMat &t } } -void Fftw::inverse(cv::UMat &complex_input, cv::UMat &real_result) +void Fftw::inverse_cpu(cv::UMat &complex_input, cv::UMat &real_result) { Fft::inverse(complex_input, real_result); @@ -255,6 +247,29 @@ void Fftw::inverse(cv::UMat &complex_input, cv::UMat &real_result) real_result.getMat(cv::ACCESS_RW) *= 1.0 / (m_width * m_height); } +void Fftw::inverse(cv::UMat &complex_input, cv::UMat &real_result) +{ + Fft::inverse(complex_input, real_result); + + cv::Mat inputMat = complex_input.getMat(cv::ACCESS_RW); + cv::UMat tempOutMat = MatUtil::plane(0,real_result); + cv::Mat outputMat = tempOutMat.getMat(cv::ACCESS_RW); + + cv::GMat in; + cv::GMat out; + if (complex_input.channels() == 2) + out = GFftw::on(in, plan_i_1ch, 2, cv::Size(outputMat.cols,outputMat.rows)); + #ifdef BIG_BATCH + else + out = GFftw::on(in, plan_i_all_scales, 2, cv::Size(outputMat.cols,outputMat.rows)); + #endif + cv::GComputation fourierInv(in, out); + cv::gapi::GKernelPackage kernelPkg = cv::gapi::GKernelPackage(); + kernelPkg.include(); + fourierInv.apply(inputMat, outputMat, cv::compile_args(kernelPkg)); + outputMat *= 1.0 / (m_width * m_height); +} + Fftw::~Fftw() { if (plan_f) fftwf_destroy_plan(plan_f); diff --git a/src/fft_fftw.h b/src/fft_fftw.h index c60a52ef..79f074f7 100644 --- a/src/fft_fftw.h +++ b/src/fft_fftw.h @@ -21,6 +21,7 @@ class Fftw : public Fft void forward_cpu(const cv::UMat &real_input, cv::UMat &complex_result); void forward_window_cpu(cv::UMat &feat, cv::UMat & complex_result, cv::UMat &temp); + void inverse_cpu(cv::UMat &complex_input, cv::UMat &real_result); ~Fftw(); From 951094688ad885b7c258b2f07bbc9a1f8e902f62 Mon Sep 17 00:00:00 2001 From: Your Name Date: Sun, 17 May 2020 00:43:59 +0200 Subject: [PATCH 121/121] =?UTF-8?q?Drobn=C3=A1=20optimalizace=20forward=5F?= =?UTF-8?q?window()=20knihovny=20OpenCV=20-=20odstran=C4=9Bno=20zakomentov?= =?UTF-8?q?an=C3=A9=20implementa=C4=8Dn=C3=AD=20h=C5=99i=C5=A1t=C4=9B=20-?= =?UTF-8?q?=20p=C5=99id=C3=A1na=20funkce=20MatUtil::set=5Fchannel()=20pro?= =?UTF-8?q?=20typ=20cv::Mat?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- src/fft_opencv.cpp | 31 +++++----- src/kcf.cpp | 149 --------------------------------------------- src/matutil.h | 7 +++ 3 files changed, 22 insertions(+), 165 deletions(-) diff --git a/src/fft_opencv.cpp b/src/fft_opencv.cpp index 0fa5d227..2411cee6 100644 --- a/src/fft_opencv.cpp +++ b/src/fft_opencv.cpp @@ -58,15 +58,15 @@ GAPI_OCV_KERNEL(GCPUDft, GDft) cv::Mat_< std::complex > cpxCopyMat = cv::Mat_< std::complex >(cpyMat); cv::Mat_< std::complex > cpxOutMat = cv::Mat_< std::complex >(out); cpxCopyMat.forEach([&cpxOutMat](std::complex &c, const int * position) { - int rowVal = *position; - int colVal = *(position +1); - cpxOutMat.ptr>(rowVal)[colVal] = c; + // int rowVal = *position; + // int colVal = *(position +1); + cpxOutMat.ptr>(*position)[*(position +1)] = c; }); } else { cpyMat.forEach([&out](float &c, const int * position) { - int rowVal = *position; - int colVal = *(position +1); - out.ptr(rowVal)[colVal] = c; + // int rowVal = *position; + // int colVal = *(position +1); + out.ptr(*position)[*(position +1)] = c; }); } } @@ -134,18 +134,17 @@ void FftOpencv::forward_window(cv::UMat &feat, cv::UMat &complex_result, cv::UMa cv::gapi::GKernelPackage kernelPkg = cv::gapi::GKernelPackage(); kernelPkg.include(); - cv::Mat matComplex_res; - cv::UMat channel; - cv::Mat matChannel; - cv::UMat complex_res; + cv::Mat featTemp = feat.getMat(cv::ACCESS_RW); + cv::Mat cpxResTemp = complex_result.getMat(cv::ACCESS_RW); + + cv::Mat channel; + cv::Mat complex_res; for (uint i = 0; i < uint(feat.size[0]); ++i) { for (uint j = 0; j < uint(feat.size[1]); ++j) { - channel = MatUtil::plane(i, j, feat); - matChannel = channel.getMat(cv::ACCESS_RW).mul(m_window); - fourierFwdWin.apply(matChannel, matComplex_res, cv::compile_args(kernelPkg)); - complex_res = matComplex_res.getUMat(cv::ACCESS_RW); - MatUtil::set_channel(int(0), int(2*j), complex_res, complex_result); - MatUtil::set_channel(int(1), int(2*j+1), complex_res, complex_result); + channel = MatUtil::plane(i, j, featTemp).mul(m_window); + fourierFwdWin.apply(channel, complex_res, cv::compile_args(kernelPkg)); + MatUtil::set_channel(int(0), int(2*j), complex_res, cpxResTemp); + MatUtil::set_channel(int(1), int(2*j+1), complex_res, cpxResTemp); } } } diff --git a/src/kcf.cpp b/src/kcf.cpp index 6593c3f7..3eaad180 100644 --- a/src/kcf.cpp +++ b/src/kcf.cpp @@ -140,155 +140,6 @@ void KCF_Tracker::init(cv::UMat &img, const cv::Rect &bbox, int fit_size_x, int __dbgTracer.debug = m_debug; TRACE(""); -// cv::Mat test2 = cv::Mat(2,2,CV_32FC4,float(1)); -// DEBUG_PRINTM(test2); -// cv::UMat test = test2.getUMat(cv::ACCESS_RW); -// DEBUG_PRINTM(test); -// std::vector dims = std::vector({2, 2, 2}); -// std::vector dims2 = std::vector({2, 2, 2}); -// cv::Mat test = cv::Mat(3, dims.data(), CV_32FC2); -// cv::Mat testAdd = cv::Mat(3, dims2.data(), CV_32FC2); -// -// cv::UMat testPl = cv::UMat(test.size[1], test.size[2], test.type(), test.getMat(cv::ACCESS_RW).ptr(0)); -// -// -//// cv::Mat_> testComplex = cv::Mat_>(test2); -// -// -// double time_profile_counter = cv::getCPUTickCount(); -// time_profile_counter = cv::getCPUTickCount() - time_profile_counter; -// std::cout << " Speed : " << time_profile_counter/((double)cvGetTickFrequency()*1000) << "ms." << std::endl; -// -// cv::UMat testOrig = cv::UMat(2, 2, CV_32FC4); -// cv::Mat test = testOrig.getMat(cv::ACCESS_RW); -// test.ptr(0)[0] = float(1); -// test.ptr(0)[1] = float(2); -// test.ptr(0)[2] = float(3); -// test.ptr(0)[3] = float(4); -// test.ptr(0)[4] = float(5); -// test.ptr(0)[5] = float(6); -// test.ptr(0)[6] = float(7); -// test.ptr(0)[7] = float(8); -// test.ptr(0)[8] = float(9); -// test.ptr(0)[9] = float(10); -// test.ptr(0)[10] = float(11); -// test.ptr(0)[11] = float(12); -// test.ptr(0)[12] = float(13); -// test.ptr(0)[13] = float(14); -// test.ptr(0)[14] = float(15); -// test.ptr(0)[15] = float(16); -// DEBUG_PRINTM(test); -// cv::UMat test2 = MatUtil::sum_over_channels_foreach(testOrig); -// DEBUG_PRINTM(test2); -// return; -// -// test.ptr(1)[0] = float(9); -// test.ptr(1)[1] = float(10); -// test.ptr(1)[2] = float(11); -// test.ptr(1)[3] = float(12); -// test.ptr(1)[4] = float(13); -// test.ptr(1)[5] = float(14); -// test.ptr(1)[6] = float(15); -// test.ptr(1)[7] = float(16); -// -// testAdd.ptr(0)[0] = float(1); -// testAdd.ptr(0)[1] = float(1); -// testAdd.ptr(0)[2] = float(1); -// testAdd.ptr(0)[3] = float(1); -// testAdd.ptr(0)[4] = float(1); -// testAdd.ptr(0)[5] = float(1); -// testAdd.ptr(0)[6] = float(1); -// testAdd.ptr(0)[7] = float(1); -// testAdd.ptr(1)[0] = float(1); -// testAdd.ptr(1)[1] = float(1); -// testAdd.ptr(1)[2] = float(1); -// testAdd.ptr(1)[3] = float(1); -// testAdd.ptr(1)[4] = float(1); -// testAdd.ptr(1)[5] = float(1); -// testAdd.ptr(1)[6] = float(1); -// testAdd.ptr(1)[7] = float(1); -//// -// std::vector dims3 = std::vector({2, 2, 2}); -// cv::Mat plan = MatUtil::plane(0,test); -// cv::Mat_< std::complex > cpxMat = cv::Mat_< std::complex >(plan); -// cv::Mat_< std::complex > cpxMat2; -// -// cv::GMat in; -// cv::GMat out = cv::gapi::addC(in,10); -// cv::GComputation ac(in, out); -// ac.apply(cpxMat, cpxMat2); -// DEBUG_PRINTM(test); -// DEBUG_PRINTM(cpxMat); -// DEBUG_PRINTM(cpxMat2); -// return; -// -// DEBUG_PRINTM(test); -// DEBUG_PRINTM(testAdd); -// DEBUG_PRINTM(testComplex); -// return; -// -// cv::GMat in; -// cv::GMat inAdd; -// cv::GMat out = cv::gapi::add(in,inAdd); -// cv::GComputation ac(cv::GIn(in, inAdd), cv::GOut(out)); -// -// -// cv::Mat tmp1 = cv::Mat(2, 2, CV_32FC2, test.ptr(0)); -// cv::Mat tmp2 = cv::Mat(2, 2, CV_32FC2, testAdd.ptr(0)); -// cv::Mat tmp3 = cv::Mat::zeros(2, 2, CV_32FC2); -// -// DEBUG_PRINTM(tmp3); -// ac.apply(cv::gin(tmp1,tmp2), cv::gout(tmp3)); -// DEBUG_PRINTM(tmp1); -// DEBUG_PRINTM(tmp2); -// DEBUG_PRINTM(tmp3); -// -// cv::Mat tmp4 = test.getMat(cv::ACCESS_WRITE); -// cv::Mat tmp5 = testAdd.getMat(cv::ACCESS_WRITE); -// std::vector dims3 = std::vector({2, 2, 2}); -// cv::Mat tmp6 = cv::Mat(dims3, CV_32FC2); -// DEBUG_PRINTM(test); -// DEBUG_PRINTM(testAdd); -// DEBUG_PRINTM(tmp6); -// ac.apply(cv::gin(test,testAdd), cv::gout(tmp6)); -// DEBUG_PRINTM(test); -// DEBUG_PRINTM(testAdd); -// DEBUG_PRINTM(tmp6); -// -// -// return; -// -// int from_to[] = { 0,0 }; -// cv::mixChannels(&testPl,1,&test2,1,from_to,1); -// int from_to2[] = { 1,1 }; -// cv::mixChannels(&testPl,1,&test2,1,from_to2,1); -// -// DEBUG_PRINTM(test2); -// return; -// -// -// assert(test.channels() % 2 == 0); -// for (uint i = 0; i < test.rows; ++i) { -// for (uint j = 0; j < test.cols; ++j){ -// for (uint k = 0; k < test.channels() / 2 ; ++k){ -// std::complex cpxVal = test.ptr>(i)[(test.channels() / 2)*j + k]; -// cpxVal.imag(- cpxVal.imag()); -// test.ptr>(i)[(test.channels() / 2)*j + k] = cpxVal; -// DEBUG_PRINTM(cpxVal); -// } -// } -// } -// -// cv::Mat test = cv::Mat(3, std::vector({2, 2, 2}).data(), CV_32FC2, float(5)); -// test.ptr(0)[0] = float(1); -// test.ptr(1)[0] = float(1); -// test.ptr(1,1)[0] = float(1); -// -// DEBUG_PRINTM(test); -// -// -// return; - // check boundary, enforce min size double x1 = bbox.x, x2 = bbox.x + bbox.width, y1 = bbox.y, y2 = bbox.y + bbox.height; if (x1 < 0) x1 = 0.; diff --git a/src/matutil.h b/src/matutil.h index a985573c..9af48dec 100644 --- a/src/matutil.h +++ b/src/matutil.h @@ -82,6 +82,13 @@ static void set_channel(int idxFrom, int idxTo, cv::UMat &source, cv::UMat &targ cv::Mat convTgt = target.getMat(cv::ACCESS_RW); cv::mixChannels( &convSrc, 1, &convTgt, 1, from_to, 1 ); } +static void set_channel(int idxFrom, int idxTo, cv::Mat &source, cv::Mat &target) +{ + assert(idxTo < target.channels()); + assert(idxFrom < source.channels()); + int from_to[] = { idxFrom,idxTo }; + cv::mixChannels( &source, 1, &target, 1, from_to, 1 ); +} /* * Sum of channel values for each point of input matrix