From bfdec03aaecfa3c6d67e9a87be95e703e73a845e Mon Sep 17 00:00:00 2001
From: Stanislaw Halik <sthalik@misaki.pl>
Date: Sun, 12 Jul 2015 06:46:03 +0200
Subject: ht: include in DLL, not as subprocess

---
 ftnoir_tracker_ht/ftnoir_tracker_ht.cpp | 152 +++++++++++++++++++++-----------
 ftnoir_tracker_ht/ftnoir_tracker_ht.h   |  41 +++++----
 ftnoir_tracker_ht/ht-api.h              |   6 +-
 ftnoir_tracker_ht/stdafx.h              |  13 ---
 4 files changed, 128 insertions(+), 84 deletions(-)

(limited to 'ftnoir_tracker_ht')

diff --git a/ftnoir_tracker_ht/ftnoir_tracker_ht.cpp b/ftnoir_tracker_ht/ftnoir_tracker_ht.cpp
index 3d142dcb..deb90ee5 100644
--- a/ftnoir_tracker_ht/ftnoir_tracker_ht.cpp
+++ b/ftnoir_tracker_ht/ftnoir_tracker_ht.cpp
@@ -44,49 +44,49 @@ void Tracker::load_settings(ht_config_t* config)
 
     config->classification_delay = 500;
     config->field_of_view = s.fov;
-    config->pyrlk_pyramids = 0;
-    config->pyrlk_win_size_w = config->pyrlk_win_size_h = 21;
     config->max_keypoints = 150;
-    config->keypoint_distance = 3.5;
+    config->keypoint_distance = 3.4;
     config->force_fps = nframes;
     config->camera_index = camera_name_to_index(s.camera_name);
-    config->ransac_num_iters = 100;
-    config->ransac_max_reprojection_error = 10;
-    config->ransac_max_inlier_error = 10;
-    config->ransac_abs_max_mean_error = 14;
-    config->ransac_max_mean_error = 8;
+
+    config->ransac_max_reprojection_error = 8;
+    config->ransac_max_inlier_error = 8;
+
+    config->pyrlk_pyramids = 0;
+    config->pyrlk_win_size_w = config->pyrlk_win_size_h = 21;
+
+    config->ransac_max_mean_error = 999;
+    config->ransac_abs_max_mean_error = 999;
+
     config->debug = 0;
-    config->ransac_min_features = 0.8;
+    config->ransac_min_features = 0.85;
+    config->ransac_num_iters = 300;
+
     int res = s.resolution;
     if (res < 0 || res >= (int)(sizeof(resolution_choices) / sizeof(resolution_tuple)))
 		res = 0;
 	resolution_tuple r = resolution_choices[res];
 	config->force_width = r.width;
     config->force_height = r.height;
-    config->flandmark_delay = 500;
+    config->flandmark_delay = 50;
     for (int i = 0; i < 5; i++)
         config->dist_coeffs[i] = 0;
 }
 
 Tracker::Tracker() :
-    lck_shm(HT_SHM_NAME, HT_MUTEX_NAME, sizeof(ht_shm_t)),
-    shm(reinterpret_cast<ht_shm_t*>(lck_shm.ptr())),
+    ht(nullptr),
+    ypr {0,0,0, 0,0,0},
     videoWidget(nullptr),
