diff options
author | Stanislaw Halik <sthalik@misaki.pl> | 2013-01-18 21:46:03 +0000 |
---|---|---|
committer | Stanislaw Halik <sthalik@misaki.pl> | 2013-01-18 21:46:03 +0000 |
commit | e4ef9f33a072a0c46897a3e58fd9a7bada519a2b (patch) | |
tree | 4a89358faf9ec725af1c1492c322555cebd01fe5 /FTNoIR_Tracker_HT | |
parent | 9f7fd1d155128e1d382654d9de1c72f19006e856 (diff) |
First version of the HT tracker
git-svn-id: svn+ssh://svn.code.sf.net/p/facetracknoir/code@209 19e81ba0-9b1a-49c3-bd6c-561e1906d5fb
Diffstat (limited to 'FTNoIR_Tracker_HT')
-rw-r--r-- | FTNoIR_Tracker_HT/FTNoIR_Tracker_HT.vcproj | 347 | ||||
-rw-r--r-- | FTNoIR_Tracker_HT/TrackerControls.ui | 261 | ||||
-rw-r--r-- | FTNoIR_Tracker_HT/ftnoir_tracker_ht.cpp | 386 | ||||
-rw-r--r-- | FTNoIR_Tracker_HT/ftnoir_tracker_ht.h | 78 | ||||
-rw-r--r-- | FTNoIR_Tracker_HT/ftnoir_tracker_ht_dll.h | 19 | ||||
-rw-r--r-- | FTNoIR_Tracker_HT/headtracker-ftnoir.h | 24 | ||||
-rw-r--r-- | FTNoIR_Tracker_HT/ht-api.h | 85 | ||||
-rw-r--r-- | FTNoIR_Tracker_HT/stdafx.h | 40 |
8 files changed, 1240 insertions, 0 deletions
diff --git a/FTNoIR_Tracker_HT/FTNoIR_Tracker_HT.vcproj b/FTNoIR_Tracker_HT/FTNoIR_Tracker_HT.vcproj new file mode 100644 index 00000000..fc14e9af --- /dev/null +++ b/FTNoIR_Tracker_HT/FTNoIR_Tracker_HT.vcproj @@ -0,0 +1,347 @@ +<?xml version="1.0" encoding="windows-1250"?> +<VisualStudioProject + ProjectType="Visual C++" + Version="8,00" + Name="FTNoIR_Tracker_HT" + ProjectGUID="{61F2B142-F7DD-4070-8A68-53AD63A5D528}" + RootNamespace="FTNoIR_Tracker_HT" + Keyword="Qt4VSv1.0" + > + <Platforms> + <Platform + Name="Win32" + /> + </Platforms> + <ToolFiles> + </ToolFiles> + <Configurations> + <Configuration + Name="Debug|Win32" + OutputDirectory="$(SolutionDir)$(ConfigurationName)" + IntermediateDirectory="$(ConfigurationName)" + ConfigurationType="2" + CharacterSet="1" + > + <Tool + Name="VCPreBuildEventTool" + /> + <Tool + Name="VCCustomBuildTool" + /> + <Tool + Name="VCXMLDataGeneratorTool" + /> + <Tool + Name="VCWebServiceProxyGeneratorTool" + /> + <Tool + Name="VCMIDLTool" + /> + <Tool + Name="VCCLCompilerTool" + Optimization="0" + AdditionalIncludeDirectories=""$(QTDIR)include";"$(QTDIR)\include\QtCore";"$(QTDIR)\include\QtGui";".\.GeneratedFiles"" + PreprocessorDefinitions="WIN32;_DEBUG;_WINDOWS;_USRDLL;FTNOIR_TRACKER_HT_EXPORTS;QT_CORE_LIB;QT_GUI_LIB" + MinimalRebuild="true" + BasicRuntimeChecks="3" + RuntimeLibrary="3" + UsePrecompiledHeader="2" + WarningLevel="3" + Detect64BitPortabilityProblems="true" + DebugInformationFormat="4" + /> + <Tool + Name="VCManagedResourceCompilerTool" + /> + <Tool + Name="VCResourceCompilerTool" + /> + <Tool + Name="VCPreLinkEventTool" + /> + <Tool + Name="VCLinkerTool" + AdditionalDependencies="QtCored4.lib QtGuid4.lib" + LinkIncremental="2" + AdditionalLibraryDirectories="$(QTDIR)lib" + GenerateDebugInformation="true" + SubSystem="2" + TargetMachine="1" + /> + <Tool + Name="VCALinkTool" + /> + <Tool + Name="VCManifestTool" + /> + <Tool + Name="VCXDCMakeTool" + /> + <Tool + Name="VCBscMakeTool" + /> + <Tool + Name="VCFxCopTool" + /> + <Tool + Name="VCAppVerifierTool" + /> + <Tool + Name="VCWebDeploymentTool" + /> + <Tool + Name="VCPostBuildEventTool" + /> + </Configuration> + <Configuration + Name="Release|Win32" + OutputDirectory="$(SolutionDir)\bin" + IntermediateDirectory="$(ConfigurationName)" + ConfigurationType="2" + CharacterSet="1" + WholeProgramOptimization="1" + > + <Tool + Name="VCPreBuildEventTool" + /> + <Tool + Name="VCCustomBuildTool" + /> + <Tool + Name="VCXMLDataGeneratorTool" + /> + <Tool + Name="VCWebServiceProxyGeneratorTool" + /> + <Tool + Name="VCMIDLTool" + /> + <Tool + Name="VCCLCompilerTool" + AdditionalIncludeDirectories=""$(QTDIR)\include";"$(QTDIR)\include\QtCore";"$(QTDIR)\include\QtGui";".\.GeneratedFiles"" + PreprocessorDefinitions="WIN32;NDEBUG;_WINDOWS;_USRDLL;FTNOIR_TRACKER_HT_EXPORTS;QT_CORE_LIB;QT_GUI_LIB;FTNOIR_TRACKER_BASE_LIB" + RuntimeLibrary="2" + UsePrecompiledHeader="0" + WarningLevel="3" + Detect64BitPortabilityProblems="true" + DebugInformationFormat="3" + /> + <Tool + Name="VCManagedResourceCompilerTool" + /> + <Tool + Name="VCResourceCompilerTool" + /> + <Tool + Name="VCPreLinkEventTool" + /> + <Tool + Name="VCLinkerTool" + AdditionalDependencies="QtCore4.lib QtGui4.lib" + LinkIncremental="1" + AdditionalLibraryDirectories=""$(SolutionDir)\dinput";"$(QTDIR)\lib"" + GenerateDebugInformation="true" + SubSystem="2" + OptimizeReferences="1" + EnableCOMDATFolding="2" + TargetMachine="1" + /> + <Tool + Name="VCALinkTool" + /> + <Tool + Name="VCManifestTool" + /> + <Tool + Name="VCXDCMakeTool" + /> + <Tool + Name="VCBscMakeTool" + /> + <Tool + Name="VCFxCopTool" + /> + <Tool + Name="VCAppVerifierTool" + /> + <Tool + Name="VCWebDeploymentTool" + /> + <Tool + Name="VCPostBuildEventTool" + /> + </Configuration> + </Configurations> + <References> + </References> + <Files> + <Filter + Name="Source Files" + Filter="cpp;c;cc;cxx;def;odl;idl;hpj;bat;asm;asmx" + UniqueIdentifier="{4FC737F1-C7A5-4376-A066-2A32D752A2FF}" + > + <File + RelativePath=".\ftnoir_tracker_ht.cpp" + > + </File> + </Filter> + <Filter + Name="Header Files" + Filter="h;hpp;hxx;hm;inl;inc;xsd" + UniqueIdentifier="{93995380-89BD-4b04-88EB-625FBE52EBFB}" + > + <File + RelativePath=".\ftnoir_tracker_ht.h" + > + <FileConfiguration + Name="Debug|Win32" + > + <Tool + Name="VCCustomBuildTool" + Description="Moc'ing ftnoir_tracker_ht.h..." + CommandLine=""$(QTDIR)\bin\moc.exe" "$(InputPath)" -o ".\.GeneratedFiles$(ConfigurationName)\moc_$(InputName).cpp" -DWIN32 -D_DEBUG -D_WINDOWS -D_USRDLL -DFTNOIR_TRACKER_HT_EXPORTS -DQT_CORE_LIB -DQT_GUI_LIB -D_WINDLL -D_UNICODE -DUNICODE "-I$(QTDIR)include" "-I$(QTDIR)\include\QtCore" "-I$(QTDIR)\include\QtGui" "-I.\.GeneratedFiles" "-fStdAfx.h" "-f../ftnoir_tracker_ht.h"
" + AdditionalDependencies=""$(QTDIR)\bin\moc.exe";$(InputPath)" + Outputs="".\.GeneratedFiles$(ConfigurationName)\moc_$(InputName).cpp"" + /> + </FileConfiguration> + <FileConfiguration + Name="Release|Win32" + > + <Tool + Name="VCCustomBuildTool" + Description="Moc'ing ftnoir_tracker_ht.h..." + CommandLine=""$(QTDIR)\bin\moc.exe" "$(InputPath)" -o ".\.GeneratedFiles$(ConfigurationName)\moc_$(InputName).cpp" -DWIN32 -DNDEBUG -D_WINDOWS -D_USRDLL -DFTNOIR_TRACKER_HT_EXPORTS -DQT_CORE_LIB -DQT_GUI_LIB -DFTNOIR_TRACKER_BASE_LIB -D_WINDLL -D_UNICODE -DUNICODE "-I$(QTDIR)\include" "-I$(QTDIR)\include\QtCore" "-I$(QTDIR)\include\QtGui" "-I.\.GeneratedFiles"
" + AdditionalDependencies=""$(QTDIR)\bin\moc.exe";$(InputPath)" + Outputs="".\.GeneratedFiles$(ConfigurationName)\moc_$(InputName).cpp"" + /> + </FileConfiguration> + </File> + <File + RelativePath=".\ftnoir_tracker_ht_dll.h" + > + </File> + <File + RelativePath=".\headtracker-ftnoir.h" + > + </File> + <File + RelativePath=".\ht-api.h" + > + </File> + <File + RelativePath=".\stdafx.h" + > + </File> + </Filter> + <Filter + Name="Resource Files" + Filter="rc;ico;cur;bmp;dlg;rc2;rct;bin;rgs;gif;jpg;jpeg;jpe;resx;tiff;tif;png;wav" + UniqueIdentifier="{67DA6AB6-F800-4c08-8B7A-83BB121AAD01}" + > + </Filter> + <Filter + Name="Generated Files" + Filter="moc;h;cpp" + UniqueIdentifier="{71ED8ED8-ACB9-4CE9-BBE1-E00B30144E11}" + > + <File + RelativePath=".\.generatedfiles\ui_TrackerControls.h" + > + </File> + <Filter + Name="Debug" + Filter="cpp;moc" + SourceControlFiles="false" + > + <File + RelativePath=".\.GeneratedFilesDebug\moc_ftnoir_tracker_ht.cpp" + > + <FileConfiguration + Name="Release|Win32" + ExcludedFromBuild="true" + > + <Tool + Name="VCCLCompilerTool" + /> + </FileConfiguration> + </File> + </Filter> + <Filter + Name="Release" + Filter="cpp;moc" + SourceControlFiles="false" + > + <File + RelativePath=".\.GeneratedFilesRelease\moc_ftnoir_tracker_ht.cpp" + > + <FileConfiguration + Name="Debug|Win32" + ExcludedFromBuild="true" + > + <Tool + Name="VCCLCompilerTool" + /> + </FileConfiguration> + </File> + </Filter> + </Filter> + <Filter + Name="Form Files" + Filter="ui" + UniqueIdentifier="{99349809-55BA-4b9d-BF79-8FDBB0286EB3}" + > + <File + RelativePath=".\TrackerControls.ui" + > + <FileConfiguration + Name="Debug|Win32" + > + <Tool + Name="VCCustomBuildTool" + Description="Uic'ing $(InputFileName)..." + CommandLine=""$(QTDIR)\bin\uic.exe" -o ".\.GeneratedFiles\ui_$(InputName).h" "$(InputPath)"
" + AdditionalDependencies="$(QTDIR)\bin\uic.exe" + Outputs="".\.GeneratedFiles\ui_$(InputName).h"" + /> + </FileConfiguration> + <FileConfiguration + Name="Release|Win32" + > + <Tool + Name="VCCustomBuildTool" + Description="Uic'ing $(InputFileName)..." + CommandLine=""$(QTDIR)\bin\uic.exe" -o ".\.GeneratedFiles\ui_$(InputName).h" "$(InputPath)"
" + AdditionalDependencies="$(QTDIR)\bin\uic.exe" + Outputs="".\.GeneratedFiles\ui_$(InputName).h"" + /> + </FileConfiguration> + </File> + </Filter> + </Files> + <Globals> + <Global + Name="lupdateOnBuild" + Value="1" + /> + <Global + Name="MocDir" + Value=".GeneratedFiles$(ConfigurationName)" + /> + <Global + Name="MocOptions" + Value="" + /> + <Global + Name="QtVersion Win32" + Value="qt-everywhere-opensource-src-4.6.2" + /> + <Global + Name="RccDir" + Value=".GeneratedFiles" + /> + <Global + Name="UicDir" + Value=".GeneratedFiles" + /> + </Globals> +</VisualStudioProject> diff --git a/FTNoIR_Tracker_HT/TrackerControls.ui b/FTNoIR_Tracker_HT/TrackerControls.ui new file mode 100644 index 00000000..7f599579 --- /dev/null +++ b/FTNoIR_Tracker_HT/TrackerControls.ui @@ -0,0 +1,261 @@ +<?xml version="1.0" encoding="UTF-8"?> +<ui version="4.0"> + <class>Form</class> + <widget class="QWidget" name="Form"> + <property name="geometry"> + <rect> + <x>0</x> + <y>0</y> + <width>378</width> + <height>127</height> + </rect> + </property> + <property name="sizePolicy"> + <sizepolicy hsizetype="Fixed" vsizetype="Fixed"> + <horstretch>0</horstretch> + <verstretch>0</verstretch> + </sizepolicy> + </property> + <property name="maximumSize"> + <size> + <width>378</width> + <height>127</height> + </size> + </property> + <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>Vertical camera field of view</string> + </property> + </widget> + <widget class="QDoubleSpinBox" name="cameraFOV"> + <property name="geometry"> + <rect> + <x>150</x> + <y>10</y> + <width>91</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>69.000000000000000</double> + </property> + </widget> + <widget class="QLabel" name="label_2"> + <property name="geometry"> + <rect> + <x>10</x> + <y>40</y> + <width>101</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>150</x> + <y>40</y> + <width>81</width> + <height>22</height> + </rect> + </property> + <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> + </widget> + <widget class="QLabel" name="label_3"> + <property name="geometry"> + <rect> + <x>10</x> + <y>70</y> + <width>71</width> + <height>16</height> + </rect> + </property> + <property name="text"> + <string>Camera index</string> + </property> + </widget> + <widget class="QSpinBox" name="cameraIndex"> + <property name="geometry"> + <rect> + <x>150</x> + <y>70</y> + <width>42</width> + <height>22</height> + </rect> + </property> + <property name="minimum"> + <number>-1</number> + </property> + <property name="maximum"> + <number>255</number> + </property> + <property name="singleStep"> + <number>1</number> + </property> + <property name="value"> + <number>-1</number> + </property> + </widget> + <widget class="QPushButton" name="buttonOK"> + <property name="geometry"> + <rect> + <x>220</x> + <y>100</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>300</x> + <y>100</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>270</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> + <resources/> + <connections/> +</ui> 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 diff --git a/FTNoIR_Tracker_HT/ftnoir_tracker_ht.h b/FTNoIR_Tracker_HT/ftnoir_tracker_ht.h new file mode 100644 index 00000000..30d62f32 --- /dev/null +++ b/FTNoIR_Tracker_HT/ftnoir_tracker_ht.h @@ -0,0 +1,78 @@ +/* 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 + * copyright notice and this permission notice appear in all copies. + */ + +#ifndef FTNOIR_TRACKER_HT_H +#define FTNOIR_TRACKER_HT_H + +#include "stdafx.h" +#include "..\ftnoir_tracker_base\ftnoir_tracker_base.h" +#include "headtracker-ftnoir.h" +#include "ui_TrackerControls.h" + +class VideoWidget : public QWidget +{ + Q_OBJECT +public: + VideoWidget(QWidget* parent); + ~VideoWidget(); + ht_video_t videoFrame; + HANDLE hMutex; +protected: + void paintEvent(QPaintEvent* e); +private: + QTimer timer; +}; + +class Tracker : public ITracker +{ +public: + Tracker(); + ~Tracker(); + void Initialize(QFrame *videoframe); + void StartTracker(HWND parent_window); + void StopTracker(bool exit); + bool GiveHeadPoseData(THeadPoseData *data); + bool enableTX, enableTY, enableTZ, enableRX, enableRY, enableRZ; + ht_shm_t* shm; +private: + HANDLE hMutex, hMapFile; + bool paused; + QProcess subprocess; + VideoWidget* videoWidget; + QHBoxLayout* layout; +}; + +// Widget that has controls for FTNoIR protocol client-settings. +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 unRegisterTracker() {}; + +private: + Ui::Form ui; + void loadSettings(); + void save(); + bool settingsDirty; + +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 new file mode 100644 index 00000000..01b4cfa0 --- /dev/null +++ b/FTNoIR_Tracker_HT/ftnoir_tracker_ht_dll.h @@ -0,0 +1,19 @@ +/* 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 + * copyright notice and this permission notice appear in all copies. + */ + +#include "..\ftnoir_tracker_base\ftnoir_tracker_base.h" + +//----------------------------------------------------------------------------- +class TrackerDll : public ITrackerDll +{ + // ITrackerDll interface + void Initialize() {} + void getFullName(QString *strToBeFilled); + void getShortName(QString *strToBeFilled); + void getDescription(QString *strToBeFilled); + void getIcon(QIcon *icon); +};
\ No newline at end of file diff --git a/FTNoIR_Tracker_HT/headtracker-ftnoir.h b/FTNoIR_Tracker_HT/headtracker-ftnoir.h new file mode 100644 index 00000000..48510997 --- /dev/null +++ b/FTNoIR_Tracker_HT/headtracker-ftnoir.h @@ -0,0 +1,24 @@ +#pragma once +#include <stdlib.h> +#include <stdio.h> +#include "ht-api.h" + +#define HT_SHM_NAME "ftnoir-tracker-ht-shm" +#define HT_MUTEX_NAME "ftnoir-tracker-ht-mutex" + +#define HT_MAX_VIDEO_WIDTH 2048 +#define HT_MAX_VIDEO_HEIGHT 1536 +#define HT_MAX_VIDEO_CHANNELS 3 + +typedef struct { + int width, height, channels; + unsigned char frame[HT_MAX_VIDEO_WIDTH * HT_MAX_VIDEO_HEIGHT * HT_MAX_VIDEO_CHANNELS]; +} ht_video_t; + +typedef struct { + ht_video_t frame; + ht_config_t config; + ht_result_t result; + volatile int timer; + volatile bool pause, terminate, running; +} ht_shm_t; diff --git a/FTNoIR_Tracker_HT/ht-api.h b/FTNoIR_Tracker_HT/ht-api.h new file mode 100644 index 00000000..ac8d45cf --- /dev/null +++ b/FTNoIR_Tracker_HT/ht-api.h @@ -0,0 +1,85 @@ +#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 +# else +# define HT_API(t) HT_EXTERN t +# endif +#endif +#if !defined(_WIN32) && !defined(_isnan) +# define _isnan isnan +#endif +#include <stdio.h> +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 ransac_max_inlier_error; + float ransac_max_reprojection_error; + int max_keypoints; + int keypoint_quality; + float keypoint_distance; + float keypoint_3distance; + int force_width; + int force_height; + int force_fps; + int camera_index; + bool debug; + int ransac_num_iters; + float ransac_min_features; + float ransac_max_mean_error; + float ransac_abs_max_mean_error; +} ht_config_t; + +typedef struct { + double rotx, roty, rotz; + double tx, ty, tz; + 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(bool) ht_cycle(headtracker_t* ctx, ht_result_t* euler); +HT_API(void) ht_reset(headtracker_t* ctx); diff --git a/FTNoIR_Tracker_HT/stdafx.h b/FTNoIR_Tracker_HT/stdafx.h new file mode 100644 index 00000000..a0c72843 --- /dev/null +++ b/FTNoIR_Tracker_HT/stdafx.h @@ -0,0 +1,40 @@ +// stdafx.h : include file for standard system include files, +// or project specific include files that are used frequently, but +// are changed infrequently +// + +#pragma once + +// Modify the following defines if you have to target a platform prior to the ones specified below. +// Refer to MSDN for the latest info on corresponding values for different platforms. +#ifndef WINVER // Allow use of features specific to Windows XP or later. +#define WINVER 0x0501 // Change this to the appropriate value to target other versions of Windows. +#endif + +#ifndef _WIN32_WINNT // Allow use of features specific to Windows XP or later. +#define _WIN32_WINNT 0x0501 // Change this to the appropriate value to target other versions of Windows. +#endif + +#ifndef _WIN32_WINDOWS // Allow use of features specific to Windows 98 or later. +#define _WIN32_WINDOWS 0x0410 // Change this to the appropriate value to target Windows Me or later. +#endif + +#ifndef _WIN32_IE // Allow use of features specific to IE 6.0 or later. +#define _WIN32_IE 0x0600 // Change this to the appropriate value to target other versions of IE. +#endif + +#define WIN32_LEAN_AND_MEAN // Exclude rarely-used stuff from Windows headers +// Windows Header Files: +#include <windows.h> +#include <QWidget> +#include <QMessageBox> +#include <QProcess> +#include <QImage> +#include <QLabel> +#include <QCoreApplication> +#include <QSettings> +#include <QIcon> +#include <QHBoxLayout> +#include <QTimer> +#include <QPainter> +#include <QPaintEvent>
\ No newline at end of file |