From 76bd17e3c095e2379daf893427cb3d9d277a064e Mon Sep 17 00:00:00 2001 From: Stanislaw Halik Date: Fri, 22 Sep 2017 14:23:03 +0200 Subject: tracker/pt: add color extraction modes --- tracker-pt/FTNoIR_PT_Controls.ui | 319 ++++++++++++++++++++++---------- tracker-pt/ftnoir_tracker_pt_dialog.cpp | 12 ++ tracker-pt/ftnoir_tracker_pt_settings.h | 13 +- tracker-pt/point_extractor.cpp | 78 +++++++- tracker-pt/point_extractor.h | 4 +- tracker-pt/point_tracker.cpp | 4 +- tracker-pt/point_tracker.h | 4 +- 7 files changed, 326 insertions(+), 108 deletions(-) (limited to 'tracker-pt') diff --git a/tracker-pt/FTNoIR_PT_Controls.ui b/tracker-pt/FTNoIR_PT_Controls.ui index 8d044654..ea83a215 100644 --- a/tracker-pt/FTNoIR_PT_Controls.ui +++ b/tracker-pt/FTNoIR_PT_Controls.ui @@ -9,8 +9,8 @@ 0 0 - 424 - 588 + 412 + 616 @@ -36,20 +36,81 @@ QLayout::SetFixedSize + + + + + 0 + 0 + + + + Status + + + + + + + 0 + 0 + + + + Extracted Points: + + + + + + + + 0 + 0 + + + + Camera Info: + + + + + + + + 0 + 0 + + + + + + + + + + + + 0 + 0 + + + + + + + + + + - + 0 0 - - - 0 - 0 - - @@ -63,6 +124,12 @@ + + + 0 + 0 + + Camera settings @@ -70,7 +137,7 @@ - + 0 0 @@ -82,6 +149,12 @@ + + + 0 + 0 + + ° @@ -99,7 +172,7 @@ - + 0 0 @@ -112,7 +185,7 @@ - + 0 0 @@ -125,7 +198,7 @@ - + 0 0 @@ -141,7 +214,7 @@ - + 0 0 @@ -162,6 +235,12 @@ + + + 0 + 0 + + Dynamic pose timeout @@ -170,7 +249,7 @@ - + 0 0 @@ -188,6 +267,12 @@ + + + 0 + 0 + + @@ -196,7 +281,7 @@ - + 0 0 @@ -218,7 +303,7 @@ - + 0 0 @@ -230,6 +315,12 @@ + + + 0 + 0 + + ms @@ -242,9 +333,9 @@ - + - + 0 0 @@ -257,7 +348,7 @@ - + 0 0 @@ -285,22 +376,91 @@ + + + 0 + 0 + + Camera settings (when available) + + + + + 0 + 0 + + + + Dynamic pose (for caps only, never clips) + + + + + + + + 0 + 0 + + + + Color channels used + + + + + + + + 0 + 0 + + + + + Normal + + + + + Floppy filter + + + + + Red + + + + + + + 0 + 0 + + Point extraction + + + 0 + 0 + + Max size @@ -311,6 +471,12 @@ + + + 0 + 0 + + Threshold @@ -321,6 +487,12 @@ + + + 0 + 0 + + Min size @@ -332,7 +504,7 @@ - + 0 0 @@ -362,6 +534,12 @@ + + + 0 + 0 + + Automatic threshold @@ -369,6 +547,12 @@ + + + 0 + 0 + + Enable, slider sets point size @@ -376,6 +560,12 @@ + + + 0 + 0 + + Maximum point diameter @@ -392,6 +582,12 @@ + + + 0 + 0 + + Minimum point diameter @@ -1147,91 +1343,14 @@ Don't roll or change position. - - + + 0 0 - - Status - - - - - - Extracted Points: - - - - - - - Camera Info: - - - - - - - - 0 - 0 - - - - - 120 - 15 - - - - - - - - - - - - 0 - 0 - - - - - 120 - 15 - - - - - - - - - - - - - - Qt::Vertical - - - QSizePolicy::Expanding - - - - 20 - 0 - - - - - - QDialogButtonBox::Cancel|QDialogButtonBox::Ok diff --git a/tracker-pt/ftnoir_tracker_pt_dialog.cpp b/tracker-pt/ftnoir_tracker_pt_dialog.cpp index ccedeb78..fa159d34 100644 --- a/tracker-pt/ftnoir_tracker_pt_dialog.cpp +++ b/tracker-pt/ftnoir_tracker_pt_dialog.cpp @@ -81,6 +81,18 @@ TrackerDialog_PT::TrackerDialog_PT() poll_tracker_info_impl(); connect(this, &TrackerDialog_PT::poll_tracker_info, this, &TrackerDialog_PT::poll_tracker_info_impl, Qt::DirectConnection); + + static constexpr pt_color_type color_types[] = { + pt_color_normal, + pt_color_floppy_filter, + pt_color_red_only, + }; + + static constexpr unsigned color_type_sz = sizeof(color_types) / sizeof(*color_types); + for (unsigned k = 0; k < color_type_sz; k++) + ui.blob_color->setItemData(k, int(color_types[k])); + + tie_setting(s.blob_color, ui.blob_color); } void TrackerDialog_PT::startstop_trans_calib(bool start) diff --git a/tracker-pt/ftnoir_tracker_pt_settings.h b/tracker-pt/ftnoir_tracker_pt_settings.h index 79c1e103..265d382e 100644 --- a/tracker-pt/ftnoir_tracker_pt_settings.h +++ b/tracker-pt/ftnoir_tracker_pt_settings.h @@ -11,6 +11,15 @@ #include "options/options.hpp" using namespace options; +enum pt_color_type +{ + // explicit values, gotta preserve the numbering in .ini + // don't reuse when removing some of the modes + pt_color_normal = 2, + pt_color_red_only = 3, + pt_color_floppy_filter = 4, +}; + struct settings_pt : opts { value camera_name; @@ -33,6 +42,7 @@ struct settings_pt : opts value dynamic_pose; value init_phase_timeout; value auto_threshold; + value blob_color; settings_pt() : opts("tracker-pt"), @@ -63,6 +73,7 @@ struct settings_pt : opts fov(b, "camera-fov", 56), dynamic_pose(b, "dynamic-pose-resolution", true), init_phase_timeout(b, "init-phase-timeout", 250), - auto_threshold(b, "automatic-threshold", true) + auto_threshold(b, "automatic-threshold", true), + blob_color(b, "blob-color", pt_color_normal) {} }; diff --git a/tracker-pt/point_extractor.cpp b/tracker-pt/point_extractor.cpp index dc36fbe5..54514111 100644 --- a/tracker-pt/point_extractor.cpp +++ b/tracker-pt/point_extractor.cpp @@ -78,6 +78,28 @@ PointExtractor::PointExtractor() blobs.reserve(max_blobs); } +void PointExtractor::separate_channels(cv::Mat const& orig, const int* order, int order_npairs) +{ + if (unlikely(ch[0].rows != orig.rows || ch[0].cols != orig.cols)) + { + for (unsigned k = 0; k < 3; k++) + { + ch[k] = cv::Mat1b(orig.rows, orig.cols); + ch_float[k] = cv::Mat1f(orig.rows, orig.cols); + } + // extra channel is a scratch buffer + ch_float[3] = cv::Mat1f(orig.rows, orig.cols); + } + + if (order == nullptr) + cv::split(orig, (cv::Mat*) ch); + else + cv::mixChannels(&orig, 1, (cv::Mat*) ch, order_npairs, order, order_npairs); + + for (unsigned k = 0; k < 3; k++) + ch[k].convertTo(ch_float[k], CV_32F); +} + void PointExtractor::extract_points(const cv::Mat& frame, cv::Mat& preview_frame, std::vector& points) { using std::sqrt; @@ -92,8 +114,60 @@ void PointExtractor::extract_points(const cv::Mat& frame, cv::Mat& preview_frame frame_blobs = cv::Mat1b(frame.rows, frame.cols); } - // convert to grayscale - cv::cvtColor(frame, frame_gray, cv::COLOR_BGR2GRAY); + const pt_color_type color = s.blob_color; + if (color == pt_color_normal) + { + // convert to grayscale + // this operation is optimized + cv::cvtColor(frame, frame_gray, cv::COLOR_BGR2GRAY); + } + else + { + switch (color) + { + case pt_color_floppy_filter: + { + // weight for blue color + static constexpr float B = .8; + // single channel weight + static constexpr float A = 1./2; + + static constexpr int from_to[] = { + 0, 0, + 1, 1 + }; + + separate_channels(frame, from_to, 2); + + ch_float[2] = ch_float[0] * B * A // blue + + ch_float[1] * (1 - B) * A; // green + ch_float[2].convertTo(frame_gray, CV_8U); + + break; + } + case pt_color_red_only: + { + static constexpr int from_to[] = { + 2, 0 + }; + + separate_channels(frame, from_to, 1); + + static constexpr float R = 3; + + ch_float[1] = ch_float[0] * R; // red + + ch_float[1].convertTo(frame_gray, CV_8U); + + break; + } + default: + once_only(qDebug() << "wrong pt_color_type enum value" << int(color)); + // don't violate POLA + cv::cvtColor(frame, frame_gray, cv::COLOR_BGR2GRAY); + break; + } + } 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 5fbe9a45..193c06dc 100644 --- a/tracker-pt/point_extractor.h +++ b/tracker-pt/point_extractor.h @@ -46,8 +46,10 @@ private: cv::Mat frame_bin; cv::Mat hist; cv::Mat frame_blobs; - std::vector blobs; + cv::Mat ch[3], ch_float[4]; + + void separate_channels(cv::Mat const& orig_frame, int const* order = nullptr, int order_cnt = -1); }; } // ns impl diff --git a/tracker-pt/point_tracker.cpp b/tracker-pt/point_tracker.cpp index d2620dce..ae873ef6 100644 --- a/tracker-pt/point_tracker.cpp +++ b/tracker-pt/point_tracker.cpp @@ -33,7 +33,7 @@ static void set_row(mat33& m, int i, const vec3& v) m(i,2) = v[2]; } -PointModel::PointModel(settings_pt& s) +PointModel::PointModel(const settings_pt& s) { set_model(s); // calculate u @@ -47,7 +47,7 @@ PointModel::PointModel(settings_pt& s) P = 1/(s11*s22-s12*s12) * mat22(s22, -s12, -s12, s11); } -void PointModel::set_model(settings_pt& s) +void PointModel::set_model(const settings_pt& s) { switch (s.active_model_panel) { diff --git a/tracker-pt/point_tracker.h b/tracker-pt/point_tracker.h index ebbbc801..2b142632 100644 --- a/tracker-pt/point_tracker.h +++ b/tracker-pt/point_tracker.h @@ -42,8 +42,8 @@ struct PointModel final enum Model { Clip, Cap, Custom }; - PointModel(settings_pt& s); - void set_model(settings_pt& s); + PointModel(const settings_pt& s); + void set_model(const settings_pt& s); void get_d_order(const vec2* points, unsigned* d_order, const vec2& d) const; }; -- cgit v1.2.3