-    layout(nullptr)
+    layout(nullptr),
+    should_stop(false)
 {
-    shm->terminate = 0;
-    shm->result.filled = false;
 }
 
 Tracker::~Tracker()
 {
-    if (shm) {
-        shm->terminate = true;
-        subprocess.waitForFinished(5000);
-    }
-    subprocess.kill();
-    if (shm)
-        shm->terminate = true;
+    should_stop = true;
+    wait();
+    ht_free_context(ht);
 	if (layout)
 		delete layout;
 	if (videoWidget)
@@ -105,41 +105,81 @@ void Tracker::start_tracker(QFrame* videoframe)
     videoframe->setLayout(layout);
     videoWidget->show();
     this->layout = layout;
-    load_settings(&shm->config);
-    shm->frame.channels = shm->frame.width = shm->frame.height = 0;
-    shm->pause = shm->terminate = shm->running = false;
-    shm->timer = 0;
-    shm->result.filled = false;
-    subprocess.setProcessChannelMode(QProcess::ForwardedChannels);
-    subprocess.setWorkingDirectory(QCoreApplication::applicationDirPath() + "/tracker-ht");
-#if defined(_WIN32)
-    subprocess.start("\"" + QCoreApplication::applicationDirPath() + "/tracker-ht/headtracker-ftnoir" + "\"");
-#else
-    subprocess.start(QCoreApplication::applicationDirPath() + "/tracker-ht/headtracker-ftnoir");
-#endif
+
+    load_settings(&conf);
+    ht = ht_make_context(&conf, nullptr);
+    start();
+}
+
+void Tracker::run()
+{
+    while (!should_stop)
+    {
+        ht_result_t euler;
+        euler.filled = false;
+        {
+            QMutexLocker l(&camera_mtx);
+
+            if (!ht_cycle(ht, &euler))
+                break;
+        }
+        if (euler.filled)
+        {
+            QMutexLocker l(&ypr_mtx);
+            ypr[TX] = euler.tx;
+            ypr[TY] = euler.ty;
+            ypr[TZ] = euler.tz;
+            ypr[Yaw] = euler.rotx;
+            ypr[Pitch] = euler.roty;
+            ypr[Roll] = euler.rotz;
+        }
+        {
+            const cv::Mat frame_ = ht_get_bgr_frame(ht);
+            if (frame_.cols <= HT_MAX_VIDEO_WIDTH && frame_.rows <= HT_MAX_VIDEO_HEIGHT && frame_.channels() <= HT_MAX_VIDEO_CHANNELS)
+            {
+                QMutexLocker l(&frame_mtx);
+
+                const int cols = frame_.cols;
+                const int rows = frame_.rows;
+                const int pitch = cols * 3;
+                for (int y = 0; y < rows; y++)
+                {
+                    for (int x = 0; x < cols; x++)
+                    {
+                        unsigned char* dest = &frame.frame[y * pitch + 3 * x];
+                        const cv::Vec3b& elt = frame_.at<cv::Vec3b>(y, x);
+                        const cv::Scalar elt2 = static_cast<cv::Scalar>(elt);
+                        dest[0] = elt2.val[0];
+                        dest[1] = elt2.val[1];
+                        dest[2] = elt2.val[2];
+                    }
+                }
+                frame.channels = frame_.channels();
+                frame.width = frame_.cols;
+                frame.height = frame_.rows;
+            }
+        }
+    }
 }
 
-void Tracker::data(double *data)
+void Tracker::data(double* data)
 {
-    lck_shm.lock();
-    shm->timer = 0;
-    if (shm->frame.width > 0)
     {
-        videoWidget->update_image(shm->frame.frame, shm->frame.width, shm->frame.height);
-        //memcpy(foo, shm->frame.frame, shm->frame.width * shm->frame.height * 3);
-        shm->frame.width = 0;
+        QMutexLocker l(&frame_mtx);
+
+        if (frame.width > 0)
+        {
+            videoWidget->update_image(frame.frame, frame.width, frame.height);
+            frame.width = 0;
+        }
     }
-    if (shm->result.filled) {
-        data[Yaw] = shm->result.rotx;
-        data[Pitch] = shm->result.roty;
-        data[Roll] = shm->result.rotz;
-        data[TX] = shm->result.tx;
-        data[TY] = shm->result.ty;
-        data[TZ] = shm->result.tz;
-    } else {
-        shm->pause = false;
+
+    {
+        QMutexLocker l(&ypr_mtx);
+
+        for (int i = 0; i < 6; i++)
+            data[i] = ypr[i];
     }
-    lck_shm.unlock();
 }
 
 extern "C" OPENTRACK_EXPORT Metadata* GetMetadata()
@@ -157,7 +197,7 @@ extern "C" OPENTRACK_EXPORT ITrackerDialog* GetDialog( )
     return new TrackerControls;
 }
 
