summaryrefslogtreecommitdiffhomepage
path: root/ftnoir_tracker_pt
diff options
context:
space:
mode:
authorStanislaw Halik <sthalik@misaki.pl>2014-12-14 23:29:53 +0100
committerStanislaw Halik <sthalik@misaki.pl>2014-12-14 23:29:53 +0100
commit2294a2866cf6ee48b8f4557c0fd47ad2fe112a4a (patch)
tree28bcc5a015f7a702ef22221c70aec0f958d20125 /ftnoir_tracker_pt
parent800f5872ba8d67284016e3b7b61b1c955fa9b1eb (diff)
pt: use settings framework
Issue: #96 Model values are recomputed every frame. This shouldn't matter, as there's very little to compute. With this change, sliders and other options are applied immediately, and the "Apply" button is gone.
Diffstat (limited to 'ftnoir_tracker_pt')
-rw-r--r--ftnoir_tracker_pt/FTNoIR_PT_Controls.ui44
-rw-r--r--ftnoir_tracker_pt/ftnoir_tracker_pt.cpp40
-rw-r--r--ftnoir_tracker_pt/ftnoir_tracker_pt.h13
-rw-r--r--ftnoir_tracker_pt/ftnoir_tracker_pt_dialog.cpp74
-rw-r--r--ftnoir_tracker_pt/ftnoir_tracker_pt_dialog.h9
-rw-r--r--ftnoir_tracker_pt/ftnoir_tracker_pt_settings.h1
-rw-r--r--ftnoir_tracker_pt/point_extractor.cpp17
-rw-r--r--ftnoir_tracker_pt/point_extractor.h9
-rw-r--r--ftnoir_tracker_pt/point_tracker.cpp20
-rw-r--r--ftnoir_tracker_pt/point_tracker.h46
10 files changed, 86 insertions, 187 deletions
diff --git a/ftnoir_tracker_pt/FTNoIR_PT_Controls.ui b/ftnoir_tracker_pt/FTNoIR_PT_Controls.ui
index 109e50cb..88b65e7e 100644
--- a/ftnoir_tracker_pt/FTNoIR_PT_Controls.ui
+++ b/ftnoir_tracker_pt/FTNoIR_PT_Controls.ui
@@ -42,13 +42,6 @@
<string>Status</string>
</property>
<layout class="QGridLayout" name="gridLayout_10">
- <item row="2" column="2">
- <widget class="QDialogButtonBox" name="buttonBox">
- <property name="standardButtons">
- <set>QDialogButtonBox::Cancel|QDialogButtonBox::Ok</set>
- </property>
- </widget>
- </item>
<item row="1" column="0">
<widget class="QLabel" name="label_3">
<property name="text">
@@ -56,6 +49,13 @@
</property>
</widget>
</item>
+ <item row="2" column="1">
+ <widget class="QDialogButtonBox" name="buttonBox">
+ <property name="standardButtons">
+ <set>QDialogButtonBox::Cancel|QDialogButtonBox::Ok</set>
+ </property>
+ </widget>
+ </item>
<item row="0" column="0">
<widget class="QLabel" name="label_38">
<property name="text">
@@ -63,17 +63,20 @@
</property>
</widget>
</item>
- <item row="2" column="1">
- <widget class="QDialogButtonBox" name="buttonBox_2">
- <property name="standardButtons">
- <set>QDialogButtonBox::Apply</set>
+ <item row="1" column="1">
+ <widget class="QLabel" name="pointinfo_label">
+ <property name="minimumSize">
+ <size>
+ <width>50</width>
+ <height>0</height>
+ </size>
</property>
- <property name="centerButtons">
- <bool>true</bool>
+ <property name="text">
+ <string/>
</property>
</widget>
</item>
- <item row="0" column="2">
+ <item row="0" column="1">
<widget class="QLabel" name="caminfo_label">
<property name="sizePolicy">
<sizepolicy hsizetype="Preferred" vsizetype="Preferred">
@@ -92,19 +95,6 @@
</property>
</widget>
</item>
- <item row="1" column="2">
- <widget class="QLabel" name="pointinfo_label">
- <property name="minimumSize">
- <size>
- <width>50</width>
- <height>0</height>
- </size>
- </property>
- <property name="text">
- <string/>
- </property>
- </widget>
- </item>
</layout>
</widget>
</item>
diff --git a/ftnoir_tracker_pt/ftnoir_tracker_pt.cpp b/ftnoir_tracker_pt/ftnoir_tracker_pt.cpp
index 3abaa35e..61216000 100644
--- a/ftnoir_tracker_pt/ftnoir_tracker_pt.cpp
+++ b/ftnoir_tracker_pt/ftnoir_tracker_pt.cpp
@@ -21,10 +21,10 @@ using namespace cv;
Tracker::Tracker()
: mutex(QMutex::Recursive),
commands(0),
- video_widget(NULL),
- video_frame(NULL),
- new_settings(nullptr)
+ video_widget(NULL),
+ video_frame(NULL)
{
+ connect(s.b.get(), SIGNAL(saving()), this, SLOT(apply_settings()));
}
Tracker::~Tracker()
@@ -65,7 +65,6 @@ void Tracker::run()
while((commands & ABORT) == 0)
{
- apply_inner();
const double dt = time.elapsed() * 1e-9;
time.start();
cv::Mat frame;
@@ -92,7 +91,7 @@ void Tracker::run()
4);
}
if (points.size() == PointModel::N_POINTS)
- point_tracker.track(points, model, get_focal_length());
+ point_tracker.track(points, PointModel(s), get_focal_length());
video_widget->update_image(frame);
}
#ifdef PT_PERF_LOG
@@ -103,36 +102,14 @@ void Tracker::run()
}
qDebug()<<"Tracker:: Thread stopping";
}
-void Tracker::apply(settings& s)
-{
- // caller guarantees object lifetime
- new_settings = &s;
-}
-void Tracker::apply_inner()
+void Tracker::apply_settings()
{
- // XXX this nonsense oughta reference settings directly,
- // rather than keep its own state -sh 20141102
- // applies to -- camera, extractor, this tracker class
- settings* tmp = new_settings.exchange(nullptr);
- if (tmp == nullptr)
- return;
- auto& s = *tmp;
qDebug()<<"Tracker:: Applying settings";
-
- {
- cv::Vec3f M01(s.m01_x, s.m01_y, s.m01_z);
- cv::Vec3f M02(s.m02_x, s.m02_y, s.m02_z);
- model = PointModel(M01, M02);
- }
+ QMutexLocker lock(&mutex);
camera.set_device_index(s.cam_index);
camera.set_res(s.cam_res_x, s.cam_res_y);
camera.set_fps(s.cam_fps);
- point_extractor.threshold_val = s.threshold;
- point_extractor.threshold_secondary_val = s.threshold_secondary;
- point_extractor.min_size = s.min_point_size;
- point_extractor.max_size = s.max_point_size;
- t_MH = cv::Vec3f(s.t_MH_x, s.t_MH_y, s.t_MH_z);
qDebug()<<"Tracker::apply ends";
}
@@ -147,8 +124,7 @@ void Tracker::start_tracker(QFrame *parent_window)
video_layout->addWidget(video_widget);
video_frame->setLayout(video_layout);
video_widget->resize(video_frame->width(), video_frame->height());
- apply(s);
- apply_inner();
+ apply_settings();
camera.start();
start();
}
@@ -169,7 +145,7 @@ void Tracker::data(THeadPoseData *data)
Affine X_CM = point_tracker.pose();
- Affine X_MH(Matx33f::eye(), t_MH);
+ Affine X_MH(Matx33f::eye(), cv::Vec3f(s.t_MH_x, s.t_MH_y, s.t_MH_z));
Affine X_GH = X_CM * X_MH;
Matx33f R = X_GH.R;
diff --git a/ftnoir_tracker_pt/ftnoir_tracker_pt.h b/ftnoir_tracker_pt/ftnoir_tracker_pt.h
index 3dd15618..8e4d58ee 100644
--- a/ftnoir_tracker_pt/ftnoir_tracker_pt.h
+++ b/ftnoir_tracker_pt/ftnoir_tracker_pt.h
@@ -33,20 +33,20 @@
//-----------------------------------------------------------------------------
// Constantly processes the tracking chain in a separate thread
-class Tracker : public ITracker, protected QThread
+class Tracker : public QThread, public ITracker
{
+ Q_OBJECT
public:
Tracker();
~Tracker() override;
void start_tracker(QFrame* parent_window) override;
void data(double* data) override;
- void apply(settings& s);
- void apply_inner();
-
void pose(Affine* X_CM) { QMutexLocker lock(&mutex); *X_CM = point_tracker.pose(); }
int get_n_points() { QMutexLocker lock(&mutex); return point_extractor.get_points().size(); }
void get_cam_info(CamInfo* info) { QMutexLocker lock(&mutex); *info = camera.get_info(); }
+public slots:
+ void apply_settings();
protected:
void run() override;
private:
@@ -66,19 +66,14 @@ private:
PointExtractor point_extractor;
PointTracker point_tracker;
- cv::Vec3f t_MH; // translation from model frame to head frame
-
PTVideoWidget* video_widget;
QFrame* video_frame;
settings s;
- std::atomic<settings*> new_settings;
Timer time;
static constexpr double rad2deg = 180.0/3.14159265;
static constexpr double deg2rad = 3.14159265/180.0;
-
- PointModel model;
};
#undef VideoWidget
diff --git a/ftnoir_tracker_pt/ftnoir_tracker_pt_dialog.cpp b/ftnoir_tracker_pt/ftnoir_tracker_pt_dialog.cpp
index 8f6edc2f..98dbfb7b 100644
--- a/ftnoir_tracker_pt/ftnoir_tracker_pt_dialog.cpp
+++ b/ftnoir_tracker_pt/ftnoir_tracker_pt_dialog.cpp
@@ -67,53 +67,16 @@ TrackerDialog::TrackerDialog()
tie_setting(s.t_MH_z, ui.tz_spin);
tie_setting(s.fov, ui.fov);
+
+ tie_setting(s.active_model_panel, ui.model_tabs);
connect( ui.tcalib_button,SIGNAL(toggled(bool)), this,SLOT(startstop_trans_calib(bool)) );
- connect(ui.buttonBox, SIGNAL(accepted()), this, SLOT(doOK()));
+ connect(ui.buttonBox, SIGNAL(accepted()), this, SLOT(doOK()));
connect(ui.buttonBox, SIGNAL(rejected()), this, SLOT(doCancel()));
- ui.model_tabs->setCurrentIndex(s.active_model_panel);
-
- connect(ui.model_tabs, SIGNAL(currentChanged(int)), this, SLOT(set_model(int)));
connect(&timer,SIGNAL(timeout()), this,SLOT(poll_tracker_info()));
timer.start(100);
-
- connect(ui.buttonBox_2, SIGNAL(clicked(QAbstractButton*)), this, SLOT(do_apply_without_saving(QAbstractButton*)));
-}
-
-void TrackerDialog::set_model_clip()
-{
- s.m01_x = 0;
- s.m01_y = static_cast<double>(s.clip_ty);
- s.m01_z = -static_cast<double>(s.clip_tz);
- s.m02_x = 0;
- s.m02_y = -static_cast<double>(s.clip_by);
- s.m02_z = -static_cast<double>(s.clip_bz);
-
- settings_changed();
-}
-
-void TrackerDialog::set_model_cap()
-{
- s.m01_x = -static_cast<double>(s.cap_x);
- s.m01_y = -static_cast<double>(s.cap_y);
- s.m01_z = -static_cast<double>(s.cap_z);
- s.m02_x = static_cast<double>(s.cap_x);
- s.m02_y = -static_cast<double>(s.cap_y);
- s.m02_z = -static_cast<double>(s.cap_z);
-
- settings_changed();
-}
-
-void TrackerDialog::set_model_custom()
-{
- settings_changed();
-}
-
-void TrackerDialog::set_model(int val)
-{
- s.active_model_panel = val;
}
void TrackerDialog::startstop_trans_calib(bool start)
@@ -134,7 +97,6 @@ void TrackerDialog::startstop_trans_calib(bool start)
s.t_MH_y = tmp[1];
s.t_MH_z = tmp[2];
}
- settings_changed();
}
}
@@ -184,14 +146,8 @@ void TrackerDialog::trans_calib_step()
}
}
-void TrackerDialog::settings_changed()
-{
- if (tracker) tracker->apply(s);
-}
-
void TrackerDialog::save()
{
- do_apply_without_saving(nullptr);
s.b->save();
}
@@ -201,28 +157,6 @@ void TrackerDialog::doOK()
close();
}
-void TrackerDialog::do_apply_without_saving(QAbstractButton*)
-{
- switch (s.active_model_panel) {
- default:
- case 0:
- set_model_clip();
- break;
- case 1:
- set_model_cap();
- break;
- case 2:
- set_model_custom();
- break;
- }
- if (tracker) tracker->apply(s);
-}
-
-void TrackerDialog::doApply()
-{
- save();
-}
-
void TrackerDialog::doCancel()
{
s.b->reload();
@@ -233,8 +167,6 @@ void TrackerDialog::register_tracker(ITracker *t)
{
qDebug()<<"TrackerDialog:: Tracker registered";
tracker = static_cast<Tracker*>(t);
- if (isVisible() & s.b->modifiedp())
- tracker->apply(s);
ui.tcalib_button->setEnabled(true);
//ui.center_button->setEnabled(true);
}
diff --git a/ftnoir_tracker_pt/ftnoir_tracker_pt_dialog.h b/ftnoir_tracker_pt/ftnoir_tracker_pt_dialog.h
index 7f634c04..c6f7f8e1 100644
--- a/ftnoir_tracker_pt/ftnoir_tracker_pt_dialog.h
+++ b/ftnoir_tracker_pt/ftnoir_tracker_pt_dialog.h
@@ -36,19 +36,10 @@ public:
public slots:
void doOK();
void doCancel();
- void doApply();
- void do_apply_without_saving(QAbstractButton *);
void startstop_trans_calib(bool start);
void poll_tracker_info();
- void set_model(int idx);
private:
- void set_model_clip();
- void set_model_cap();
- void set_model_custom();
-
- void settings_changed();
-
settings s;
Tracker* tracker;
QTimer timer;
diff --git a/ftnoir_tracker_pt/ftnoir_tracker_pt_settings.h b/ftnoir_tracker_pt/ftnoir_tracker_pt_settings.h
index 804de22e..bce89058 100644
--- a/ftnoir_tracker_pt/ftnoir_tracker_pt_settings.h
+++ b/ftnoir_tracker_pt/ftnoir_tracker_pt_settings.h
@@ -9,7 +9,6 @@
#define FTNOIR_TRACKER_PT_SETTINGS_H
#include <opencv2/core/core.hpp>
-#include "point_tracker.h"
#include "opentrack/options.hpp"
using namespace options;
diff --git a/ftnoir_tracker_pt/point_extractor.cpp b/ftnoir_tracker_pt/point_extractor.cpp
index 819bf5e8..f4eefb0f 100644
--- a/ftnoir_tracker_pt/point_extractor.cpp
+++ b/ftnoir_tracker_pt/point_extractor.cpp
@@ -37,7 +37,8 @@ const vector<Vec2f>& PointExtractor::extract_points(Mat& frame)
Mat frame_gray;
cvtColor(frame, frame_gray, CV_RGB2GRAY);
- int secondary = threshold_secondary_val;
+ int secondary = s.threshold_secondary;
+ int primary = s.threshold;
// mask for everything that passes the threshold (or: the upper threshold of the hysteresis)
Mat frame_bin;
@@ -49,15 +50,15 @@ const vector<Vec2f>& PointExtractor::extract_points(Mat& frame)
Mat frame_last_and_low;
if(secondary==0){
- threshold(frame_gray, frame_bin, threshold_val, 255, THRESH_BINARY);
+ threshold(frame_gray, frame_bin, primary, 255, THRESH_BINARY);
}else{
// we recombine a number of buffers, this might be slower than a single loop of per-pixel logic
// but it might as well be faster if openCV makes good use of SIMD
- float t = threshold_val;
+ float t = primary;
//float hyst = float(threshold_secondary_val)/512.;
//threshold(frame_gray, frame_bin, (t + ((255.-t)*hyst)), 255, THRESH_BINARY);
- float hyst = float(threshold_secondary_val)/256.;
- threshold(frame_gray, frame_bin, t, 255, THRESH_BINARY);
+ float hyst = float(primary)/256.;
+ threshold(frame_gray, frame_bin, t, 255, THRESH_BINARY);
threshold(frame_gray, frame_bin_low,std::max(float(1), t - (t*hyst)), 255, THRESH_BINARY);
frame_bin.copyTo(frame_bin_copy);
@@ -71,6 +72,10 @@ const vector<Vec2f>& PointExtractor::extract_points(Mat& frame)
frame_last.copyTo(frame_bin);
}
}
+
+ int min_size = s.min_point_size;
+ int max_size = s.max_point_size;
+
unsigned int region_size_min = 3.14*min_size*min_size/4.0;
unsigned int region_size_max = 3.14*max_size*max_size/4.0;
@@ -118,7 +123,7 @@ const vector<Vec2f>& PointExtractor::extract_points(Mat& frame)
if(secondary==0){
val = frame_gray.at<unsigned char>(i,j);
- val = float(val - threshold_val)/(256 - threshold_val);
+ val = float(val - primary)/(256 - primary);
val = val*val; // makes it more stable (less emphasis on low values, more on the peak)
}else{
//hysteresis point detection gets stability from ignoring pixel noise so we decidedly leave the actual pixel values out of the picture
diff --git a/ftnoir_tracker_pt/point_extractor.h b/ftnoir_tracker_pt/point_extractor.h
index 5252b68d..2cac29a9 100644
--- a/ftnoir_tracker_pt/point_extractor.h
+++ b/ftnoir_tracker_pt/point_extractor.h
@@ -11,6 +11,8 @@
#include <opencv2/core/core.hpp>
#include <opencv2/imgproc/imgproc.hpp>
+#include "ftnoir_tracker_pt_settings.h"
+
// ----------------------------------------------------------------------------
// Extracts points from an opencv image
class PointExtractor
@@ -22,11 +24,8 @@ public:
const std::vector<cv::Vec2f>& extract_points(cv::Mat &frame);
const std::vector<cv::Vec2f>& get_points() { return points; }
PointExtractor();
-
- int threshold_val;
- int threshold_secondary_val;
- int min_size, max_size;
-
+
+ settings s;
private:
std::vector<cv::Vec2f> points;
cv::Mat frame_last;
diff --git a/ftnoir_tracker_pt/point_tracker.cpp b/ftnoir_tracker_pt/point_tracker.cpp
index 9f04af30..3fdc60ef 100644
--- a/ftnoir_tracker_pt/point_tracker.cpp
+++ b/ftnoir_tracker_pt/point_tracker.cpp
@@ -33,26 +33,6 @@ static void set_row(Matx33f& m, int i, const Vec3f& v)
m(i,2) = v[2];
}
-PointModel::PointModel() :
- M01 { 0, 0, 0 },
- M02 { 0, 0, 0 }
-{
-}
-
-PointModel::PointModel(Vec3f M01, Vec3f M02)
- : M01(M01), M02(M02)
-{
- // calculate u
- u = M01.cross(M02);
- u /= norm(u);
-
- // calculate projection matrix on M01,M02 plane
- float s11 = M01.dot(M01);
- float s12 = M01.dot(M02);
- float s22 = M02.dot(M02);
- P = 1.0/(s11*s22-s12*s12) * Matx22f(s22, -s12, -s12, s11);
-}
-
#ifdef OPENTRACK_API
static bool d_vals_sort(const pair<float,int> a, const pair<float,int> b)
{
diff --git a/ftnoir_tracker_pt/point_tracker.h b/ftnoir_tracker_pt/point_tracker.h
index d37fb726..83c7dc00 100644
--- a/ftnoir_tracker_pt/point_tracker.h
+++ b/ftnoir_tracker_pt/point_tracker.h
@@ -16,6 +16,10 @@
#endif
#include <vector>
+#include "ftnoir_tracker_pt_settings.h"
+
+#include <QObject>
+
// ----------------------------------------------------------------------------
// Affine frame trafo
class Affine
@@ -59,13 +63,6 @@ class PointModel
public:
static constexpr int N_POINTS = 3;
- PointModel(cv::Vec3f M01, cv::Vec3f M02);
- PointModel();
-
- inline const cv::Vec3f& get_M01() const { return M01; }
- inline const cv::Vec3f& get_M02() const { return M02; }
-
-private:
cv::Vec3f M01; // M01 in model frame
cv::Vec3f M02; // M02 in model frame
@@ -73,6 +70,41 @@ private:
cv::Matx22f P;
+ enum Model { Clip = 0, Cap = 1, Custom = 2 };
+
+ PointModel(settings& s)
+ {
+ set_model(s);
+ // calculate u
+ u = M01.cross(M02);
+ u /= norm(u);
+
+ // calculate projection matrix on M01,M02 plane
+ float s11 = M01.dot(M01);
+ float s12 = M01.dot(M02);
+ float s22 = M02.dot(M02);
+ P = 1.0/(s11*s22-s12*s12) * cv::Matx22f(s22, -s12, -s12, s11);
+ }
+
+ void set_model(settings& s)
+ {
+ switch (s.active_model_panel)
+ {
+ case Clip:
+ M01 = cv::Vec3f(0, static_cast<double>(s.clip_ty), -static_cast<double>(s.clip_tz));
+ M02 = cv::Vec3f(0, -static_cast<double>(s.clip_by), -static_cast<double>(s.clip_bz));
+ break;
+ case Cap:
+ M01 = cv::Vec3f(-static_cast<double>(s.cap_x), -static_cast<double>(s.cap_y), -static_cast<double>(s.cap_z));
+ M02 = cv::Vec3f(static_cast<double>(s.cap_x), -static_cast<double>(s.cap_y), -static_cast<double>(s.cap_z));
+ break;
+ case Custom:
+ M01 = cv::Vec3f(s.m01_x, s.m01_y, s.m01_z);
+ M02 = cv::Vec3f(s.m02_x, s.m02_y, s.m02_z);
+ break;
+ }
+ }
+
template<typename vec>
void get_d_order(const std::vector<vec>& points, int* d_order, vec d) const;
};