diff options
-rw-r--r-- | ftnoir_tracker_pt/FTNoIR_PT_Controls.ui | 44 | ||||
-rw-r--r-- | ftnoir_tracker_pt/ftnoir_tracker_pt.cpp | 40 | ||||
-rw-r--r-- | ftnoir_tracker_pt/ftnoir_tracker_pt.h | 13 | ||||
-rw-r--r-- | ftnoir_tracker_pt/ftnoir_tracker_pt_dialog.cpp | 74 | ||||
-rw-r--r-- | ftnoir_tracker_pt/ftnoir_tracker_pt_dialog.h | 9 | ||||
-rw-r--r-- | ftnoir_tracker_pt/ftnoir_tracker_pt_settings.h | 1 | ||||
-rw-r--r-- | ftnoir_tracker_pt/point_extractor.cpp | 17 | ||||
-rw-r--r-- | ftnoir_tracker_pt/point_extractor.h | 9 | ||||
-rw-r--r-- | ftnoir_tracker_pt/point_tracker.cpp | 20 | ||||
-rw-r--r-- | ftnoir_tracker_pt/point_tracker.h | 46 |
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; }; |