Skip to content

Commit

Permalink
[fictrac] add thr_rgb_tfrm config option; fix thresholding bug (win_i…
Browse files Browse the repository at this point in the history
…t); minor change to mask roi growing (reduce circ rad rather than eroding mask)
  • Loading branch information
rjdmoore committed Jul 9, 2019
1 parent 41ab862 commit 94372ad
Show file tree
Hide file tree
Showing 3 changed files with 55 additions and 15 deletions.
7 changes: 7 additions & 0 deletions include/FrameGrabber.h
Original file line number Diff line number Diff line change
Expand Up @@ -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
);
Expand Down Expand Up @@ -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;

Expand Down
57 changes: 45 additions & 12 deletions src/FrameGrabber.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -18,11 +18,10 @@
#include <opencv2/videoio.hpp>

#include <cmath> // round
#include <string>

using cv::Mat;
using std::shared_ptr;
using std::unique_lock;
using std::mutex;
using namespace std;

///
///
Expand All @@ -32,6 +31,7 @@ FrameGrabber::FrameGrabber( shared_ptr<FrameSource> 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)
Expand All @@ -49,6 +49,16 @@ FrameGrabber::FrameGrabber( shared_ptr<FrameSource> 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;
Expand Down Expand Up @@ -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.
Expand All @@ -259,29 +290,31 @@ 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
uint8_t* pthrmax = thresh_max.data;
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; }
}
Expand All @@ -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; }
}
Expand Down
6 changes: 3 additions & 3 deletions src/Trackball.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -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.
Expand Down Expand Up @@ -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);
Expand Down Expand Up @@ -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.
Expand Down

0 comments on commit 94372ad

Please sign in to comment.