From 94372ad71716ee232e4c0bfb23830c508e5c04bd Mon Sep 17 00:00:00 2001 From: rjdmoore <3844483+rjdmoore@users.noreply.github.com> Date: Tue, 9 Jul 2019 22:23:41 +0200 Subject: [PATCH] [fictrac] add thr_rgb_tfrm config option; fix thresholding bug (win_it); minor change to mask roi growing (reduce circ rad rather than eroding mask) --- include/FrameGrabber.h | 7 ++++++ src/FrameGrabber.cpp | 57 +++++++++++++++++++++++++++++++++--------- src/Trackball.cpp | 6 ++--- 3 files changed, 55 insertions(+), 15 deletions(-) diff --git a/include/FrameGrabber.h b/include/FrameGrabber.h index f5d80a4..c2059e5 100644 --- a/include/FrameGrabber.h +++ b/include/FrameGrabber.h @@ -30,6 +30,7 @@ class FrameGrabber const cv::Mat& remap_mask, double thresh_ratio, double thresh_win_pc, + std::string thresh_rgb_transform = "grey", int max_buf_len = 1, int max_frame_cnt = -1 ); @@ -58,6 +59,12 @@ class FrameGrabber double _thresh_ratio; int _thresh_win, _thresh_rad; + enum { + GREY, + RED, + GREEN, + BLUE + } _thresh_rgb_transform; int _max_buf_len, _max_frame_cnt; diff --git a/src/FrameGrabber.cpp b/src/FrameGrabber.cpp index ad476d4..e4671e1 100644 --- a/src/FrameGrabber.cpp +++ b/src/FrameGrabber.cpp @@ -18,11 +18,10 @@ #include #include // round +#include using cv::Mat; -using std::shared_ptr; -using std::unique_lock; -using std::mutex; +using namespace std; /// /// @@ -32,6 +31,7 @@ FrameGrabber::FrameGrabber( shared_ptr source, const Mat& remap_mask, double thresh_ratio, double thresh_win_pc, + string thresh_rgb_transform, int max_buf_len, int max_frame_cnt ) : _source(source), _remapper(remapper), _remap_mask(remap_mask), _active(false) @@ -49,6 +49,16 @@ FrameGrabber::FrameGrabber( shared_ptr source, } _thresh_ratio = thresh_ratio; + if ((thresh_rgb_transform == "red") || (thresh_rgb_transform == "r")) { + _thresh_rgb_transform = FrameGrabber::RED; + } else if ((thresh_rgb_transform == "green") || (thresh_rgb_transform == "g")) { + _thresh_rgb_transform = FrameGrabber::GREEN; + } else if ((thresh_rgb_transform == "blue") || (thresh_rgb_transform == "b")) { + _thresh_rgb_transform = FrameGrabber::BLUE; + } else { + _thresh_rgb_transform = FrameGrabber::GREY; + } + if ((thresh_win_pc < 0) || (thresh_win_pc > 1.0)) { LOG_WRN("Invalid thresh_win parameter (%f)! Defaulting to 0.2", thresh_win_pc); thresh_win_pc = 0.2; @@ -241,7 +251,28 @@ void FrameGrabber::process() memset(win_min_hist.get(), 0, _thresh_win); /// Create grey ROI frame. - cv::cvtColor(frame_bgr, frame_grey, cv::COLOR_BGR2GRAY); + int from_to[2] = { 0, 0 }; + switch (_thresh_rgb_transform) { + case RED: + from_to[0] = 2; from_to[1] = 0; + cv::mixChannels(&frame_bgr, 1, &frame_grey, 1, from_to, 1); + break; + + case GREEN: + from_to[0] = 1; from_to[1] = 0; + cv::mixChannels(&frame_bgr, 1, &frame_grey, 1, from_to, 1); + break; + + case BLUE: + from_to[0] = 0; from_to[1] = 0; + cv::mixChannels(&frame_bgr, 1, &frame_grey, 1, from_to, 1); + break; + + case GREY: + default: + cv::cvtColor(frame_bgr, frame_grey, cv::COLOR_BGR2GRAY); + break; + } _remapper->apply(frame_grey, remap_grey); /// Blur image before calculating region min/max values. @@ -259,12 +290,13 @@ void FrameGrabber::process() uint8_t* pgrey = remap_blur.ptr(i); for (int j = 0; j <= _thresh_rad; j++) { if (pmask[j] < 255) { continue; } - uint8_t g = pgrey[j]; + const uint8_t& g = pgrey[j]; if ((g > max) && (g < 255)) { max = g; } // ignore overexposed regions if (g < min) { min = g; } } - win_max_hist[win_it++] = max; - win_min_hist[win_it++] = min; + win_max_hist[win_it] = max; + win_min_hist[win_it] = min; + win_it++; } // compute window min/max @@ -272,16 +304,17 @@ void FrameGrabber::process() uint8_t* pthrmin = thresh_min.data; for (int j = 0; j < _rw; j++) { for (int i = 0; i < _rh; i++) { + // add row max = 0; min = 255; if ((i + _thresh_rad) < _rh) { const uint8_t* pmask = _remap_mask.ptr(i + _thresh_rad); - uint8_t* pgrey = remap_blur.ptr(i + _thresh_rad); + const uint8_t* pgrey = remap_blur.ptr(i + _thresh_rad); for (int s = -_thresh_rad; s <= _thresh_rad; s++) { - int js = j + s; + const int js = j + s; if ((js < 0) || (js >= _rw)) { continue; } if (pmask[js] < 255) { continue; } - uint8_t g = pgrey[js]; + const uint8_t& g = pgrey[js]; if ((g > max) && (g < 255)) { max = g; } // ignore overexposed regions if (g < min) { min = g; } } @@ -291,10 +324,10 @@ void FrameGrabber::process() const uint8_t* pmask = _remap_mask.ptr(i + _thresh_rad - _rh); uint8_t* pgrey = remap_blur.ptr(i + _thresh_rad - _rh); for (int s = -_thresh_rad; s <= _thresh_rad; s++) { - int js = j + s + 1; + const int js = j + s + 1; if ((js < 0) || (js >= _rw)) { continue; } if (pmask[js] < 255) { continue; } - uint8_t g = pgrey[js]; + const uint8_t& g = pgrey[js]; if ((g > max) && (g < 255)) { max = g; } // ignore overexposed regions if (g < min) { min = g; } } diff --git a/src/Trackball.cpp b/src/Trackball.cpp index a991101..06ec8b3 100644 --- a/src/Trackball.cpp +++ b/src/Trackball.cpp @@ -198,7 +198,7 @@ Trackball::Trackball(string cfg_fn) _r_d_ratio = sin(_sphere_rad); /// Allow sphere region in mask. - auto int_circ = projCircleInt(_src_model, _sphere_c, _sphere_rad); + auto int_circ = projCircleInt(_src_model, _sphere_c, _sphere_rad * 0.975f); // crop a bit of the circle to avoid circumference thresholding issues cv::fillConvexPoly(src_mask, *int_circ, CV_RGB(255, 255, 255)); /// Mask out ignore regions. @@ -283,7 +283,6 @@ Trackball::Trackball(string cfg_fn) _roi_mask.create(_roi_h, _roi_w, CV_8UC1); _roi_mask.setTo(cv::Scalar::all(255)); remapper->apply(src_mask, _roi_mask); - erode(_roi_mask, _roi_mask, Mat(), cv::Point(-1, -1), 1, cv::BORDER_CONSTANT, 0); // remove edge effects /// Surface mapping. _sphere_model = CameraModel::createEquiArea(_map_w, _map_h, CM_PI_2, -CM_PI, CM_PI, -2 * CM_PI); @@ -514,7 +513,8 @@ Trackball::Trackball(string cfg_fn) remapper, _roi_mask, thresh_ratio, - thresh_win_pc + thresh_win_pc, + _cfg("thr_rgb_tfrm") ); /// Write all parameters back to config file.