diff options
| -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; +}; | 
