diff options
author | Stanislaw Halik <sthalik@misaki.pl> | 2016-04-27 07:28:41 +0200 |
---|---|---|
committer | Stanislaw Halik <sthalik@misaki.pl> | 2016-04-27 07:28:55 +0200 |
commit | 546cfb5ad52dcfe1421d1af5e7baeada588ac735 (patch) | |
tree | 20c266e33e08ca281c93942ebf7f7e0c49e6d3e0 | |
parent | 9bd2c6921d8d9ccec50d926b4b3eea5d05b79db9 (diff) |
tracker/pt: experimental non-white color removal
It's enabled only for automatic thresholding. With it on, it's possible
to keep tracking in normal light conditions without changing gain or
exposure beforehand.
It won't function on badly overexposed images, or with other bright
white colors in the frame. It should function on somewhat overexposed
images.
CPU usage is somewhat high, even taking advantage of all OpenCV SIMD
goodness as per the code. We can revert the change if user reception is
bad.
-rwxr-xr-x[-rw-r--r--] | tracker-pt/point_extractor.cpp | 63 | ||||
-rwxr-xr-x[-rw-r--r--] | tracker-pt/point_extractor.h | 7 |
2 files changed, 69 insertions, 1 deletions
diff --git a/tracker-pt/point_extractor.cpp b/tracker-pt/point_extractor.cpp index a1294c1e..87a60e51 100644..100755 --- a/tracker-pt/point_extractor.cpp +++ b/tracker-pt/point_extractor.cpp @@ -13,12 +13,73 @@ # include "opentrack-compat/timer.hpp" #endif +//#define DEBUG_SUM_OF_SQUARES +#ifdef DEBUG_SUM_OF_SQUARES +# define SUM_OF_SQUARES_WINNAME "sum-of-squares-debug" +# include <opencv2/highgui.hpp> +#endif + PointExtractor::PointExtractor() { +#ifdef DEBUG_SUM_OF_SQUARES + cv::namedWindow(SUM_OF_SQUARES_WINNAME); +#endif blobs.reserve(max_blobs); points.reserve(max_blobs); } +PointExtractor::~PointExtractor() +{ +#ifdef DEBUG_SUM_OF_SQUARES + cv::destroyWindow(SUM_OF_SQUARES_WINNAME); +#endif +} + +void PointExtractor::gray_square_diff(const cv::Mat &frame, cv::Mat &frame_gray) +{ + const unsigned nchans = frame.channels(); + const int rows = frame.rows; + const int cols = frame.cols; + cv::cvtColor(frame, frame_gray, cv::COLOR_RGB2GRAY); + + if (nchans == 1 || !s.auto_threshold) + return; + + cv::split(frame, gray_split_channels); + + if (nchans > gray_absdiff_channels.size()) + gray_absdiff_channels.resize(nchans); + + for (unsigned i = 0; i < nchans; i++) + cv::absdiff(frame_gray, gray_split_channels[i], gray_absdiff_channels[i]); + + if (frame_gray_tmp.rows != rows || frame_gray_tmp.cols != cols) + frame_gray_tmp = cv::Mat(rows, cols, CV_32FC1); + + frame_gray.convertTo(frame_gray_tmp, CV_32FC1); + + constexpr float scale = .9; + + if (float_absdiff_channel.cols != cols || float_absdiff_channel.rows != rows) + float_absdiff_channel = cv::Mat(rows, cols, CV_32FC1); + + for (unsigned i = 0; i < nchans; i++) + { + gray_absdiff_channels[i].convertTo(float_absdiff_channel, CV_32FC1); + + frame_gray_tmp -= float_absdiff_channel.mul(float_absdiff_channel, scale); + } + + frame_gray_tmp = cv::max(0., frame_gray_tmp); + + frame_gray_tmp.convertTo(frame_gray, CV_8UC1); + +#ifdef DEBUG_SUM_OF_SQUARES + cv::imshow(SUM_OF_SQUARES_WINNAME, frame_gray); + cv::waitKey(1); +#endif +} + const std::vector<cv::Vec2f>& PointExtractor::extract_points(cv::Mat& frame) { const int W = frame.cols; @@ -31,7 +92,7 @@ const std::vector<cv::Vec2f>& PointExtractor::extract_points(cv::Mat& frame) } // convert to grayscale - cv::cvtColor(frame, frame_gray, cv::COLOR_RGB2GRAY); + gray_square_diff(frame, frame_gray); const double region_size_min = s.min_point_size; const double region_size_max = s.max_point_size; diff --git a/tracker-pt/point_extractor.h b/tracker-pt/point_extractor.h index 3e4661f9..5a3630be 100644..100755 --- a/tracker-pt/point_extractor.h +++ b/tracker-pt/point_extractor.h @@ -25,15 +25,22 @@ public: const std::vector<cv::Vec2f> &extract_points(cv::Mat &frame); int get_n_points() { QMutexLocker l(&mtx); return points.size(); } PointExtractor(); + ~PointExtractor(); settings_pt s; private: + void gray_square_diff(const cv::Mat& frame, cv::Mat& frame_gray); + enum { hist_c = 2 }; std::vector<cv::Vec2f> points; QMutex mtx; cv::Mat frame_gray; + cv::Mat frame_gray_tmp; cv::Mat frame_bin; cv::Mat hist; + std::vector<cv::Mat> gray_split_channels; + std::vector<cv::Mat> gray_absdiff_channels; + cv::Mat float_absdiff_channel; enum { max_blobs = 16 }; |