summaryrefslogtreecommitdiffhomepage
diff options
context:
space:
mode:
-rw-r--r--tracker-pt/camera.cpp50
-rw-r--r--tracker-pt/camera.h56
-rw-r--r--tracker-pt/export.hpp11
-rw-r--r--tracker-pt/ftnoir_tracker_pt.cpp38
-rw-r--r--tracker-pt/ftnoir_tracker_pt.h34
-rw-r--r--tracker-pt/ftnoir_tracker_pt_dialog.cpp34
-rw-r--r--tracker-pt/ftnoir_tracker_pt_dialog.h13
-rw-r--r--tracker-pt/ftnoir_tracker_pt_settings.h85
-rw-r--r--tracker-pt/module.cpp50
-rw-r--r--tracker-pt/point_extractor.cpp22
-rw-r--r--tracker-pt/point_extractor.h18
-rw-r--r--tracker-pt/point_tracker.cpp10
-rw-r--r--tracker-pt/point_tracker.h25
-rw-r--r--tracker-pt/pt-api.cpp62
-rw-r--r--tracker-pt/pt-api.hpp119
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;
+};