-TrackerControls::TrackerControls()
+TrackerControls::TrackerControls() : tracker(nullptr)
 {
 	ui.setupUi(this);
     ui.cameraName->clear();
@@ -187,5 +227,11 @@ void TrackerControls::doCancel()
 
 void TrackerControls::camera_settings()
 {
-    open_camera_settings(nullptr, s.camera_name, nullptr);
+    if (tracker)
+    {
+        cv::VideoCapture* cap = ht_capture(tracker->ht);
+        open_camera_settings(cap, s.camera_name, &tracker->camera_mtx);
+    }
+    else
+        open_camera_settings(nullptr, s.camera_name, nullptr);
 }
diff --git a/ftnoir_tracker_ht/ftnoir_tracker_ht.h b/ftnoir_tracker_ht/ftnoir_tracker_ht.h
index 348fc246..b2fcb147 100644
--- a/ftnoir_tracker_ht/ftnoir_tracker_ht.h
+++ b/ftnoir_tracker_ht/ftnoir_tracker_ht.h
@@ -5,10 +5,8 @@
  * copyright notice and this permission notice appear in all copies.
  */
 
-#ifndef FTNOIR_TRACKER_HT_H
-#define FTNOIR_TRACKER_HT_H
+#pragma once
 
-#include "stdafx.h"
 #include "headtracker-ftnoir.h"
 #include "ui_ht-trackercontrols.h"
 #include "ht_video_widget.h"
@@ -18,6 +16,12 @@
 #include "opentrack/plugin-api.hpp"
 #include "opentrack/opencv-camera-dialog.hpp"
 
+#include <QThread>
+#include <QMutex>
+#include <QMutexLocker>
+#include <QHBoxLayout>
+#include <QString>
+
 using namespace options;
 
 struct settings : opts {
@@ -33,42 +37,47 @@ struct settings : opts {
     {}
 };
 
-class Tracker : public QObject, public ITracker
+class Tracker : public QThread, public ITracker
 {
     Q_OBJECT
 public:
     Tracker();
     ~Tracker() override;
+    void run() override;
     void start_tracker(QFrame* frame);
     void data(double *data);
     void load_settings(ht_config_t* config);
+    headtracker_t* ht;
+    QMutex camera_mtx;
 private:
+    double ypr[6];
     settings s;
-    PortableLockedShm lck_shm;
-    ht_shm_t* shm;
-    QProcess subprocess;
+    ht_config_t conf;
     HTVideoWidget* videoWidget;
     QHBoxLayout* layout;
+    QMutex ypr_mtx, frame_mtx;
+    ht_video_t frame;
+    volatile bool should_stop;
 };
 
-// Widget that has controls for FTNoIR protocol client-settings.
 class TrackerControls : public ITrackerDialog, protected camera_dialog<Tracker>
 {
     Q_OBJECT
 public:
-    explicit TrackerControls();
-    void register_tracker(ITracker *) {}
-    void unregister_tracker() {}
-
+    TrackerControls();
+    void register_tracker(ITracker * t)
+    {
+        tracker = static_cast<Tracker*>(t);
+    }
+    void unregister_tracker() {
+        tracker = nullptr;
+    }
 private:
     Ui::Form ui;
     settings s;
-
+    Tracker* tracker;
 private slots:
     void doOK();
     void doCancel();
     void camera_settings();
 };
-
-#endif
-
diff --git a/ftnoir_tracker_ht/ht-api.h b/ftnoir_tracker_ht/ht-api.h
index 4f88a6a3..4629a00b 100644
--- a/ftnoir_tracker_ht/ht-api.h
+++ b/ftnoir_tracker_ht/ht-api.h
@@ -9,7 +9,8 @@
 #if !defined(_WIN32) && !defined(_isnan)
 #  define _isnan isnan
 #endif
-//#include <opencv2/core.hpp>
+#include <opencv2/core.hpp>
+#include <opencv2/highgui.hpp>
 struct ht_context;
 typedef struct ht_context headtracker_t;
 
@@ -44,6 +45,7 @@ typedef struct {
 
 HT_API(headtracker_t*) ht_make_context(const ht_config_t* config, const char* filename);
 HT_API(void) ht_free_context(headtracker_t* ctx);
-//HT_API(const cv::Mat) ht_get_bgr_frame(headtracker_t* ctx);
+HT_API(const cv::Mat) ht_get_bgr_frame(headtracker_t* ctx);
 HT_API(bool) ht_cycle(headtracker_t* ctx, ht_result_t* euler);
 HT_API(void) ht_reset(headtracker_t* ctx);
+HT_API(cv::VideoCapture*) ht_capture(headtracker_t* ctx);
diff --git a/ftnoir_tracker_ht/stdafx.h b/ftnoir_tracker_ht/stdafx.h
index 6f1539b7..e69de29b 100644
--- a/ftnoir_tracker_ht/stdafx.h
+++ b/ftnoir_tracker_ht/stdafx.h
@@ -1,13 +0,0 @@
-#include <QWidget>
-#include <QMessageBox>
-#include <QProcess>
-#include <QImage>
-#include <QLabel>
-#include <QCoreApplication>
-#include <QIcon>
-#include <QHBoxLayout>
-#include <QTimer>
-#include <QPainter>
-#include <QPaintEvent>
-#include <QList>
-#include <QString>
-- 
cgit v1.2.3