diff options
Diffstat (limited to 'ftnoir_tracker_ht')
-rw-r--r-- | ftnoir_tracker_ht/ftnoir_tracker_ht.cpp | 316 | ||||
-rw-r--r-- | ftnoir_tracker_ht/ftnoir_tracker_ht.h | 64 | ||||
-rw-r--r-- | ftnoir_tracker_ht/ftnoir_tracker_ht_dll.h | 3 | ||||
-rw-r--r-- | ftnoir_tracker_ht/ht-api.h | 68 | ||||
-rw-r--r-- | ftnoir_tracker_ht/ht-trackercontrols.ui | 596 | ||||
-rw-r--r-- | ftnoir_tracker_ht/ht_video_widget.cpp | 44 | ||||
-rw-r--r-- | ftnoir_tracker_ht/ht_video_widget.h (renamed from ftnoir_tracker_ht/video_widget.h) | 20 | ||||
-rw-r--r-- | ftnoir_tracker_ht/stdafx.h | 1 | ||||
-rw-r--r-- | ftnoir_tracker_ht/video_widget.cpp | 30 |
9 files changed, 377 insertions, 765 deletions
diff --git a/ftnoir_tracker_ht/ftnoir_tracker_ht.cpp b/ftnoir_tracker_ht/ftnoir_tracker_ht.cpp index b755010c..76a6ba71 100644 --- a/ftnoir_tracker_ht/ftnoir_tracker_ht.cpp +++ b/ftnoir_tracker_ht/ftnoir_tracker_ht.cpp @@ -7,7 +7,7 @@ #include "facetracknoir/global-settings.h" #include <cmath> -#if defined(_WIN32) || defined(__WIN32) +#if defined(_WIN32) #include <dshow.h> #else #include <unistd.h> @@ -16,7 +16,7 @@ // delicious copypasta static QList<QString> get_camera_names(void) { QList<QString> ret; -#if defined(_WIN32) || defined(__WIN32) +#if defined(_WIN32) // Create the System Device Enumerator. HRESULT hr; ICreateDevEnum *pSysDevEnum = NULL; @@ -62,14 +62,14 @@ static QList<QString> get_camera_names(void) { pEnumCat->Release(); } pSysDevEnum->Release(); -#else +#elif !defined(__APPLE__) for (int i = 0; i < 16; i++) { char buf[128]; sprintf(buf, "/dev/video%d", i); if (access(buf, R_OK | W_OK) == 0) { ret.append(buf); } else { - break; + continue; } } #endif @@ -88,67 +88,71 @@ static resolution_tuple resolution_choices[] = { { 0, 0 } }; -static void load_settings(ht_config_t* config, Tracker* tracker) +void Tracker::load_settings(ht_config_t* config) { - QSettings settings("opentrack"); - QString currentFile = settings.value( "SettingsFile", QCoreApplication::applicationDirPath() + "/Settings/default.ini" ).toString(); - QSettings iniFile( currentFile, QSettings::IniFormat ); + int nframes = 0; + switch (static_cast<int>(s.fps)) + { + default: + case 0: + nframes = 0; + break; + case 1: + nframes = 30; + break; + case 2: + nframes = 60; + break; + case 3: + nframes = 120; + break; + case 4: + nframes = 180; + break; + } - iniFile.beginGroup( "HT-Tracker" ); config->classification_delay = 500; - config->field_of_view = iniFile.value("fov", 52).toFloat(); - config->pyrlk_pyramids = 3; + config->field_of_view = s.fov; + config->pyrlk_pyramids = 0; config->pyrlk_win_size_w = config->pyrlk_win_size_h = 21; - config->max_keypoints = 200; - config->keypoint_distance = 4.5; - //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->max_keypoints = 150; + config->keypoint_distance = 6; + config->force_fps = nframes; + config->camera_index = s.camera_idx - 1; config->ransac_num_iters = 100; - config->ransac_max_reprojection_error = 6.5; - config->ransac_max_inlier_error = 6.5; - config->ransac_abs_max_mean_error = 15; - config->ransac_max_mean_error = 4.5; + 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->debug = 0; - config->ransac_min_features = 0.8; - int res = iniFile.value("resolution", 0).toInt(); + config->ransac_min_features = 0.86; + 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 = 200; - qDebug() << "width" << r.width << "height" << r.height; - 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(); - } - + config->flandmark_delay = 500; for (int i = 0; i < 5; i++) - config->dist_coeffs[i] = iniFile.value(QString("dc%1").arg(i), 0).toDouble(); - - iniFile.endGroup(); + config->dist_coeffs[i] = 0; } -Tracker::Tracker() : lck_shm(HT_SHM_NAME, HT_MUTEX_NAME, sizeof(ht_shm_t)), fresh(false) +Tracker::Tracker() : + lck_shm(HT_SHM_NAME, HT_MUTEX_NAME, sizeof(ht_shm_t)), + shm(reinterpret_cast<ht_shm_t*>(lck_shm.mem)), + videoWidget(nullptr), + layout(nullptr) { - videoWidget = NULL; - layout = NULL; - enableRX = enableRY = enableRZ = enableTX = enableTY = enableTZ = true; - shm = (ht_shm_t*) lck_shm.mem; shm->terminate = 0; - load_settings(&shm->config, this); shm->result.filled = false; } Tracker::~Tracker() { + if (shm) { + shm->terminate = true; + subprocess.waitForFinished(5000); + } subprocess.kill(); if (shm) shm->terminate = true; @@ -161,7 +165,7 @@ Tracker::~Tracker() void Tracker::StartTracker(QFrame* videoframe) { videoframe->show(); - videoWidget = new VideoWidget(videoframe); + videoWidget = new HTVideoWidget(videoframe); QHBoxLayout* layout = new QHBoxLayout(); layout->setContentsMargins(0, 0, 0, 0); layout->addWidget(videoWidget); @@ -170,60 +174,51 @@ void Tracker::StartTracker(QFrame* videoframe) videoframe->setLayout(layout); videoWidget->show(); this->layout = layout; - load_settings(&shm->config, this); + load_settings(&shm->config); shm->frame.channels = shm->frame.width = shm->frame.height = 0; shm->pause = shm->terminate = shm->running = false; shm->timer = 0; subprocess.setWorkingDirectory(QCoreApplication::applicationDirPath() + "/tracker-ht"); -#if defined(_WIN32) || defined(__WIN32) +#if defined(_WIN32) subprocess.start("\"" + QCoreApplication::applicationDirPath() + "/tracker-ht/headtracker-ftnoir" + "\""); #else subprocess.start(QCoreApplication::applicationDirPath() + "/tracker-ht/headtracker-ftnoir"); #endif - connect(&timer, SIGNAL(timeout()), this, SLOT(paint_widget())); - timer.start(40); } -void Tracker::paint_widget() { - if (fresh) { - fresh = false; - videoWidget->update(); - } -} - -bool Tracker::GiveHeadPoseData(double *data) +void Tracker::GetHeadPoseData(double *data) { - bool ret = false; - 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); - fresh = true; shm->frame.width = 0; } if (shm->result.filled) { - if (enableRX) + if (s.enableRX) data[Yaw] = shm->result.rotx; - if (enableRY) { + if (s.enableRY) { data[Pitch] = shm->result.roty; } - if (enableRZ) { + if (s.enableRZ) { data[Roll] = shm->result.rotz; } - if (enableTX) + if (s.enableTX) data[TX] = shm->result.tx; - if (enableTY) + if (s.enableTY) data[TY] = shm->result.ty; - if (enableTZ) + if (s.enableTZ) data[TZ] = shm->result.tz; - ret = true; + if (fabs(data[Yaw]) > 60 || fabs(data[Pitch]) > 50 || fabs(data[Roll]) > 40) + { + shm->pause = true; + } + } else { + shm->pause = false; } lck_shm.unlock(); - - return ret; } //----------------------------------------------------------------------------- @@ -247,31 +242,16 @@ void TrackerDll::getIcon(QIcon *icon) *icon = QIcon(":/images/ht.png"); } - -//----------------------------------------------------------------------------- -//#pragma comment(linker, "/export:GetTrackerDll=_GetTrackerDll@0") - extern "C" FTNOIR_TRACKER_BASE_EXPORT Metadata* CALLING_CONVENTION GetMetadata() { return new TrackerDll; } -//#pragma comment(linker, "/export:GetTracker=_GetTracker@0") - extern "C" FTNOIR_TRACKER_BASE_EXPORT ITracker* CALLING_CONVENTION GetConstructor() { 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") - extern "C" FTNOIR_TRACKER_BASE_EXPORT ITrackerDialog* CALLING_CONVENTION GetDialog( ) { return new TrackerControls; @@ -280,162 +260,32 @@ extern "C" FTNOIR_TRACKER_BASE_EXPORT ITrackerDialog* CALLING_CONVENTION GetDial TrackerControls::TrackerControls() { ui.setupUi(this); - setAttribute(Qt::WA_NativeWindow, true); - connect(ui.cameraName, SIGNAL(currentIndexChanged(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())); - //connect(ui.buttonSettings, SIGNAL(clicked()), this, SLOT(cameraSettings())); - loadSettings(); - settingsDirty = false; -} - -TrackerControls::~TrackerControls() -{ -} - -void TrackerControls::showEvent(QShowEvent *event) -{ -} - -void TrackerControls::Initialize(QWidget* parent) -{ - loadSettings(); - show(); -} - -void TrackerControls::loadSettings() -{ - ui.cameraName->clear(); - QList<QString> names = get_camera_names(); - names.prepend("Any available"); - ui.cameraName->addItems(names); - QSettings settings("opentrack"); - QString currentFile = settings.value( "SettingsFile", QCoreApplication::applicationDirPath() + "/Settings/default.ini" ).toString(); - QSettings iniFile( currentFile, QSettings::IniFormat ); - iniFile.beginGroup( "HT-Tracker" ); - ui.cameraName->setCurrentIndex(iniFile.value("camera-index", -1).toInt() + 1); - ui.cameraFOV->setValue(iniFile.value("fov", 52).toFloat()); - 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::Checked : Qt::Unchecked); - ui.ry->setCheckState(iniFile.value("enable-ry", true).toBool() ? Qt::Checked : Qt::Unchecked); - ui.rz->setCheckState(iniFile.value("enable-rz", true).toBool() ? Qt::Checked : Qt::Unchecked); - ui.tx->setCheckState(iniFile.value("enable-tx", true).toBool() ? Qt::Checked : Qt::Unchecked); - ui.ty->setCheckState(iniFile.value("enable-ty", true).toBool() ? Qt::Checked : Qt::Unchecked); - ui.tz->setCheckState(iniFile.value("enable-tz", true).toBool() ? Qt::Checked : Qt::Unchecked); - ui.resolution->setCurrentIndex(iniFile.value("resolution", 0).toInt()); - - ui.doubleSpinBox->setValue(iniFile.value("dc0").toDouble()); - ui.doubleSpinBox_2->setValue(iniFile.value("dc1").toDouble()); - ui.doubleSpinBox_3->setValue(iniFile.value("dc2").toDouble()); - ui.doubleSpinBox_4->setValue(iniFile.value("dc3").toDouble()); - ui.doubleSpinBox_5->setValue(iniFile.value("dc4").toDouble()); - - iniFile.endGroup(); - settingsDirty = false; -} - -void TrackerControls::save() -{ - QSettings settings("opentrack"); - 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.cameraName->currentIndex() - 1); - iniFile.setValue("enable-rx", ui.rx->checkState() != Qt::Unchecked ? true : false); - iniFile.setValue("enable-ry", ui.ry->checkState() != Qt::Unchecked ? true : false); - iniFile.setValue("enable-rz", ui.rz->checkState() != Qt::Unchecked ? true : false); - iniFile.setValue("enable-tx", ui.tx->checkState() != Qt::Unchecked ? true : false); - iniFile.setValue("enable-ty", ui.ty->checkState() != Qt::Unchecked ? true : false); - iniFile.setValue("enable-tz", ui.tz->checkState() != Qt::Unchecked ? true : false); - iniFile.setValue("resolution", ui.resolution->currentIndex()); - - iniFile.setValue("dc0", ui.doubleSpinBox->value()); - iniFile.setValue("dc1", ui.doubleSpinBox_2->value()); - iniFile.setValue("dc2", ui.doubleSpinBox_3->value()); - iniFile.setValue("dc3", ui.doubleSpinBox_4->value()); - iniFile.setValue("dc4", ui.doubleSpinBox_5->value()); - - iniFile.endGroup(); - settingsDirty = false; + ui.cameraName->clear(); + QList<QString> names = get_camera_names(); + names.prepend("Any available"); + ui.cameraName->addItems(names); + tie_setting(s.camera_idx, ui.cameraName); + tie_setting(s.fps, ui.cameraFPS); + tie_setting(s.fov, ui.cameraFOV); + tie_setting(s.enableTX, ui.tx); + tie_setting(s.enableTY, ui.ty); + tie_setting(s.enableTZ, ui.tz); + tie_setting(s.enableRX, ui.rx); + tie_setting(s.enableRY, ui.ry); + tie_setting(s.enableRZ, ui.rz); + tie_setting(s.resolution, ui.resolution); + connect(ui.buttonBox, SIGNAL(rejected()), this, SLOT(doCancel())); + connect(ui.buttonBox, SIGNAL(accepted()), this, SLOT(doOK())); } void TrackerControls::doOK() { - save(); + s.b->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(); - } + s.b->revert(); + this->close(); } diff --git a/ftnoir_tracker_ht/ftnoir_tracker_ht.h b/ftnoir_tracker_ht/ftnoir_tracker_ht.h index fcdea140..583249dc 100644 --- a/ftnoir_tracker_ht/ftnoir_tracker_ht.h +++ b/ftnoir_tracker_ht/ftnoir_tracker_ht.h @@ -12,40 +12,48 @@ #include "ftnoir_tracker_base/ftnoir_tracker_base.h" #include "headtracker-ftnoir.h" #include "ui_ht-trackercontrols.h" -#include "video_widget.h" +#include "ht_video_widget.h" #include "compat/compat.h" #include <QObject> -#include <QTimer> +#include "facetracknoir/options.h" +using namespace options; + +struct settings { + pbundle b; + value<bool> enableTX, enableTY, enableTZ, enableRX, enableRY, enableRZ; + value<double> fov; + value<int> fps, camera_idx, resolution; + settings() : + b(bundle("HT-Tracker")), + enableTX(b, "enable-tx", true), + enableTY(b, "enable-ty", true), + enableTZ(b, "enable-tz", true), + enableRX(b, "enable-rx", true), + enableRY(b, "enable-ry", true), + enableRZ(b, "enable-rz", true), + fov(b, "fov", 56), + fps(b, "fps", 0), + camera_idx(b, "camera-index", 0), + resolution(b, "resolution", 0) + {} +}; class Tracker : public QObject, public ITracker { Q_OBJECT public: Tracker(); - ~Tracker(); + virtual ~Tracker(); void StartTracker(QFrame* frame); - bool GiveHeadPoseData(double *data); - bool enableTX, enableTY, enableTZ, enableRX, enableRY, enableRZ; - ht_shm_t* shm; - bool NeedsTimeToFinish() { - return true; - } - void WaitForExit() { - if (shm) { - shm->terminate = true; - subprocess.waitForFinished(5000); - } - subprocess.kill(); - } + void GetHeadPoseData(double *data); + void load_settings(ht_config_t* config); private: - QTimer timer; + settings s; PortableLockedShm lck_shm; + ht_shm_t* shm; QProcess subprocess; - VideoWidget* videoWidget; + HTVideoWidget* videoWidget; QHBoxLayout* layout; - volatile bool fresh; -private slots: - void paint_widget(); }; // Widget that has controls for FTNoIR protocol client-settings. @@ -53,27 +61,17 @@ class TrackerControls : public QWidget, public ITrackerDialog { Q_OBJECT public: - explicit TrackerControls(); - virtual ~TrackerControls(); - void showEvent ( QShowEvent * event ); - - void Initialize(QWidget *parent); - void registerTracker(ITracker *tracker) {} + void registerTracker(ITracker *) {} void unRegisterTracker() {} private: Ui::Form ui; - void loadSettings(); - void save(); - bool settingsDirty; + settings s; private slots: void doOK(); void doCancel(); - void settingChanged() { settingsDirty = true; } - void settingChanged(int) { settingsDirty = true; } - void settingChanged(double) { settingsDirty = true; } }; #endif diff --git a/ftnoir_tracker_ht/ftnoir_tracker_ht_dll.h b/ftnoir_tracker_ht/ftnoir_tracker_ht_dll.h index 1e53f802..ffdc5262 100644 --- a/ftnoir_tracker_ht/ftnoir_tracker_ht_dll.h +++ b/ftnoir_tracker_ht/ftnoir_tracker_ht_dll.h @@ -1,4 +1,4 @@ -/* Copyright (c) 2013 Stanis³aw Halik <sthalik@misaki.pl> +/* Copyright (c) 2013 StanisÅ‚aw 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 @@ -12,7 +12,6 @@ class TrackerDll : public Metadata { // ITrackerDll interface - void Initialize() {} void getFullName(QString *strToBeFilled); void getShortName(QString *strToBeFilled); void getDescription(QString *strToBeFilled); diff --git a/ftnoir_tracker_ht/ht-api.h b/ftnoir_tracker_ht/ht-api.h index e6960206..2ab2e840 100644 --- a/ftnoir_tracker_ht/ht-api.h +++ b/ftnoir_tracker_ht/ht-api.h @@ -1,38 +1,33 @@ #pragma once #ifndef HT_API -#ifndef __cplusplus -# define HT_EXTERN -#else -# define HT_EXTERN extern "C" -#endif # if defined(_WIN32) && !defined(MINGW) -# define HT_API(t) HT_EXTERN __declspec(dllexport) t __stdcall +# define HT_API(t) __declspec(dllexport) t __stdcall # else -# define HT_API(t) HT_EXTERN t +# define HT_API(t) t # endif #endif #if !defined(_WIN32) && !defined(_isnan) # define _isnan isnan #endif -#include <stdio.h> +#include <opencv2/core/core.hpp> struct ht_context; typedef struct ht_context headtracker_t; typedef struct ht_config { - float field_of_view; - float classification_delay; - int pyrlk_pyramids; - int pyrlk_win_size_w; - int pyrlk_win_size_h; + float field_of_view; + float classification_delay; + int pyrlk_pyramids; + int pyrlk_win_size_w; + int pyrlk_win_size_h; float ransac_max_inlier_error; float ransac_max_reprojection_error; - int max_keypoints; - float keypoint_distance; + int max_keypoints; + float keypoint_distance; int force_width; - int force_height; - int force_fps; - int camera_index; - bool debug; + int force_height; + int force_fps; + int camera_index; + bool debug; int ransac_num_iters; float ransac_min_features; float ransac_max_mean_error; @@ -44,42 +39,11 @@ typedef struct ht_config { typedef struct { double rotx, roty, rotz; double tx, ty, tz; - bool filled; + bool filled; } ht_result_t; -typedef enum { - cfg_type_float = 0, - cfg_type_int = 1, - cfg_type_bool = 2, - cfg_type_double = 3 -} ht_cfg_type_t; - -typedef union -{ - double d; - float f; - int i; -} ht_cfg_value_t; - -typedef struct { - const char* name; - int offset; - ht_cfg_type_t type; - ht_cfg_value_t default_value; - ht_cfg_value_t min; - ht_cfg_value_t max; - const char* docstring; -} ht_reflection_t; - -typedef struct { - int rows, cols, channels; - unsigned char* data; -} ht_frame_t; - HT_API(headtracker_t*) ht_make_context(const ht_config_t* config, const char* filename); -HT_API(void) ht_load_config(FILE* stream, ht_config_t* cfg); HT_API(void) ht_free_context(headtracker_t* ctx); -HT_API(void) ht_get_bgr_frame(headtracker_t* ctx, ht_frame_t* ret); -HT_API(void) ht_make_config(ht_config_t* cfg); +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); diff --git a/ftnoir_tracker_ht/ht-trackercontrols.ui b/ftnoir_tracker_ht/ht-trackercontrols.ui index fbe7a41a..f57022c8 100644 --- a/ftnoir_tracker_ht/ht-trackercontrols.ui +++ b/ftnoir_tracker_ht/ht-trackercontrols.ui @@ -9,8 +9,8 @@ <rect> <x>0</x> <y>0</y> - <width>593</width> - <height>280</height> + <width>531</width> + <height>166</height> </rect> </property> <property name="sizePolicy"> @@ -28,420 +28,200 @@ <property name="windowTitle"> <string>HT tracker settings</string> </property> - <widget class="QLabel" name="label"> - <property name="geometry"> - <rect> - <x>10</x> - <y>10</y> - <width>141</width> - <height>16</height> - </rect> - </property> - <property name="text"> - <string>Horizontal FOV</string> - </property> - </widget> - <widget class="QDoubleSpinBox" name="cameraFOV"> - <property name="geometry"> - <rect> - <x>130</x> - <y>10</y> - <width>251</width> - <height>22</height> - </rect> - </property> - <property name="locale"> - <locale language="English" country="UnitedStates"/> - </property> - <property name="minimum"> - <double>35.000000000000000</double> - </property> - <property name="maximum"> - <double>180.000000000000000</double> - </property> - <property name="value"> - <double>52.000000000000000</double> - </property> - </widget> - <widget class="QLabel" name="label_2"> - <property name="geometry"> - <rect> - <x>10</x> - <y>40</y> - <width>137</width> - <height>16</height> - </rect> - </property> - <property name="text"> - <string>Frames per second</string> - </property> - </widget> - <widget class="QComboBox" name="cameraFPS"> - <property name="geometry"> - <rect> - <x>130</x> - <y>40</y> - <width>251</width> - <height>22</height> - </rect> - </property> - <item> - <property name="text"> - <string notr="true">Default</string> - </property> + <layout class="QGridLayout" name="gridLayout"> + <item row="0" column="1"> + <widget class="QDoubleSpinBox" name="cameraFOV"> + <property name="locale"> + <locale language="English" country="UnitedStates"/> + </property> + <property name="minimum"> + <double>35.000000000000000</double> + </property> + <property name="maximum"> + <double>180.000000000000000</double> + </property> + <property name="value"> + <double>52.000000000000000</double> + </property> + </widget> + </item> + <item row="0" column="0"> + <widget class="QLabel" name="label"> + <property name="text"> + <string>Horizontal FOV</string> + </property> + </widget> + </item> + <item row="0" column="2" rowspan="3"> + <widget class="QGroupBox" name="groupBox"> + <property name="title"> + <string>Enable axes</string> + </property> + <widget class="QCheckBox" name="rx"> + <property name="geometry"> + <rect> + <x>10</x> + <y>20</y> + <width>70</width> + <height>17</height> + </rect> + </property> + <property name="text"> + <string>RX</string> + </property> + </widget> + <widget class="QCheckBox" name="ry"> + <property name="geometry"> + <rect> + <x>10</x> + <y>40</y> + <width>70</width> + <height>17</height> + </rect> + </property> + <property name="text"> + <string>RY</string> + </property> + </widget> + <widget class="QCheckBox" name="rz"> + <property name="geometry"> + <rect> + <x>10</x> + <y>60</y> + <width>70</width> + <height>17</height> + </rect> + </property> + <property name="text"> + <string>RZ</string> + </property> + </widget> + <widget class="QCheckBox" name="tx"> + <property name="geometry"> + <rect> + <x>60</x> + <y>20</y> + <width>70</width> + <height>17</height> + </rect> + </property> + <property name="text"> + <string>TX</string> + </property> + </widget> + <widget class="QCheckBox" name="ty"> + <property name="geometry"> + <rect> + <x>60</x> + <y>40</y> + <width>70</width> + <height>17</height> + </rect> + </property> + <property name="text"> + <string>TY</string> + </property> + </widget> + <widget class="QCheckBox" name="tz"> + <property name="geometry"> + <rect> + <x>60</x> + <y>60</y> + <width>70</width> + <height>17</height> + </rect> + </property> + <property name="text"> + <string>TZ</string> + </property> + </widget> + </widget> </item> - <item> - <property name="text"> - <string>30</string> - </property> + <item row="1" column="0"> + <widget class="QLabel" name="label_2"> + <property name="text"> + <string>Frames per second</string> + </property> + </widget> </item> - <item> - <property name="text"> - <string>60</string> - </property> + <item row="1" column="1"> + <widget class="QComboBox" name="cameraFPS"> + <item> + <property name="text"> + <string notr="true">Default</string> + </property> + </item> + <item> + <property name="text"> + <string>30</string> + </property> + </item> + <item> + <property name="text"> + <string>60</string> + </property> + </item> + <item> + <property name="text"> + <string>120</string> + </property> + </item> + <item> + <property name="text"> + <string>180</string> + </property> + </item> + </widget> </item> - <item> - <property name="text"> - <string>120</string> - </property> + <item row="2" column="0"> + <widget class="QLabel" name="label_3"> + <property name="text"> + <string>Camera name</string> + </property> + </widget> </item> - </widget> - <widget class="QLabel" name="label_3"> - <property name="geometry"> - <rect> - <x>10</x> - <y>70</y> - <width>133</width> - <height>16</height> - </rect> - </property> - <property name="text"> - <string>Camera name</string> - </property> - </widget> - <widget class="QPushButton" name="buttonOK"> - <property name="geometry"> - <rect> - <x>430</x> - <y>250</y> - <width>75</width> - <height>23</height> - </rect> - </property> - <property name="text"> - <string>OK</string> - </property> - </widget> - <widget class="QPushButton" name="buttonCancel"> - <property name="geometry"> - <rect> - <x>510</x> - <y>250</y> - <width>75</width> - <height>23</height> - </rect> - </property> - <property name="text"> - <string>Cancel</string> - </property> - </widget> - <widget class="QGroupBox" name="groupBox"> - <property name="geometry"> - <rect> - <x>390</x> - <y>10</y> - <width>101</width> - <height>81</height> - </rect> - </property> - <property name="title"> - <string>Enable axes</string> - </property> - <widget class="QCheckBox" name="rx"> - <property name="geometry"> - <rect> - <x>10</x> - <y>20</y> - <width>70</width> - <height>17</height> - </rect> - </property> - <property name="text"> - <string>RX</string> - </property> - </widget> - <widget class="QCheckBox" name="ry"> - <property name="geometry"> - <rect> - <x>10</x> - <y>40</y> - <width>70</width> - <height>17</height> - </rect> - </property> - <property name="text"> - <string>RY</string> - </property> - </widget> - <widget class="QCheckBox" name="rz"> - <property name="geometry"> - <rect> - <x>10</x> - <y>60</y> - <width>70</width> - <height>17</height> - </rect> - </property> - <property name="text"> - <string>RZ</string> - </property> - </widget> - <widget class="QCheckBox" name="tx"> - <property name="geometry"> - <rect> - <x>60</x> - <y>20</y> - <width>70</width> - <height>17</height> - </rect> - </property> - <property name="text"> - <string>TX</string> - </property> - </widget> - <widget class="QCheckBox" name="ty"> - <property name="geometry"> - <rect> - <x>60</x> - <y>40</y> - <width>70</width> - <height>17</height> - </rect> - </property> - <property name="text"> - <string>TY</string> - </property> - </widget> - <widget class="QCheckBox" name="tz"> - <property name="geometry"> - <rect> - <x>60</x> - <y>60</y> - <width>70</width> - <height>17</height> - </rect> - </property> - <property name="text"> - <string>TZ</string> - </property> - </widget> - </widget> - <widget class="QComboBox" name="cameraName"> - <property name="geometry"> - <rect> - <x>130</x> - <y>70</y> - <width>251</width> - <height>22</height> - </rect> - </property> - </widget> - <widget class="QLabel" name="label_4"> - <property name="geometry"> - <rect> - <x>10</x> - <y>100</y> - <width>128</width> - <height>16</height> - </rect> - </property> - <property name="text"> - <string>Resolution</string> - </property> - </widget> - <widget class="QComboBox" name="resolution"> - <property name="geometry"> - <rect> - <x>130</x> - <y>100</y> - <width>251</width> - <height>22</height> - </rect> - </property> - <item> - <property name="text"> - <string>640x480</string> - </property> + <item row="2" column="1"> + <widget class="QComboBox" name="cameraName"/> </item> - <item> - <property name="text"> - <string>320x240</string> - </property> + <item row="3" column="0"> + <widget class="QLabel" name="label_4"> + <property name="text"> + <string>Resolution</string> + </property> + </widget> </item> - <item> - <property name="text"> - <string>320x200</string> - </property> + <item row="3" column="1"> + <widget class="QComboBox" name="resolution"> + <item> + <property name="text"> + <string>640x480</string> + </property> + </item> + <item> + <property name="text"> + <string>320x240</string> + </property> + </item> + <item> + <property name="text"> + <string>320x200</string> + </property> + </item> + <item> + <property name="text"> + <string>Default (not recommended!)</string> + </property> + </item> + </widget> </item> - <item> - <property name="text"> - <string>Default (not recommended!)</string> - </property> + <item row="4" column="2"> + <widget class="QDialogButtonBox" name="buttonBox"> + <property name="standardButtons"> + <set>QDialogButtonBox::Cancel|QDialogButtonBox::Ok</set> + </property> + </widget> </item> - </widget> - <widget class="QDoubleSpinBox" name="doubleSpinBox"> - <property name="geometry"> - <rect> - <x>130</x> - <y>130</y> - <width>171</width> - <height>22</height> - </rect> - </property> - <property name="frame"> - <bool>true</bool> - </property> - <property name="buttonSymbols"> - <enum>QAbstractSpinBox::NoButtons</enum> - </property> - <property name="decimals"> - <number>24</number> - </property> - <property name="minimum"> - <double>-1000.000000000000000</double> - </property> - <property name="maximum"> - <double>1000.000000000000000</double> - </property> - <property name="singleStep"> - <double>0.000000000000000</double> - </property> - </widget> - <widget class="QLabel" name="label_5"> - <property name="geometry"> - <rect> - <x>10</x> - <y>130</y> - <width>111</width> - <height>16</height> - </rect> - </property> - <property name="text"> - <string>Distortion coefficients</string> - </property> - </widget> - <widget class="QDoubleSpinBox" name="doubleSpinBox_2"> - <property name="geometry"> - <rect> - <x>130</x> - <y>160</y> - <width>171</width> - <height>22</height> - </rect> - </property> - <property name="frame"> - <bool>true</bool> - </property> - <property name="buttonSymbols"> - <enum>QAbstractSpinBox::NoButtons</enum> - </property> - <property name="decimals"> - <number>24</number> - </property> - <property name="minimum"> - <double>-1000.000000000000000</double> - </property> - <property name="maximum"> - <double>1000.000000000000000</double> - </property> - <property name="singleStep"> - <double>0.000000000000000</double> - </property> - </widget> - <widget class="QDoubleSpinBox" name="doubleSpinBox_3"> - <property name="geometry"> - <rect> - <x>130</x> - <y>190</y> - <width>171</width> - <height>22</height> - </rect> - </property> - <property name="frame"> - <bool>true</bool> - </property> - <property name="buttonSymbols"> - <enum>QAbstractSpinBox::NoButtons</enum> - </property> - <property name="decimals"> - <number>24</number> - </property> - <property name="minimum"> - <double>-1000.000000000000000</double> - </property> - <property name="maximum"> - <double>1000.000000000000000</double> - </property> - <property name="singleStep"> - <double>0.000000000000000</double> - </property> - </widget> - <widget class="QDoubleSpinBox" name="doubleSpinBox_4"> - <property name="geometry"> - <rect> - <x>130</x> - <y>220</y> - <width>171</width> - <height>22</height> - </rect> - </property> - <property name="frame"> - <bool>true</bool> - </property> - <property name="buttonSymbols"> - <enum>QAbstractSpinBox::NoButtons</enum> - </property> - <property name="decimals"> - <number>24</number> - </property> - <property name="minimum"> - <double>-1000.000000000000000</double> - </property> - <property name="maximum"> - <double>1000.000000000000000</double> - </property> - <property name="singleStep"> - <double>0.000000000000000</double> - </property> - </widget> - <widget class="QDoubleSpinBox" name="doubleSpinBox_5"> - <property name="geometry"> - <rect> - <x>130</x> - <y>250</y> - <width>171</width> - <height>22</height> - </rect> - </property> - <property name="frame"> - <bool>true</bool> - </property> - <property name="buttonSymbols"> - <enum>QAbstractSpinBox::NoButtons</enum> - </property> - <property name="decimals"> - <number>24</number> - </property> - <property name="minimum"> - <double>-1000.000000000000000</double> - </property> - <property name="maximum"> - <double>1000.000000000000000</double> - </property> - <property name="singleStep"> - <double>0.000000000000000</double> - </property> - </widget> + </layout> </widget> <resources/> <connections/> diff --git a/ftnoir_tracker_ht/ht_video_widget.cpp b/ftnoir_tracker_ht/ht_video_widget.cpp new file mode 100644 index 00000000..c6d59b34 --- /dev/null +++ b/ftnoir_tracker_ht/ht_video_widget.cpp @@ -0,0 +1,44 @@ +/* Copyright (c) 2012 Patrick Ruoff + * + * 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. + */ + +#include "ht_video_widget.h" + +#include <QDebug> + +using namespace std; + +void HTVideoWidget::update_image(unsigned char *frame, int width, int height) +{ + QMutexLocker foo(&mtx); + memcpy(fb, frame, width * height * 3); + this->width = width; + this->height = height; +} + +void HTVideoWidget::update_and_repaint() +{ + QMutexLocker foo(&mtx); + if (width*height <= 0) + return; + QImage qframe = QImage(width, height, QImage::Format_RGB888); + uchar* data = qframe.bits(); + const int pitch = qframe.bytesPerLine(); + for (int y = 0; y < height; y++) + { + const int part = y*width; + for (int x = 0; x < width; x++) + { + const int pos = 3 * (part + x); + data[y * pitch + x * 3 + 0] = fb[pos + 2]; + data[y * pitch + x * 3 + 1] = fb[pos + 1]; + data[y * pitch + x * 3 + 2] = fb[pos + 0]; + } + } + auto qframe2 = qframe.scaled(size(), Qt::IgnoreAspectRatio, Qt::FastTransformation); + texture = qframe2; + update(); +} diff --git a/ftnoir_tracker_ht/video_widget.h b/ftnoir_tracker_ht/ht_video_widget.h index 87b6278a..cbfe6ddc 100644 --- a/ftnoir_tracker_ht/video_widget.h +++ b/ftnoir_tracker_ht/ht_video_widget.h @@ -15,25 +15,33 @@ #include <QLabel> #include <QPainter> #include <QPaintEvent> +#include <QTimer> // ---------------------------------------------------------------------------- -class VideoWidget : public QWidget +class HTVideoWidget : public QWidget { - Q_OBJECT + Q_OBJECT public: - VideoWidget(QWidget *parent) : QWidget(parent), mtx() { - } + HTVideoWidget(QWidget *parent) : QWidget(parent), fb(), width(0), height(0) { + connect(&timer, SIGNAL(timeout()), this, SLOT(update_and_repaint())); + timer.start(60); + } void update_image(unsigned char* frame, int width, int height); protected slots: void paintEvent( QPaintEvent* e ) { QMutexLocker foo(&mtx); QPainter painter(this); - painter.drawPixmap(e->rect(), pixmap, e->rect()); + painter.drawImage(e->rect(), texture); } + void update_and_repaint(); + private: QMutex mtx; - QPixmap pixmap; + QImage texture; + QTimer timer; + char fb[2048*2048*3]; + int width,height; }; #endif // VIDEOWIDGET_H diff --git a/ftnoir_tracker_ht/stdafx.h b/ftnoir_tracker_ht/stdafx.h index 0e532c9f..6f1539b7 100644 --- a/ftnoir_tracker_ht/stdafx.h +++ b/ftnoir_tracker_ht/stdafx.h @@ -4,7 +4,6 @@ #include <QImage> #include <QLabel> #include <QCoreApplication> -#include <QSettings> #include <QIcon> #include <QHBoxLayout> #include <QTimer> diff --git a/ftnoir_tracker_ht/video_widget.cpp b/ftnoir_tracker_ht/video_widget.cpp deleted file mode 100644 index 84cba6a3..00000000 --- a/ftnoir_tracker_ht/video_widget.cpp +++ /dev/null @@ -1,30 +0,0 @@ -/* Copyright (c) 2012 Patrick Ruoff - * - * 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. - */ - -#include "video_widget.h" - -#include <QDebug> - -using namespace std; - -void VideoWidget::update_image(unsigned char *frame, int width, int height) -{ - QMutexLocker foo(&mtx); - QImage qframe = QImage(width, height, QImage::Format_RGB888); - uchar* data = qframe.bits(); - const int pitch = qframe.bytesPerLine(); - for (int y = 0; y < height; y++) - for (int x = 0; x < width; x++) - { - const int pos = 3 * (y*width + x); - data[y * pitch + x * 3 + 0] = frame[pos + 2]; - data[y * pitch + x * 3 + 1] = frame[pos + 1]; - data[y * pitch + x * 3 + 2] = frame[pos + 0]; - } - qframe = qframe.scaled(size(), Qt::IgnoreAspectRatio, Qt::FastTransformation); - pixmap = QPixmap::fromImage(qframe); -} |