summaryrefslogtreecommitdiffhomepage
path: root/FTNoIR_Tracker_HT/ftnoir_tracker_ht.cpp
diff options
context:
space:
mode:
Diffstat (limited to 'FTNoIR_Tracker_HT/ftnoir_tracker_ht.cpp')
-rw-r--r--FTNoIR_Tracker_HT/ftnoir_tracker_ht.cpp386
1 files changed, 386 insertions, 0 deletions
diff --git a/FTNoIR_Tracker_HT/ftnoir_tracker_ht.cpp b/FTNoIR_Tracker_HT/ftnoir_tracker_ht.cpp
new file mode 100644
index 00000000..0b9c923f
--- /dev/null
+++ b/FTNoIR_Tracker_HT/ftnoir_tracker_ht.cpp
@@ -0,0 +1,386 @@
+#include "stdafx.h"
+#include "..\ftnoir_tracker_base\ftnoir_tracker_base.h"
+#include "headtracker-ftnoir.h"
+#include "ftnoir_tracker_ht.h"
+#include "ftnoir_tracker_ht_dll.h"
+#include "UI_TRACKERCONTROLS.h"
+
+static TCHAR shmName[] = TEXT(HT_SHM_NAME);
+static TCHAR mutexName[] = TEXT(HT_MUTEX_NAME);
+
+#define WIDGET_WIDTH 250
+#define WIDGET_HEIGHT 170
+
+static void load_settings(ht_config_t* config, Tracker* tracker)
+{
+ QSettings settings("Abbequerque Inc.", "FaceTrackNoIR");
+ QString currentFile = settings.value( "SettingsFile", QCoreApplication::applicationDirPath() + "/Settings/default.ini" ).toString();
+ QSettings iniFile( currentFile, QSettings::IniFormat );
+
+ iniFile.beginGroup( "HT-Tracker" );
+ config->classification_delay = 1000;
+ config->field_of_view = iniFile.value("fov", 69).toFloat();
+ config->pyrlk_pyramids = 3;
+ config->pyrlk_win_size_w = config->pyrlk_win_size_h = 21;
+ config->max_keypoints = 250;
+ config->keypoint_quality = 31;
+ config->keypoint_distance = 3.9;
+ config->keypoint_3distance = 12;
+ config->force_width = 640;
+ config->force_height = 480;
+ config->force_fps = iniFile.value("fps", 0).toInt();
+ config->camera_index = iniFile.value("camera-index", -1).toInt();
+ config->ransac_num_iters = 100;
+ config->ransac_max_reprojection_error = 7;
+ config->ransac_max_inlier_error = 7;
+ config->ransac_max_mean_error = 5;
+ config->ransac_abs_max_mean_error = 7;
+ config->debug = 0;
+ config->ransac_min_features = 0.90;
+ if (tracker)
+ {
+ tracker->enableRX = iniFile.value("enable-rx", true).toBool();
+ tracker->enableRY = iniFile.value("enable-ry", true).toBool();
+ tracker->enableRZ = iniFile.value("enable-rz", true).toBool();
+ tracker->enableTX = iniFile.value("enable-tx", true).toBool();
+ tracker->enableTY = iniFile.value("enable-ty", true).toBool();
+ tracker->enableTZ = iniFile.value("enable-tz", true).toBool();
+ }
+ iniFile.endGroup();
+}
+
+Tracker::Tracker()
+{
+ videoWidget = NULL;
+ layout = NULL;
+ enableRX = enableRY = enableRZ = enableTX = enableTY = enableTZ = true;
+ hMutex = CreateMutex(NULL, false, mutexName);
+ hMapFile = CreateFileMapping(
+ INVALID_HANDLE_VALUE,
+ NULL,
+ PAGE_READWRITE,
+ 0,
+ sizeof(ht_shm_t),
+ shmName);
+ shm = (ht_shm_t*) MapViewOfFile(hMapFile,
+ FILE_MAP_READ | FILE_MAP_WRITE,
+ 0,
+ 0,
+ sizeof(ht_shm_t));
+ paused = false;
+ load_settings(&shm->config, this);
+}
+
+Tracker::~Tracker()
+{
+ if (layout)
+ delete layout;
+ if (videoWidget)
+ delete videoWidget;
+ UnmapViewOfFile(shm);
+ CloseHandle(hMapFile);
+ CloseHandle(hMutex);
+}
+
+void Tracker::Initialize(QFrame *videoframe)
+{
+ videoframe->setAttribute(Qt::WA_NativeWindow);
+ videoframe->show();
+ videoWidget = new VideoWidget(videoframe);
+ QHBoxLayout* layout = new QHBoxLayout();
+ layout->setContentsMargins(0, 0, 0, 0);
+ layout->addWidget(videoWidget);
+ if (videoframe->layout())
+ delete videoframe->layout();
+ videoframe->setLayout(layout);
+ videoWidget->resize(WIDGET_WIDTH, WIDGET_HEIGHT);
+ videoWidget->show();
+ this->layout = layout;
+}
+
+void Tracker::StartTracker(HWND parent)
+{
+ if (paused)
+ {
+ shm->pause = false;
+ }
+ else
+ {
+ load_settings(&shm->config, this);
+ shm->frame.channels = shm->frame.width = shm->frame.height = 0;
+ shm->pause = shm->terminate = shm->running = false;
+ shm->timer = 0;
+ switch (subprocess.state())
+ {
+ case QProcess::ProcessState::Running:
+ case QProcess::ProcessState::Starting:
+ subprocess.kill();
+ }
+ subprocess.setWorkingDirectory("tracker-ht");
+ subprocess.start("tracker-ht/headtracker-ftnoir.exe");
+ }
+}
+
+void Tracker::StopTracker(bool exit)
+{
+ if (exit)
+ {
+ shm->terminate = true;
+ subprocess.kill();
+ }
+ else
+ {
+ shm->pause = true;
+ }
+}
+
+bool Tracker::GiveHeadPoseData(THeadPoseData* data)
+{
+ bool ret = false;
+
+ if (WaitForSingleObject(hMutex, INFINITE) == WAIT_OBJECT_0)
+ {
+ shm->timer = 0;
+ if (WaitForSingleObject(videoWidget->hMutex, INFINITE) == WAIT_OBJECT_0)
+ {
+ memcpy(&videoWidget->videoFrame, &shm->frame, sizeof(ht_video_t));
+ ReleaseMutex(videoWidget->hMutex);
+ }
+ if (shm->result.filled) {
+ if (enableRX)
+ data->yaw = shm->result.rotx * 57.295781;
+ if (enableRY)
+ data->pitch = shm->result.roty * 57.295781;
+ if (enableRZ)
+ data->roll = shm->result.rotz * 57.295781;
+ if (enableTX)
+ data->x = shm->result.tx;
+ if (enableTY)
+ data->y = shm->result.ty;
+ if (enableTZ)
+ data->z = shm->result.tz;
+ ret = true;
+ }
+ ReleaseMutex(hMutex);
+ }
+
+ return ret;
+}
+
+VideoWidget::VideoWidget(QWidget* parent) : QWidget(parent)
+{
+ hMutex = CreateMutex(NULL, false, NULL);
+ videoFrame.channels = videoFrame.height = videoFrame.width = 0;
+ connect(&timer, SIGNAL(timeout()), this, SLOT(update()));
+ timer.start(35);
+}
+
+VideoWidget::~VideoWidget()
+{
+ CloseHandle(hMutex);
+}
+
+void VideoWidget::paintEvent(QPaintEvent *e)
+{
+ if (WaitForSingleObject(hMutex, INFINITE) == WAIT_OBJECT_0)
+ {
+ if (videoFrame.width > 0)
+ {
+ QImage image((uchar*) videoFrame.frame, videoFrame.width, videoFrame.height, QImage::Format_RGB888);
+ QPainter painter(this);
+ painter.drawPixmap(e->rect(), QPixmap::fromImage(image.rgbSwapped()).scaled(WIDGET_WIDTH, WIDGET_HEIGHT, Qt::AspectRatioMode::KeepAspectRatioByExpanding), e->rect());
+ }
+ ReleaseMutex(hMutex);
+ }
+}
+
+//-----------------------------------------------------------------------------
+void TrackerDll::getFullName(QString *strToBeFilled)
+{
+ *strToBeFilled = "HT 0.5";
+}
+
+void TrackerDll::getShortName(QString *strToBeFilled)
+{
+ *strToBeFilled = "HT";
+}
+
+void TrackerDll::getDescription(QString *strToBeFilled)
+{
+ *strToBeFilled = "";
+}
+
+void TrackerDll::getIcon(QIcon *icon)
+{
+ *icon = QIcon();
+}
+
+
+//-----------------------------------------------------------------------------
+#pragma comment(linker, "/export:GetTrackerDll=_GetTrackerDll@0")
+
+FTNOIR_TRACKER_BASE_EXPORT ITrackerDllPtr __stdcall GetTrackerDll()
+{
+ return new TrackerDll;
+}
+
+#pragma comment(linker, "/export:GetTracker=_GetTracker@0")
+
+FTNOIR_TRACKER_BASE_EXPORT ITrackerPtr __stdcall GetTracker()
+{
+ return new Tracker;
+}
+
+////////////////////////////////////////////////////////////////////////////////
+// Factory function that creates instances if the Tracker-settings dialog object.
+
+// Export both decorated and undecorated names.
+// GetTrackerDialog - Undecorated name, which can be easily used with GetProcAddress
+// Win32 API function.
+// _GetTrackerDialog@0 - Common name decoration for __stdcall functions in C language.
+#pragma comment(linker, "/export:GetTrackerDialog=_GetTrackerDialog@0")
+
+FTNOIR_TRACKER_BASE_EXPORT ITrackerDialogPtr __stdcall GetTrackerDialog( )
+{
+ return new TrackerControls;
+}
+
+TrackerControls::TrackerControls()
+{
+ ui.setupUi(this);
+ loadSettings();
+ connect(ui.cameraIndex, SIGNAL(valueChanged(int)), this, SLOT(settingChanged(int)));
+ connect(ui.cameraFPS, SIGNAL(currentIndexChanged(int)), this, SLOT(settingChanged(int)));
+ connect(ui.cameraFOV, SIGNAL(valueChanged(double)), this, SLOT(settingChanged(double)));
+ connect(ui.rx, SIGNAL(stateChanged(int)), this, SLOT(settingChanged(int)));
+ connect(ui.ry, SIGNAL(stateChanged(int)), this, SLOT(settingChanged(int)));
+ connect(ui.rz, SIGNAL(stateChanged(int)), this, SLOT(settingChanged(int)));
+ connect(ui.tx, SIGNAL(stateChanged(int)), this, SLOT(settingChanged(int)));
+ connect(ui.ty, SIGNAL(stateChanged(int)), this, SLOT(settingChanged(int)));
+ connect(ui.tz, SIGNAL(stateChanged(int)), this, SLOT(settingChanged(int)));
+ connect(ui.buttonCancel, SIGNAL(clicked()), this, SLOT(doCancel()));
+ connect(ui.buttonOK, SIGNAL(clicked()), this, SLOT(doOK()));
+ settingsDirty = false;
+}
+
+TrackerControls::~TrackerControls()
+{
+}
+
+void TrackerControls::showEvent(QShowEvent *event)
+{
+}
+
+void TrackerControls::Initialize(QWidget* parent)
+{
+ show();
+}
+
+void TrackerControls::loadSettings()
+{
+ QSettings settings("Abbequerque Inc.", "FaceTrackNoIR");
+ QString currentFile = settings.value( "SettingsFile", QCoreApplication::applicationDirPath() + "/Settings/default.ini" ).toString();
+ QSettings iniFile( currentFile, QSettings::IniFormat );
+ iniFile.beginGroup( "HT-Tracker" );
+ ui.cameraIndex->setValue(iniFile.value("camera-index", -1).toInt());
+ ui.cameraFOV->setValue(iniFile.value("fov", 69).toInt());
+ int fps;
+ switch (iniFile.value("fps", 0).toInt())
+ {
+ default:
+ case 0:
+ fps = 0;
+ break;
+ case 30:
+ fps = 1;
+ break;
+ case 60:
+ fps = 2;
+ break;
+ case 120:
+ fps = 3;
+ break;
+ }
+ ui.cameraFPS->setCurrentIndex(fps);
+ ui.rx->setCheckState(iniFile.value("enable-rx", true).toBool() ? Qt::CheckState::Checked : Qt::CheckState::Unchecked);
+ ui.ry->setCheckState(iniFile.value("enable-ry", true).toBool() ? Qt::CheckState::Checked : Qt::CheckState::Unchecked);
+ ui.rz->setCheckState(iniFile.value("enable-rz", true).toBool() ? Qt::CheckState::Checked : Qt::CheckState::Unchecked);
+ ui.tx->setCheckState(iniFile.value("enable-tx", true).toBool() ? Qt::CheckState::Checked : Qt::CheckState::Unchecked);
+ ui.ty->setCheckState(iniFile.value("enable-ty", true).toBool() ? Qt::CheckState::Checked : Qt::CheckState::Unchecked);
+ ui.tz->setCheckState(iniFile.value("enable-tz", true).toBool() ? Qt::CheckState::Checked : Qt::CheckState::Unchecked);
+ iniFile.endGroup();
+ settingsDirty = false;
+}
+
+void TrackerControls::save()
+{
+ QSettings settings("Abbequerque Inc.", "FaceTrackNoIR");
+ QString currentFile = settings.value( "SettingsFile", QCoreApplication::applicationDirPath() + "/Settings/default.ini" ).toString();
+ QSettings iniFile( currentFile, QSettings::IniFormat );
+
+ iniFile.beginGroup( "HT-Tracker" );
+ iniFile.setValue("fov", ui.cameraFOV->value());
+ int fps;
+ switch (ui.cameraFPS->currentIndex())
+ {
+ case 0:
+ default:
+ fps = 0;
+ break;
+ case 1:
+ fps = 30;
+ break;
+ case 2:
+ fps = 60;
+ break;
+ case 3:
+ fps = 120;
+ break;
+ }
+ iniFile.setValue("fps", fps);
+ iniFile.setValue("camera-index", ui.cameraIndex->value());
+ iniFile.setValue("enable-rx", ui.rx->checkState());
+ iniFile.setValue("enable-ry", ui.ry->checkState());
+ iniFile.setValue("enable-rz", ui.rz->checkState());
+ iniFile.setValue("enable-tx", ui.tx->checkState());
+ iniFile.setValue("enable-ty", ui.ty->checkState());
+ iniFile.setValue("enable-tz", ui.tz->checkState());
+ iniFile.endGroup();
+ settingsDirty = false;
+}
+
+void TrackerControls::doOK()
+{
+ save();
+ this->close();
+}
+
+void TrackerControls::doCancel()
+{
+ if (settingsDirty) {
+ int ret = QMessageBox::question ( this,
+ "Settings have changed",
+ "Do you want to save the settings?",
+ QMessageBox::Save | QMessageBox::Discard | QMessageBox::Cancel,
+ QMessageBox::Discard );
+
+ switch (ret) {
+ case QMessageBox::Save:
+ save();
+ this->close();
+ break;
+ case QMessageBox::Discard:
+ this->close();
+ break;
+ case QMessageBox::Cancel:
+ // Cancel was clicked
+ break;
+ default:
+ // should never be reached
+ break;
+ }
+ }
+ else {
+ this->close();
+ }
+} \ No newline at end of file