diff options
author | Stanislaw Halik <sthalik@misaki.pl> | 2018-01-11 19:03:10 +0100 |
---|---|---|
committer | Stanislaw Halik <sthalik@misaki.pl> | 2018-01-11 19:03:10 +0100 |
commit | fbd961775001228f6ffd9cc3bf09aa2de610aeae (patch) | |
tree | b54c35357ea0ec0fbf2d78d14a17bcf4047c9488 /tracker-pt | |
parent | 71374d0b5cd456e25252775fdec89fe3cf2aa5e6 (diff) |
tracker/pt: allow for reuse
Issue: #718
This allows for replacing the camera and point extractor code. See
`module.cpp' and `pt-api.hpp`.
Diffstat (limited to 'tracker-pt')
-rw-r--r-- | tracker-pt/camera.cpp | 50 | ||||
-rw-r--r-- | tracker-pt/camera.h | 56 | ||||
-rw-r--r-- | tracker-pt/export.hpp | 11 | ||||
-rw-r--r-- | tracker-pt/ftnoir_tracker_pt.cpp | 38 | ||||
-rw-r--r-- | tracker-pt/ftnoir_tracker_pt.h | 34 | ||||
-rw-r--r-- | tracker-pt/ftnoir_tracker_pt_dialog.cpp | 34 | ||||
-rw-r--r-- | tracker-pt/ftnoir_tracker_pt_dialog.h | 13 | ||||
-rw-r--r-- | tracker-pt/ftnoir_tracker_pt_settings.h | 85 | ||||
-rw-r--r-- | tracker-pt/module.cpp | 50 | ||||
-rw-r--r-- | tracker-pt/point_extractor.cpp | 22 | ||||
-rw-r--r-- | tracker-pt/point_extractor.h | 18 | ||||
-rw-r--r-- | tracker-pt/point_tracker.cpp | 10 | ||||
-rw-r--r-- | tracker-pt/point_tracker.h | 25 | ||||
-rw-r--r-- | tracker-pt/pt-api.cpp | 62 | ||||
-rw-r--r-- | tracker-pt/pt-api.hpp | 119 |
15 files changed, 368 insertions, 259 deletions
diff --git a/tracker-pt/camera.cpp b/tracker-pt/camera.cpp index f218a6d6..4784c51a 100644 --- a/tracker-pt/camera.cpp +++ b/tracker-pt/camera.cpp @@ -10,8 +10,12 @@ #include "compat/camera-names.hpp" #include "compat/math-imports.hpp" +#include "cv/video-property-page.hpp" + constexpr double Camera::dt_eps; +Camera::Camera() : dt_mean(0), fov(0), s("tracker-pt") {} + QString Camera::get_desired_name() const { return desired_name; @@ -22,28 +26,26 @@ QString Camera::get_active_name() const return active_name; } -double CamInfo::get_focal_length() const +void Camera::show_camera_settings() { - const double diag_len = sqrt(double(res_x*res_x + res_y*res_y)); - const double aspect_x = res_x / diag_len; - //const double aspect_y = res_y / diag_len; - const double diag_fov = fov * M_PI/180; - const double fov_x = 2*atan(tan(diag_fov*.5) * aspect_x); - //const double fov_y = 2*atan(tan(diag_fov*.5) * aspect_y); - const double fx = .5 / tan(fov_x * .5); - return fx; - //fy = .5 / tan(fov_y * .5); - //static bool once = false; if (!once) { once = true; qDebug() << "f" << ret << "fov" << (fov * 180/M_PI); } + const int idx = camera_name_to_index(s.camera_name); + + if (bool(*this)) + video_property_page::show_from_capture(*cap, idx); + else + { + video_property_page::show(idx); + } } -warn_result_unused Camera::result Camera::get_info() const +Camera::result Camera::get_info() const { if (cam_info.res_x == 0 || cam_info.res_y == 0) - return result(false, CamInfo()); + return result(false, pt_camera_info()); return result(true, cam_info); } -warn_result_unused Camera::result Camera::get_frame(cv::Mat& frame) +Camera::result Camera::get_frame(cv::Mat& frame) { const bool new_frame = _get_frame(frame); @@ -69,10 +71,10 @@ warn_result_unused Camera::result Camera::get_frame(cv::Mat& frame) return result(true, cam_info); } else - return result(false, CamInfo()); + return result(false, pt_camera_info()); } -warn_result_unused Camera::open_status Camera::start(int idx, int fps, int res_x, int res_y) +pt_camera_open_status Camera::start(int idx, int fps, int res_x, int res_y) { if (idx >= 0 && fps >= 0 && res_x >= 0 && res_y >= 0) { @@ -102,7 +104,7 @@ warn_result_unused Camera::open_status Camera::start(int idx, int fps, int res_x if (cap->isOpened() && cap->grab()) { - cam_info = CamInfo(); + cam_info = pt_camera_info(); active_name = QString(); cam_info.idx = idx; dt_mean = 0; @@ -110,20 +112,20 @@ warn_result_unused Camera::open_status Camera::start(int idx, int fps, int res_x t.start(); - return open_ok_change; + return cam_open_ok_change; } else { stop(); - return open_error; + return cam_open_error; } } - return open_ok_no_change; + return cam_open_ok_no_change; } stop(); - return open_error; + return cam_open_error; } void Camera::stop() @@ -131,11 +133,11 @@ void Camera::stop() cap = nullptr; desired_name = QString(); active_name = QString(); - cam_info = CamInfo(); - cam_desired = CamInfo(); + cam_info = pt_camera_info(); + cam_desired = pt_camera_info(); } -warn_result_unused bool Camera::_get_frame(cv::Mat& frame) +bool Camera::_get_frame(cv::Mat& frame) { if (cap && cap->isOpened()) { diff --git a/tracker-pt/camera.h b/tracker-pt/camera.h index 076e6847..7a4f75c4 100644 --- a/tracker-pt/camera.h +++ b/tracker-pt/camera.h @@ -8,9 +8,7 @@ #pragma once #include "compat/ndebug-guard.hpp" - -#undef NDEBUG -#include <cassert> +#include "pt-api.hpp" #include "compat/util.hpp" #include "compat/timer.hpp" @@ -22,55 +20,35 @@ #include <tuple> #include <QString> -struct CamInfo final -{ - CamInfo() : fov(0), fps(0), res_x(0), res_y(0), idx(-1) {} - double get_focal_length() const; - - double fov; - double fps; - - int res_x; - int res_y; - int idx; -}; - -struct Camera final +struct Camera final : pt_camera { - enum open_status : unsigned { open_error, open_ok_no_change, open_ok_change }; + Camera(); - using result = std::tuple<bool, CamInfo>; + pt_camera_open_status start(int idx, int fps, int res_x, int res_y) override; + void stop() override; - Camera() : dt_mean(0), fov(0) {} + result get_frame(cv::Mat& frame) override; + result get_info() const override; - warn_result_unused open_status start(int idx, int fps, int res_x, int res_y); - void stop(); + pt_camera_info get_desired() const override { return cam_desired; } + QString get_desired_name() const override; + QString get_active_name() const override; - warn_result_unused result get_frame(cv::Mat& frame); - warn_result_unused result get_info() const; + operator bool() const override { return cap && cap->isOpened(); } - CamInfo get_desired() const { return cam_desired; } - QString get_desired_name() const; - QString get_active_name() const; + void set_fov(double value) override { fov = value; } - cv::VideoCapture& operator*() { assert(cap); return *cap; } - const cv::VideoCapture& operator*() const { assert(cap); return *cap; } - cv::VideoCapture* operator->() { assert(cap); return cap.get(); } - const cv::VideoCapture* operator->() const { return cap.get(); } - operator bool() const { return cap && cap->isOpened(); } - - void set_fov(double value) { fov = value; } + void show_camera_settings() override; private: warn_result_unused bool _get_frame(cv::Mat& frame); - double dt_mean; - double fov; + double dt_mean, fov; Timer t; - CamInfo cam_info; - CamInfo cam_desired; + pt_camera_info cam_info; + pt_camera_info cam_desired; QString desired_name, active_name; struct camera_deleter final @@ -82,5 +60,7 @@ private: camera_ptr cap; + pt_settings s; + static constexpr double dt_eps = 1./384; }; diff --git a/tracker-pt/export.hpp b/tracker-pt/export.hpp new file mode 100644 index 00000000..a733c9fe --- /dev/null +++ b/tracker-pt/export.hpp @@ -0,0 +1,11 @@ +// generates export.hpp for each module from compat/linkage.hpp + +#pragma once + +#include "compat/linkage-macros.hpp" + +#ifdef BUILD_TRACKER_PT +# define OTR_PT_EXPORT OTR_GENERIC_EXPORT +#else +# define OTR_PT_EXPORT OTR_GENERIC_IMPORT +#endif diff --git a/tracker-pt/ftnoir_tracker_pt.cpp b/tracker-pt/ftnoir_tracker_pt.cpp index ca81ff40..b2d9bcbe 100644 --- a/tracker-pt/ftnoir_tracker_pt.cpp +++ b/tracker-pt/ftnoir_tracker_pt.cpp @@ -10,15 +10,24 @@ #include "compat/camera-names.hpp" #include "compat/math-imports.hpp" +#include "pt-api.hpp" + #include <cmath> -#include <functional> +#include <utility> + +#include <opencv2/imgproc.hpp> #include <QHBoxLayout> #include <QDebug> #include <QFile> #include <QCoreApplication> -Tracker_PT::Tracker_PT() +using namespace types; + +Tracker_PT::Tracker_PT(const pt_runtime_traits& traits) : + s(traits.get_module_name()), + point_extractor(std::move(traits.make_point_extractor())), + camera(std::move(traits.make_camera())) { cv::setBreakOnError(true); @@ -33,7 +42,7 @@ Tracker_PT::~Tracker_PT() wait(); QMutexLocker l(&camera_mtx); - camera.stop(); + camera->stop(); } void Tracker_PT::run() @@ -48,14 +57,14 @@ void Tracker_PT::run() while(!isInterruptionRequested()) { - CamInfo cam_info; + pt_camera_info cam_info; bool new_frame = false; { QMutexLocker l(&camera_mtx); if (camera) - std::tie(new_frame, cam_info) = camera.get_frame(frame); + std::tie(new_frame, cam_info) = camera->get_frame(frame); } if (new_frame) @@ -64,7 +73,7 @@ void Tracker_PT::run() cv::Size(preview_size.width(), preview_size.height()), 0, 0, cv::INTER_NEAREST); - point_extractor.extract_points(frame, preview_frame, points); + point_extractor->extract_points(frame, preview_frame, points); point_count = points.size(); const double fx = cam_info.get_focal_length(); @@ -120,16 +129,17 @@ void Tracker_PT::maybe_reopen_camera() { QMutexLocker l(&camera_mtx); - Camera::open_status status = camera.start(camera_name_to_index(s.camera_name), s.cam_fps, s.cam_res_x, s.cam_res_y); + pt_camera_open_status status = camera->start(camera_name_to_index(s.camera_name), + s.cam_fps, s.cam_res_x, s.cam_res_y); switch (status) { - case Camera::open_error: + case cam_open_error: break; - case Camera::open_ok_change: + case cam_open_ok_change: frame = cv::Mat(); break; - case Camera::open_ok_no_change: + case cam_open_ok_no_change: break; } } @@ -137,7 +147,7 @@ void Tracker_PT::maybe_reopen_camera() void Tracker_PT::set_fov(int value) { QMutexLocker l(&camera_mtx); - camera.set_fov(value); + camera->set_fov(value); } module_status Tracker_PT::start_tracker(QFrame* video_frame) @@ -228,15 +238,13 @@ int Tracker_PT::get_n_points() return int(point_count); } -bool Tracker_PT::get_cam_info(CamInfo* info) +bool Tracker_PT::get_cam_info(pt_camera_info* info) { QMutexLocker lock(&camera_mtx); bool ret; - std::tie(ret, *info) = camera.get_info(); + std::tie(ret, *info) = camera->get_info(); return ret; } -#include "ftnoir_tracker_pt_dialog.h" -OPENTRACK_DECLARE_TRACKER(Tracker_PT, TrackerDialog_PT, PT_metadata) diff --git a/tracker-pt/ftnoir_tracker_pt.h b/tracker-pt/ftnoir_tracker_pt.h index 8274d62e..9cf14cfd 100644 --- a/tracker-pt/ftnoir_tracker_pt.h +++ b/tracker-pt/ftnoir_tracker_pt.h @@ -9,12 +9,10 @@ #pragma once #include "api/plugin-api.hpp" -#include "ftnoir_tracker_pt_settings.h" #include "cv/numeric.hpp" -#include "camera.h" -#include "point_extractor.h" +#include "pt-api.hpp" #include "point_tracker.h" #include "cv/video-widget.hpp" #include "compat/util.hpp" @@ -25,17 +23,13 @@ #include <opencv2/core.hpp> -#include <QCoreApplication> #include <QThread> #include <QMutex> -#include <QMutexLocker> -#include <QTime> #include <QLayout> -#include <QSize> class TrackerDialog_PT; -namespace impl { +namespace pt_impl { using namespace types; @@ -43,11 +37,10 @@ class Tracker_PT : public QThread, public ITracker { Q_OBJECT - friend class camera_dialog; friend class ::TrackerDialog_PT; public: - Tracker_PT(); + Tracker_PT(const pt_runtime_traits& pt_runtime_traits); ~Tracker_PT() override; module_status start_tracker(QFrame* parent_window) override; void data(double* data) override; @@ -55,7 +48,7 @@ public: Affine pose(); int get_n_points(); - bool get_cam_info(CamInfo* info); + bool get_cam_info(pt_camera_info* info); public slots: void maybe_reopen_camera(); void set_fov(int value); @@ -64,15 +57,16 @@ protected: private: QMutex camera_mtx; QMutex data_mtx; - Camera camera; - PointExtractor point_extractor; - PointTracker point_tracker; + std::unique_ptr<pt_point_extractor> point_extractor; + std::unique_ptr<pt_camera> camera; + PointTracker point_tracker; + + pt_settings s; std::unique_ptr<cv_video_widget> video_widget; std::unique_ptr<QLayout> layout; - settings_pt s; cv::Mat frame, preview_frame; std::vector<vec2> points; @@ -85,12 +79,6 @@ private: //static constexpr float deg2rad = float(M_PI/180); }; -} // ns impl - -class PT_metadata : public Metadata -{ - QString name() { return otr_tr("PointTracker 1.1"); } - QIcon icon() { return QIcon(":/Resources/Logo_IR.png"); } -}; +} // ns pt_impl -using impl::Tracker_PT; +using pt_impl::Tracker_PT; diff --git a/tracker-pt/ftnoir_tracker_pt_dialog.cpp b/tracker-pt/ftnoir_tracker_pt_dialog.cpp index 14fb6f91..350cdb24 100644 --- a/tracker-pt/ftnoir_tracker_pt_dialog.cpp +++ b/tracker-pt/ftnoir_tracker_pt_dialog.cpp @@ -7,17 +7,19 @@ */ #include "ftnoir_tracker_pt_dialog.h" -#include "cv/video-property-page.hpp" #include "compat/camera-names.hpp" #include <opencv2/core.hpp> #include <QString> #include <QDebug> -TrackerDialog_PT::TrackerDialog_PT() - : tracker(nullptr), - timer(this), - trans_calib(1, 2, 0) +using namespace options; + +TrackerDialog_PT::TrackerDialog_PT(const QString& module_name) : + s(module_name), + tracker(nullptr), + timer(this), + trans_calib(1, 2, 0) { ui.setupUi(this); @@ -110,7 +112,7 @@ QString TrackerDialog_PT::threshold_display_text(int threshold_value) return tr("Brightness %1/255").arg(threshold_value); else { - CamInfo info; + pt_camera_info info; int w = s.cam_res_x, h = s.cam_res_y; if (w * h <= 0) @@ -119,7 +121,7 @@ QString TrackerDialog_PT::threshold_display_text(int threshold_value) if (tracker && tracker->get_cam_info(&info) && info.res_x * info.res_y != 0) w = info.res_x, h = info.res_y; - double value = PointExtractor::threshold_radius_value(w, h, threshold_value); + double value = pt_point_extractor::threshold_radius_value(w, h, threshold_value); return tr("LED radius %1 pixels").arg(value, 0, 'f', 2); } @@ -193,7 +195,7 @@ void TrackerDialog_PT::startstop_trans_calib(bool start) void TrackerDialog_PT::poll_tracker_info_impl() { - CamInfo info; + pt_camera_info info; if (tracker && tracker->get_cam_info(&info)) { ui.caminfo_label->setText(tr("%1x%2 @ %3 FPS").arg(info.res_x).arg(info.res_y).arg(iround(info.fps))); @@ -216,23 +218,11 @@ void TrackerDialog_PT::set_camera_settings_available(const QString& /* camera_na void TrackerDialog_PT::show_camera_settings() { - const int idx = ui.camdevice_combo->currentIndex(); - if (tracker) { - if (tracker->camera) - { - cv::VideoCapture& cap = *tracker->camera; - - CamInfo info; - bool status; - std::tie(status, info) = tracker->camera.get_info(); - if (status) - video_property_page::show_from_capture(cap, info.idx); - } + QMutexLocker l(&tracker->camera_mtx); + tracker->camera->show_camera_settings(); } - else - video_property_page::show(idx); } void TrackerDialog_PT::trans_calib_step() diff --git a/tracker-pt/ftnoir_tracker_pt_dialog.h b/tracker-pt/ftnoir_tracker_pt_dialog.h index bae03adc..655e52ca 100644 --- a/tracker-pt/ftnoir_tracker_pt_dialog.h +++ b/tracker-pt/ftnoir_tracker_pt_dialog.h @@ -5,11 +5,10 @@ * copyright notice and this permission notice appear in all copies. */ -#ifndef FTNOIR_TRACKER_PT_DIALOG_H -#define FTNOIR_TRACKER_PT_DIALOG_H +#pragma once + +#include "pt-api.hpp" -#include "api/plugin-api.hpp" -#include "ftnoir_tracker_pt_settings.h" #include "ftnoir_tracker_pt.h" #include "ui_FTNoIR_PT_Controls.h" #include "cv/translation-calibrator.hpp" @@ -23,7 +22,7 @@ class TrackerDialog_PT : public ITrackerDialog { Q_OBJECT public: - TrackerDialog_PT(); + TrackerDialog_PT(const QString& module_name); void register_tracker(ITracker *tracker) override; void unregister_tracker() override; void save(); @@ -41,7 +40,7 @@ signals: private: QString threshold_display_text(int threshold_value); - settings_pt s; + pt_settings s; Tracker_PT* tracker; QTimer timer, calib_timer; TranslationCalibrator trans_calib; @@ -50,5 +49,3 @@ private: Ui::UICPTClientControls ui; }; - -#endif //FTNOIR_TRACKER_PT_DIALOG_H diff --git a/tracker-pt/ftnoir_tracker_pt_settings.h b/tracker-pt/ftnoir_tracker_pt_settings.h deleted file mode 100644 index 7495a328..00000000 --- a/tracker-pt/ftnoir_tracker_pt_settings.h +++ /dev/null @@ -1,85 +0,0 @@ -/* Copyright (c) 2012 Patrick Ruoff - * Copyright (c) 2014-2015 Stanislaw Halik <sthalik@misaki.pl> - * - * 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 "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_natural = 2, - pt_color_red_only = 3, - pt_color_average = 5, - pt_color_blue_only = 6, -}; - -struct settings_pt : opts -{ - settings_pt() : opts("tracker-pt") {} - - value<QString> camera_name { b, "camera-name", "" }; - value<int> cam_res_x { b, "camera-res-width", 640 }, - cam_res_y { b, "camera-res-height", 480 }, - cam_fps { b, "camera-fps", 30 }; - value<double> min_point_size { b, "min-point-size", 2.5 }, - max_point_size { b, "max-point-size", 50 }; - - value<int> m01_x { b, "m_01-x", 0 }, m01_y { b, "m_01-y", 0 }, m01_z { b, "m_01-z", 0 }; - value<int> m02_x { b, "m_02-x", 0 }, m02_y { b, "m_02-y", 0 }, m02_z { b, "m_02-z", 0 }; - - value<int> 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<int> 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<int> 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<int> fov { b, "camera-fov", 56 }; - - value<bool> dynamic_pose { b, "dynamic-pose-resolution", true }; - value<int> init_phase_timeout { b, "init-phase-timeout", 250 }; - value<bool> auto_threshold { b, "automatic-threshold", true }; - value<pt_color_type> blob_color { b, "blob-color", pt_color_natural }; - - value<slider_value> threshold_slider { b, "threshold-slider", slider_value(128, 0, 255) }; - -#if 0 - -#define XSTR(x) #x - -#define M(name, val) \ - { b, "interconnect-m" XSTR(name), (val) } -#define A(name) M(name, 0), -#define B(name) M(name, 1), - - value<double> interconnect[6][6] { - { B(00) A(01) A(02) A(03) A(04) A(05) }, - { A(10) B(11) A(12) A(13) A(14) A(15) }, - { A(20) A(21) B(22) A(23) A(24) A(25) }, - { A(30) A(31) A(32) B(33) A(34) A(35) }, - { A(40) A(41) A(42) A(43) B(44) A(45) }, - { A(50) A(51) A(52) A(53) A(54) B(55) }, - }; - -#undef M -#undef A -#undef B -#undef XSTR - -#endif -}; diff --git a/tracker-pt/module.cpp b/tracker-pt/module.cpp new file mode 100644 index 00000000..0d96c351 --- /dev/null +++ b/tracker-pt/module.cpp @@ -0,0 +1,50 @@ +#include "ftnoir_tracker_pt.h" +#include "api/plugin-api.hpp" + +#include "camera.h" +#include "point_extractor.h" +#include "ftnoir_tracker_pt_dialog.h" + +#include "pt-api.hpp" + +#include <memory> + +static const QString module_name = "tracker-pt"; + +struct pt_module_traits final : pt_runtime_traits +{ + std::unique_ptr<pt_camera> make_camera() const override + { + return std::unique_ptr<pt_camera>(new Camera); + } + + std::unique_ptr<pt_point_extractor> make_point_extractor() const override + { + return std::unique_ptr<pt_point_extractor>(new PointExtractor(module_name)); + } + + QString get_module_name() const override + { + return module_name; + } +}; + +struct pt_tracker_module : Tracker_PT +{ + pt_tracker_module() : Tracker_PT(pt_module_traits()) + { + } +}; + +struct pt_tracker_dialog_module : TrackerDialog_PT +{ + pt_tracker_dialog_module() : TrackerDialog_PT(module_name) {} +}; + +class pt_module_metadata : public Metadata +{ + QString name() { return _("PointTracker 1.1"); } + QIcon icon() { return QIcon(":/Resources/Logo_IR.png"); } +}; + +OPENTRACK_DECLARE_TRACKER(pt_tracker_module, pt_tracker_dialog_module, pt_module_metadata) diff --git a/tracker-pt/point_extractor.cpp b/tracker-pt/point_extractor.cpp index ea7b82a5..464c25db 100644 --- a/tracker-pt/point_extractor.cpp +++ b/tracker-pt/point_extractor.cpp @@ -11,6 +11,7 @@ #include "point_tracker.h" #include <QDebug> +#include "cv/numeric.hpp" #include <opencv2/videoio.hpp> #undef PREVIEW @@ -80,7 +81,7 @@ static cv::Vec2d MeanShiftIteration(const cv::Mat &frame_gray, const vec2 &curre return current_center; } -PointExtractor::PointExtractor() +PointExtractor::PointExtractor(const QString& module_name) : s(module_name) { blobs.reserve(max_blobs); } @@ -194,18 +195,6 @@ void PointExtractor::threshold_image(const cv::Mat& frame_gray, cv::Mat1b& outpu } } -double PointExtractor::threshold_radius_value(int w, int h, int threshold) -{ - double cx = w / 640., cy = h / 480.; - - const double min_radius = 1.75 * cx; - const double max_radius = 15 * cy; - - const double radius = std::fmax(0., (max_radius-min_radius) * threshold / f(255) + min_radius); - - return radius; -} - void PointExtractor::extract_points(const cv::Mat& frame, cv::Mat& preview_frame, std::vector<vec2>& points) { ensure_buffers(frame); @@ -268,7 +257,10 @@ void PointExtractor::extract_points(const cv::Mat& frame, cv::Mat& preview_frame if (radius > region_size_max || radius < region_size_min) continue; - blobs.emplace_back(radius, vec2(rect.width/2., rect.height/2.), std::pow(f(norm), f(1.1))/cnt, rect); + blobs.emplace_back(radius, + vec2(rect.width/2., rect.height/2.), + std::pow(f(norm), f(1.1))/cnt, + rect); if (idx >= max_blobs) goto end; @@ -372,7 +364,7 @@ end: } } -blob::blob(f radius, const vec2& pos, f brightness, cv::Rect& rect) : +blob::blob(f radius, const vec2& pos, f brightness, const cv::Rect& rect) : radius(radius), brightness(brightness), pos(pos), rect(rect) { //qDebug() << "radius" << radius << "pos" << pos[0] << pos[1]; diff --git a/tracker-pt/point_extractor.h b/tracker-pt/point_extractor.h index d31304b9..266964e5 100644 --- a/tracker-pt/point_extractor.h +++ b/tracker-pt/point_extractor.h @@ -8,9 +8,7 @@ #pragma once -#include "ftnoir_tracker_pt_settings.h" -#include "camera.h" -#include "cv/numeric.hpp" +#include "pt-api.hpp" #include <vector> @@ -27,23 +25,21 @@ struct blob vec2 pos; cv::Rect rect; - blob(f radius, const vec2& pos, f brightness, cv::Rect &rect); + blob(f radius, const vec2& pos, f brightness, const cv::Rect& rect); }; -class PointExtractor final +class PointExtractor final : public pt_point_extractor { 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& frame, cv::Mat& preview_frame, std::vector<vec2>& points); - PointExtractor(); - - settings_pt s; - - static double threshold_radius_value(int w, int h, int threshold); + void extract_points(const cv::Mat& frame, cv::Mat& preview_frame, std::vector<vec2>& points) override; + PointExtractor(const QString& module_name); private: static constexpr int max_blobs = 16; + pt_settings s; + cv::Mat1b frame_gray, frame_bin, frame_blobs; cv::Mat1f hist; std::vector<blob> blobs; diff --git a/tracker-pt/point_tracker.cpp b/tracker-pt/point_tracker.cpp index 139e282d..57641d1a 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(const settings_pt& s) +PointModel::PointModel(const pt_settings& s) { set_model(s); // calculate u @@ -47,7 +47,7 @@ PointModel::PointModel(const settings_pt& s) P = 1/(s11*s22-s12*s12) * mat22(s22, -s12, -s12, s11); } -void PointModel::set_model(const settings_pt& s) +void PointModel::set_model(const pt_settings& s) { switch (s.active_model_panel) { @@ -90,7 +90,7 @@ PointTracker::PointTracker() PointTracker::PointOrder PointTracker::find_correspondences_previous(const vec2* points, const PointModel& model, - const CamInfo& info) + const pt_camera_info& info) { const double fx = info.get_focal_length(); PointTracker::PointOrder p; @@ -138,7 +138,7 @@ PointTracker::PointOrder PointTracker::find_correspondences_previous(const vec2* return p; } -bool PointTracker::maybe_use_old_point_order(const PointOrder& order, const CamInfo& info) +bool PointTracker::maybe_use_old_point_order(const PointOrder& order, const pt_camera_info& info) { constexpr f std_width = 640, std_height = 480; @@ -202,7 +202,7 @@ bool PointTracker::maybe_use_old_point_order(const PointOrder& order, const CamI void PointTracker::track(const std::vector<vec2>& points, const PointModel& model, - const CamInfo& info, + const pt_camera_info& info, int init_phase_timeout) { const double fx = info.get_focal_length(); diff --git a/tracker-pt/point_tracker.h b/tracker-pt/point_tracker.h index 3c94535f..816e02de 100644 --- a/tracker-pt/point_tracker.h +++ b/tracker-pt/point_tracker.h @@ -8,10 +8,9 @@ #pragma once #include "compat/timer.hpp" -#include "ftnoir_tracker_pt_settings.h" #include "cv/affine.hpp" #include "cv/numeric.hpp" -#include "camera.h" +#include "pt-api.hpp" #include <opencv2/core.hpp> #include <cstddef> @@ -20,7 +19,7 @@ #include <array> #include <QObject> -namespace impl { +namespace pt_impl { // ---------------------------------------------------------------------------- // Describes a 3-point model @@ -42,8 +41,9 @@ struct PointModel final enum Model { Clip, Cap, Custom }; - PointModel(const settings_pt& s); - void set_model(const settings_pt& s); + PointModel(const pt_settings& s); + void set_model(const pt_settings& s); + void get_d_order(const vec2* points, unsigned* d_order, const vec2& d) const; }; @@ -58,7 +58,7 @@ public: // track the pose using the set of normalized point coordinates (x pos in range -0.5:0.5) // f : (focal length)/(sensor width) // dt : time since last call - void track(const std::vector<vec2>& projected_points, const PointModel& model, const CamInfo& info, int init_phase_timeout); + void track(const std::vector<vec2>& projected_points, const PointModel& model, const pt_camera_info& info, int init_phase_timeout); Affine pose() { return X_CM; } vec2 project(const vec3& v_M, f focal_length); vec2 project(const vec3& v_M, f focal_length, const Affine& X_CM); @@ -68,20 +68,19 @@ private: // the points in model order using PointOrder = std::array<vec2, 3>; - bool maybe_use_old_point_order(const PointOrder& order, const CamInfo& info); - PointOrder prev_order, prev_scaled_order; + bool maybe_use_old_point_order(const PointOrder& order, const pt_camera_info& info); PointOrder find_correspondences(const vec2* projected_points, const PointModel &model); - PointOrder find_correspondences_previous(const vec2* points, const PointModel &model, const CamInfo& info); + PointOrder find_correspondences_previous(const vec2* points, const PointModel &model, const pt_camera_info& info); int POSIT(const PointModel& point_model, const PointOrder& order, f focal_length); // The POSIT algorithm, returns the number of iterations Affine X_CM; // transform from model to camera - + PointOrder prev_order, prev_scaled_order; Timer t; bool init_phase = true, prev_order_valid = false; }; -} // ns types +} // ns pt_impl -using impl::PointTracker; -using impl::PointModel; +using pt_impl::PointTracker; +using pt_impl::PointModel; diff --git a/tracker-pt/pt-api.cpp b/tracker-pt/pt-api.cpp new file mode 100644 index 00000000..c11f372f --- /dev/null +++ b/tracker-pt/pt-api.cpp @@ -0,0 +1,62 @@ +#include "pt-api.hpp" +#include "cv/numeric.hpp" + +using namespace types; + +pt_camera_info::pt_camera_info() +{ +} + +double pt_camera_info::get_focal_length() const +{ + const double diag_len = std::sqrt(double(res_x*res_x + res_y*res_y)); + const double aspect_x = res_x / diag_len; + //const double aspect_y = res_y / diag_len; + const double diag_fov = fov * M_PI/180; + const double fov_x = 2*std::atan(std::tan(diag_fov*.5) * aspect_x); + //const double fov_y = 2*atan(tan(diag_fov*.5) * aspect_y); + const double fx = .5 / std::tan(fov_x * .5); + return fx; + //fy = .5 / tan(fov_y * .5); + //static bool once = false; if (!once) { once = true; qDebug() << "f" << ret << "fov" << (fov * 180/M_PI); } +} + +pt_settings::pt_settings(const QString& name) : opts(name) +{ +} + +pt_camera::pt_camera() +{ +} + +pt_camera::~pt_camera() +{ +} + +pt_runtime_traits::pt_runtime_traits() +{ +} + +pt_runtime_traits::~pt_runtime_traits() +{ +} + +pt_point_extractor::pt_point_extractor() +{ +} + +pt_point_extractor::~pt_point_extractor() +{ +} + +double pt_point_extractor::threshold_radius_value(int w, int h, int threshold) +{ + double cx = w / 640., cy = h / 480.; + + const double min_radius = 1.75 * cx; + const double max_radius = 15 * cy; + + const double radius = std::fmax(0., (max_radius-min_radius) * threshold / f(255) + min_radius); + + return radius; +} diff --git a/tracker-pt/pt-api.hpp b/tracker-pt/pt-api.hpp new file mode 100644 index 00000000..79a47526 --- /dev/null +++ b/tracker-pt/pt-api.hpp @@ -0,0 +1,119 @@ +#pragma once + +#include "export.hpp" + +#include "cv/numeric.hpp" +#include "options/options.hpp" + +#include <memory> + +#include <opencv2/core.hpp> + +struct OTR_PT_EXPORT pt_camera_info final +{ + pt_camera_info(); + virtual double get_focal_length() const; + + double fov = 0; + double fps = 0; + + int res_x = 0; + int res_y = 0; + int idx = -1; +}; + +enum pt_camera_open_status : unsigned { cam_open_error, cam_open_ok_no_change, cam_open_ok_change }; + +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, +}; + +struct OTR_PT_EXPORT pt_camera +{ + using result = std::tuple<bool, pt_camera_info>; + + pt_camera(); + virtual ~pt_camera(); + + virtual warn_result_unused pt_camera_open_status start(int idx, int fps, int res_x, int res_y) = 0; + virtual void stop() = 0; + virtual warn_result_unused result get_frame(cv::Mat& frame) = 0; + + virtual warn_result_unused result get_info() const = 0; + virtual pt_camera_info get_desired() const = 0; + + virtual QString get_desired_name() const = 0; + virtual QString get_active_name() const = 0; + + virtual void set_fov(double value) = 0; + virtual operator bool() const = 0; + + virtual void show_camera_settings() = 0; +}; + +struct OTR_PT_EXPORT pt_point_extractor +{ + using vec2 = types::vec2; + + pt_point_extractor(); + virtual ~pt_point_extractor(); + virtual void extract_points(const cv::Mat& frame, cv::Mat& preview_frame, std::vector<vec2>& points) = 0; + + static double threshold_radius_value(int w, int h, int threshold); +}; + +struct OTR_PT_EXPORT pt_settings final : options::opts +{ + using slider_value = options::slider_value; + + pt_settings(const QString& name); + + value<QString> camera_name { b, "camera-name", "" }; + value<int> cam_res_x { b, "camera-res-width", 640 }, + cam_res_y { b, "camera-res-height", 480 }, + cam_fps { b, "camera-fps", 30 }; + value<double> min_point_size { b, "min-point-size", 2.5 }, + max_point_size { b, "max-point-size", 50 }; + + value<int> m01_x { b, "m_01-x", 0 }, m01_y { b, "m_01-y", 0 }, m01_z { b, "m_01-z", 0 }; + value<int> m02_x { b, "m_02-x", 0 }, m02_y { b, "m_02-y", 0 }, m02_z { b, "m_02-z", 0 }; + + value<int> 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<int> 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<int> 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<int> fov { b, "camera-fov", 56 }; + + value<bool> dynamic_pose { b, "dynamic-pose-resolution", true }; + value<int> init_phase_timeout { b, "init-phase-timeout", 250 }; + value<bool> auto_threshold { b, "automatic-threshold", true }; + value<pt_color_type> blob_color { b, "blob-color", pt_color_natural }; + + value<slider_value> threshold_slider { b, "threshold-slider", slider_value(128, 0, 255) }; +}; + +struct OTR_PT_EXPORT pt_runtime_traits +{ + pt_runtime_traits(); + virtual ~pt_runtime_traits(); + + virtual std::unique_ptr<pt_camera> make_camera() const = 0; + virtual std::unique_ptr<pt_point_extractor> make_point_extractor() const = 0; + virtual QString get_module_name() const = 0; +}; |