From 546cfb5ad52dcfe1421d1af5e7baeada588ac735 Mon Sep 17 00:00:00 2001 From: Stanislaw Halik Date: Wed, 27 Apr 2016 07:28:41 +0200 Subject: 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. --- tracker-pt/point_extractor.cpp | 63 +++++++++++++++++++++++++++++++++++++++++- tracker-pt/point_extractor.h | 7 +++++ 2 files changed, 69 insertions(+), 1 deletion(-) mode change 100644 => 100755 tracker-pt/point_extractor.cpp mode change 100644 => 100755 tracker-pt/point_extractor.h diff --git a/tracker-pt/point_extractor.cpp b/tracker-pt/point_extractor.cpp old mode 100644 new mode 100755 index a1294c1e..87a60e51 --- 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 +#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& PointExtractor::extract_points(cv::Mat& frame) { const int W = frame.cols; @@ -31,7 +92,7 @@ const std::vector& 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 old mode 100644 new mode 100755 index 3e4661f9..5a3630be --- a/tracker-pt/point_extractor.h +++ b/tracker-pt/point_extractor.h @@ -25,15 +25,22 @@ public: const std::vector &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 points; QMutex mtx; cv::Mat frame_gray; + cv::Mat frame_gray_tmp; cv::Mat frame_bin; cv::Mat hist; + std::vector gray_split_channels; + std::vector gray_absdiff_channels; + cv::Mat float_absdiff_channel; enum { max_blobs = 16 }; -- cgit v1.2.3