From a814bff460cff1263e236e465c7ef8c8f88baf55 Mon Sep 17 00:00:00 2001 From: Stéphane Lenclud Date: Sun, 14 Apr 2019 11:40:52 +0200 Subject: Easy Tracker: Renaming settings. --- tracker-easy/cv-point-extractor.cpp | 151 ------------------------------------ tracker-easy/cv-point-extractor.h | 41 ---------- tracker-easy/module.cpp | 2 +- tracker-easy/point-extractor.cpp | 151 ++++++++++++++++++++++++++++++++++++ tracker-easy/point-extractor.h | 41 ++++++++++ tracker-easy/pt-settings.hpp | 73 ----------------- tracker-easy/settings.h | 71 +++++++++++++++++ tracker-easy/tracker-easy-api.h | 29 ++----- tracker-easy/tracker-easy-dialog.h | 2 +- tracker-easy/tracker-easy.cpp | 4 +- tracker-easy/tracker-easy.h | 5 +- 11 files changed, 277 insertions(+), 293 deletions(-) delete mode 100644 tracker-easy/cv-point-extractor.cpp delete mode 100644 tracker-easy/cv-point-extractor.h create mode 100644 tracker-easy/point-extractor.cpp create mode 100644 tracker-easy/point-extractor.h delete mode 100644 tracker-easy/pt-settings.hpp create mode 100644 tracker-easy/settings.h diff --git a/tracker-easy/cv-point-extractor.cpp b/tracker-easy/cv-point-extractor.cpp deleted file mode 100644 index c7a3c958..00000000 --- a/tracker-easy/cv-point-extractor.cpp +++ /dev/null @@ -1,151 +0,0 @@ -/* - * Copyright (c) 2019 Stephane Lenclud - * - * Permission to use, copy, modify, and/or distribute this software for any - * purpose with or without fee is hereby granted, provided that the above - * copyright notice and this permission notice appear in all copies. - */ - -#include "cv-point-extractor.h" -#include "preview.h" -#include "tracker-easy.h" - -#include "cv/numeric.hpp" -#include "compat/math.hpp" -#include - -#include -#include -#include -#include - -#include - -using namespace numeric_types; - -namespace EasyTracker -{ - - CvPointExtractor::CvPointExtractor() : s(KModuleName) - { - - } - - - void CvPointExtractor::extract_points(const cv::Mat& aFrame, cv::Mat* aPreview, std::vector& aPoints) - { - //TODO: Assert if channel size is neither one nor two - // Make sure our frame channel is 8 bit - size_t channelSize = aFrame.elemSize1(); - if (channelSize == 2) - { - // We have a 16 bits single channel. Typically coming from Kinect V2 IR sensor - // Resample to 8-bits - double min = std::numeric_limits::min(); - double max = std::numeric_limits::max(); - //cv::minMaxLoc(raw, &min, &max); // Should we use 16bit min and max instead? - // For scalling to have more precission in the range we are interrested in - min = max - 255; - // See: https://stackoverflow.com/questions/14539498/change-type-of-mat-object-from-cv-32f-to-cv-8u/14539652 - aFrame.convertTo(iFrameChannelSizeOne, CV_8U, 255.0 / (max - min), -255.0*min / (max - min)); - } - else - { - iFrameChannelSizeOne = aFrame; - } - - - // Make sure our frame has a single channel - // Make an extra copy if needed - const int channelCount = iFrameChannelSizeOne.channels(); - if (channelCount == 3) - { - // Convert to grayscale - // TODO: What's our input format, BRG or RGB? - // That won't make our point extraction work but at least it won't crash - cv::cvtColor(iFrameChannelSizeOne, iFrameGray, cv::COLOR_BGR2GRAY); - // TODO: Instead convert to HSV and use a key color together with cv::inRange to sport the color we want. - // Key color should be defined in settings. - } - else if (channelCount == 1) - { - // No further convertion needed - iFrameGray = iFrameChannelSizeOne; - } - else - { - eval_once(qDebug() << "tracker/easy: camera frame depth not supported" << aFrame.channels()); - return; - } - - // Contours detection - std::vector > contours; - cv::findContours(iFrameGray, contours, CV_RETR_EXTERNAL, CV_CHAIN_APPROX_NONE); - - // Workout which countours are valid points - for (size_t i = 0; i < contours.size(); i++) - { - if (aPreview) - { - cv::drawContours(*aPreview, contours, (int)i, CV_RGB(255, 0, 0), 2); - } - - - cv::Rect bBox; - bBox = cv::boundingRect(contours[i]); - - float ratio = (float)bBox.width / (float)bBox.height; - if (ratio > 1.0f) - ratio = 1.0f / ratio; - - - // Searching for a bBox almost square - float minArea = s.min_point_size*s.min_point_size; - float maxArea = s.max_point_size*s.max_point_size; - if (bBox.width >= s.min_point_size - && bBox.height >= s.min_point_size - && bBox.width <= s.max_point_size - && bBox.height <= s.max_point_size - && bBox.area() >= minArea - && bBox.area() <= maxArea - /*&& ratio > 0.75 &&*/) - { - vec2 center; - center[0] = bBox.x + bBox.width / 2; - center[1] = bBox.y + bBox.height / 2; - aPoints.push_back(vec2(center)); - - if (aPreview) - { - cv::rectangle(*aPreview, bBox, CV_RGB(0, 255, 0), 2); - } - } - } - - // Keep only the three points which are highest, i.e. with lowest Y coordinates - // That's most usefull to discard noise from features below your cap/head. - // Typically noise comming from zippers and metal parts on your clothing. - // With a cap tracker it also successfully discards noise from glasses. - // However it may not work as good with a clip user wearing glasses. - while (aPoints.size() > 3) // Until we have no more than three points - { - int maxY = 0; - size_t index = -1; - - // Search for the point with highest Y coordinate - for (size_t i = 0; i < aPoints.size(); i++) - { - if (aPoints[i][1] > maxY) - { - maxY = aPoints[i][1]; - index = i; - } - } - - // Discard it - aPoints.erase(aPoints.begin() + index); - } - } - -} - diff --git a/tracker-easy/cv-point-extractor.h b/tracker-easy/cv-point-extractor.h deleted file mode 100644 index 677be292..00000000 --- a/tracker-easy/cv-point-extractor.h +++ /dev/null @@ -1,41 +0,0 @@ -/* - * Copyright (c) 2019 Stephane Lenclud - * - * Permission to use, copy, modify, and/or distribute this software for any - * purpose with or without fee is hereby granted, provided that the above - * copyright notice and this permission notice appear in all copies. - */ - -#pragma once - -#include "tracker-easy-api.h" - -#include - -#include -#include - - -using namespace numeric_types; - -namespace EasyTracker -{ - - - class CvPointExtractor final : public IPointExtractor - { - public: - // extracts points from frame and draws some processing info into frame, if draw_output is set - // dt: time since last call in seconds - void extract_points(const cv::Mat& aFrame, cv::Mat* aPreview, std::vector& aPoints) override; - CvPointExtractor(); - // Settings - pt_settings s; - // Our frame with a channel size of 8 bits - cv::Mat iFrameChannelSizeOne; - // Our frame with a single 8 bits channel - cv::Mat iFrameGray; - }; - -} - diff --git a/tracker-easy/module.cpp b/tracker-easy/module.cpp index b6d21c80..b7b60fa8 100644 --- a/tracker-easy/module.cpp +++ b/tracker-easy/module.cpp @@ -2,7 +2,7 @@ #include "tracker-easy-dialog.h" #include "tracker-easy-api.h" #include "module.hpp" -#include "cv-point-extractor.h" +#include "point-extractor.h" #include diff --git a/tracker-easy/point-extractor.cpp b/tracker-easy/point-extractor.cpp new file mode 100644 index 00000000..d8ea3c53 --- /dev/null +++ b/tracker-easy/point-extractor.cpp @@ -0,0 +1,151 @@ +/* + * Copyright (c) 2019 Stephane Lenclud + * + * Permission to use, copy, modify, and/or distribute this software for any + * purpose with or without fee is hereby granted, provided that the above + * copyright notice and this permission notice appear in all copies. + */ + +#include "point-extractor.h" +#include "preview.h" +#include "tracker-easy.h" + +#include "cv/numeric.hpp" +#include "compat/math.hpp" +#include + +#include +#include +#include +#include + +#include + +using namespace numeric_types; + +namespace EasyTracker +{ + + PointExtractor::PointExtractor() : s(KModuleName) + { + + } + + + void PointExtractor::extract_points(const cv::Mat& aFrame, cv::Mat* aPreview, std::vector& aPoints) + { + //TODO: Assert if channel size is neither one nor two + // Make sure our frame channel is 8 bit + size_t channelSize = aFrame.elemSize1(); + if (channelSize == 2) + { + // We have a 16 bits single channel. Typically coming from Kinect V2 IR sensor + // Resample to 8-bits + double min = std::numeric_limits::min(); + double max = std::numeric_limits::max(); + //cv::minMaxLoc(raw, &min, &max); // Should we use 16bit min and max instead? + // For scalling to have more precission in the range we are interrested in + min = max - 255; + // See: https://stackoverflow.com/questions/14539498/change-type-of-mat-object-from-cv-32f-to-cv-8u/14539652 + aFrame.convertTo(iFrameChannelSizeOne, CV_8U, 255.0 / (max - min), -255.0*min / (max - min)); + } + else + { + iFrameChannelSizeOne = aFrame; + } + + + // Make sure our frame has a single channel + // Make an extra copy if needed + const int channelCount = iFrameChannelSizeOne.channels(); + if (channelCount == 3) + { + // Convert to grayscale + // TODO: What's our input format, BRG or RGB? + // That won't make our point extraction work but at least it won't crash + cv::cvtColor(iFrameChannelSizeOne, iFrameGray, cv::COLOR_BGR2GRAY); + // TODO: Instead convert to HSV and use a key color together with cv::inRange to sport the color we want. + // Key color should be defined in settings. + } + else if (channelCount == 1) + { + // No further convertion needed + iFrameGray = iFrameChannelSizeOne; + } + else + { + eval_once(qDebug() << "tracker/easy: camera frame depth not supported" << aFrame.channels()); + return; + } + + // Contours detection + std::vector > contours; + cv::findContours(iFrameGray, contours, CV_RETR_EXTERNAL, CV_CHAIN_APPROX_NONE); + + // Workout which countours are valid points + for (size_t i = 0; i < contours.size(); i++) + { + if (aPreview) + { + cv::drawContours(*aPreview, contours, (int)i, CV_RGB(255, 0, 0), 2); + } + + + cv::Rect bBox; + bBox = cv::boundingRect(contours[i]); + + float ratio = (float)bBox.width / (float)bBox.height; + if (ratio > 1.0f) + ratio = 1.0f / ratio; + + + // Searching for a bBox almost square + float minArea = s.min_point_size*s.min_point_size; + float maxArea = s.max_point_size*s.max_point_size; + if (bBox.width >= s.min_point_size + && bBox.height >= s.min_point_size + && bBox.width <= s.max_point_size + && bBox.height <= s.max_point_size + && bBox.area() >= minArea + && bBox.area() <= maxArea + /*&& ratio > 0.75 &&*/) + { + vec2 center; + center[0] = bBox.x + bBox.width / 2; + center[1] = bBox.y + bBox.height / 2; + aPoints.push_back(vec2(center)); + + if (aPreview) + { + cv::rectangle(*aPreview, bBox, CV_RGB(0, 255, 0), 2); + } + } + } + + // Keep only the three points which are highest, i.e. with lowest Y coordinates + // That's most usefull to discard noise from features below your cap/head. + // Typically noise comming from zippers and metal parts on your clothing. + // With a cap tracker it also successfully discards noise from glasses. + // However it may not work as good with a clip user wearing glasses. + while (aPoints.size() > 3) // Until we have no more than three points + { + int maxY = 0; + size_t index = -1; + + // Search for the point with highest Y coordinate + for (size_t i = 0; i < aPoints.size(); i++) + { + if (aPoints[i][1] > maxY) + { + maxY = aPoints[i][1]; + index = i; + } + } + + // Discard it + aPoints.erase(aPoints.begin() + index); + } + } + +} + diff --git a/tracker-easy/point-extractor.h b/tracker-easy/point-extractor.h new file mode 100644 index 00000000..d6bbd241 --- /dev/null +++ b/tracker-easy/point-extractor.h @@ -0,0 +1,41 @@ +/* + * Copyright (c) 2019 Stephane Lenclud + * + * Permission to use, copy, modify, and/or distribute this software for any + * purpose with or without fee is hereby granted, provided that the above + * copyright notice and this permission notice appear in all copies. + */ + +#pragma once + +#include "tracker-easy-api.h" + +#include + +#include +#include + + +using namespace numeric_types; + +namespace EasyTracker +{ + + + class PointExtractor final : public IPointExtractor + { + public: + // extracts points from frame and draws some processing info into frame, if draw_output is set + // dt: time since last call in seconds + void extract_points(const cv::Mat& aFrame, cv::Mat* aPreview, std::vector& aPoints) override; + PointExtractor(); + // Settings + Settings s; + // Our frame with a channel size of 8 bits + cv::Mat iFrameChannelSizeOne; + // Our frame with a single 8 bits channel + cv::Mat iFrameGray; + }; + +} + diff --git a/tracker-easy/pt-settings.hpp b/tracker-easy/pt-settings.hpp deleted file mode 100644 index 723ee08d..00000000 --- a/tracker-easy/pt-settings.hpp +++ /dev/null @@ -1,73 +0,0 @@ -#pragma once - -#include "options/options.hpp" - -#include - -enum pt_color_type -{ - // explicit values, gotta preserve the numbering in .ini - // don't reuse when removing some of the modes - pt_color_natural = 2, - pt_color_red_only = 3, - pt_color_average = 5, - pt_color_blue_only = 6, - pt_color_green_only = 7, -}; - -namespace pt_impl { - -using namespace options; - -#ifdef __clang__ -# pragma clang diagnostic push -# pragma clang diagnostic ignored "-Wweak-vtables" -#endif - -struct pt_settings final : options::opts -{ - using slider_value = options::slider_value; - - value camera_name { b, "camera-name", "" }; - value cam_res_x { b, "camera-res-width", 640 }, - cam_res_y { b, "camera-res-height", 480 }, - cam_fps { b, "camera-fps", 30 }; - value min_point_size { b, "min-point-size", 2.5 }, - max_point_size { b, "max-point-size", 50 }; - - value m01_x { b, "m_01-x", 0 }, m01_y { b, "m_01-y", 0 }, m01_z { b, "m_01-z", 0 }; - value m02_x { b, "m_02-x", 0 }, m02_y { b, "m_02-y", 0 }, m02_z { b, "m_02-z", 0 }; - - value t_MH_x { b, "model-centroid-x", 0 }, - t_MH_y { b, "model-centroid-y", 0 }, - t_MH_z { b, "model-centroid-z", 0 }; - - value clip_ty { b, "clip-ty", 40 }, - clip_tz { b, "clip-tz", 30 }, - clip_by { b, "clip-by", 70 }, - clip_bz { b, "clip-bz", 80 }; - - value active_model_panel { b, "active-model-panel", 0 }, - cap_x { b, "cap-x", 40 }, - cap_y { b, "cap-y", 60 }, - cap_z { b, "cap-z", 100 }; - - value fov { b, "camera-fov", 56 }; - - value dynamic_pose { b, "dynamic-pose-resolution", false }; - value init_phase_timeout { b, "init-phase-timeout", 250 }; - value auto_threshold { b, "automatic-threshold", true }; - value blob_color { b, "blob-color", pt_color_natural }; - - value threshold_slider { b, "threshold-slider", { 128, 0, 255 } }; - - explicit pt_settings(const QString& name) : opts(name) {} -}; - -#ifdef __clang__ -# pragma clang diagnostic pop -#endif - -} // ns pt_impl - -using pt_settings = pt_impl::pt_settings; diff --git a/tracker-easy/settings.h b/tracker-easy/settings.h new file mode 100644 index 00000000..7d8c7c70 --- /dev/null +++ b/tracker-easy/settings.h @@ -0,0 +1,71 @@ +#pragma once + +#include "options/options.hpp" + +#include + +enum pt_color_type +{ + // explicit values, gotta preserve the numbering in .ini + // don't reuse when removing some of the modes + pt_color_natural = 2, + pt_color_red_only = 3, + pt_color_average = 5, + pt_color_blue_only = 6, + pt_color_green_only = 7, +}; + +namespace EasyTracker { + + using namespace options; + +#ifdef __clang__ +# pragma clang diagnostic push +# pragma clang diagnostic ignored "-Wweak-vtables" +#endif + + struct Settings final : options::opts + { + using slider_value = options::slider_value; + + value camera_name{ b, "camera-name", "" }; + value cam_res_x{ b, "camera-res-width", 640 }, + cam_res_y{ b, "camera-res-height", 480 }, + cam_fps{ b, "camera-fps", 30 }; + value min_point_size{ b, "min-point-size", 2.5 }, + max_point_size{ b, "max-point-size", 50 }; + + value m01_x{ b, "m_01-x", 0 }, m01_y{ b, "m_01-y", 0 }, m01_z{ b, "m_01-z", 0 }; + value m02_x{ b, "m_02-x", 0 }, m02_y{ b, "m_02-y", 0 }, m02_z{ b, "m_02-z", 0 }; + + value t_MH_x{ b, "model-centroid-x", 0 }, + t_MH_y{ b, "model-centroid-y", 0 }, + t_MH_z{ b, "model-centroid-z", 0 }; + + value clip_ty{ b, "clip-ty", 40 }, + clip_tz{ b, "clip-tz", 30 }, + clip_by{ b, "clip-by", 70 }, + clip_bz{ b, "clip-bz", 80 }; + + value active_model_panel{ b, "active-model-panel", 0 }, + cap_x{ b, "cap-x", 40 }, + cap_y{ b, "cap-y", 60 }, + cap_z{ b, "cap-z", 100 }; + + value fov{ b, "camera-fov", 56 }; + + value dynamic_pose{ b, "dynamic-pose-resolution", false }; + value init_phase_timeout{ b, "init-phase-timeout", 250 }; + value auto_threshold{ b, "automatic-threshold", true }; + value blob_color{ b, "blob-color", pt_color_natural }; + + value threshold_slider{ b, "threshold-slider", { 128, 0, 255 } }; + + explicit Settings(const QString& name) : opts(name) {} + }; + +#ifdef __clang__ +# pragma clang diagnostic pop +#endif + +} // diff --git a/tracker-easy/tracker-easy-api.h b/tracker-easy/tracker-easy-api.h index e5627d11..b50ce018 100644 --- a/tracker-easy/tracker-easy-api.h +++ b/tracker-easy/tracker-easy-api.h @@ -1,6 +1,13 @@ +/* Copyright (c) 2019 Stephane Lenclud + * + * Permission to use, copy, modify, and/or distribute this software for any + * purpose with or without fee is hereby granted, provided that the above + * copyright notice and this permission notice appear in all copies. + */ + #pragma once -#include "pt-settings.hpp" +#include "settings.h" #include "cv/numeric.hpp" #include "options/options.hpp" @@ -15,10 +22,6 @@ #include #include -#ifdef __clang__ -# pragma clang diagnostic push -# pragma clang diagnostic ignored "-Wweak-vtables" -#endif const int KPointCount = 3; @@ -31,20 +34,4 @@ public: virtual void extract_points(const cv::Mat& image, cv::Mat* aPreview, std::vector& aPoints) = 0; }; -struct IEasyTrackerTraits -{ - template using pointer = std::shared_ptr; - - IEasyTrackerTraits(); - virtual ~IEasyTrackerTraits(); - - virtual pointer make_point_extractor() const = 0; - virtual QString get_module_name() const = 0; -}; - -template -using pt_pointer = typename IEasyTrackerTraits::pointer; -#ifdef __clang__ -# pragma clang diagnostic pop -#endif diff --git a/tracker-easy/tracker-easy-dialog.h b/tracker-easy/tracker-easy-dialog.h index 86b9771b..861e0ff9 100644 --- a/tracker-easy/tracker-easy-dialog.h +++ b/tracker-easy/tracker-easy-dialog.h @@ -41,7 +41,7 @@ namespace EasyTracker protected: QString threshold_display_text(int threshold_value); - pt_settings s; + Settings s; Tracker* tracker; QTimer timer, calib_timer; TranslationCalibrator trans_calib; diff --git a/tracker-easy/tracker-easy.cpp b/tracker-easy/tracker-easy.cpp index 083bd951..acedc379 100644 --- a/tracker-easy/tracker-easy.cpp +++ b/tracker-easy/tracker-easy.cpp @@ -11,7 +11,7 @@ #include "video/video-widget.hpp" #include "compat/math-imports.hpp" #include "compat/check-visible.hpp" -#include "cv-point-extractor.h" +#include "point-extractor.h" #include "tracker-easy-api.h" #include @@ -36,7 +36,7 @@ namespace EasyTracker Tracker::Tracker() : s{ KModuleName }, - point_extractor{ std::make_unique() }, + point_extractor{ std::make_unique() }, iPreview{ preview_width, preview_height } { cv::setBreakOnError(true); diff --git a/tracker-easy/tracker-easy.h b/tracker-easy/tracker-easy.h index 341d676b..57419c1c 100644 --- a/tracker-easy/tracker-easy.h +++ b/tracker-easy/tracker-easy.h @@ -38,7 +38,6 @@ namespace EasyTracker { friend class Dialog; - template using pointer = pt_pointer; explicit Tracker(); ~Tracker() override; @@ -57,7 +56,7 @@ namespace EasyTracker QMutex camera_mtx; - pt_settings s; + Settings s; std::unique_ptr layout; std::vector iPoints; @@ -67,7 +66,7 @@ namespace EasyTracker std::unique_ptr point_extractor; std::unique_ptr camera; video::impl::camera::info iCameraInfo; - pointer widget; + std::unique_ptr widget; video::frame iFrame; cv::Mat iMatFrame; -- cgit v1.2.3