From 7eeb8dfaede7bb54b37b8ea538135914a43ab011 Mon Sep 17 00:00:00 2001 From: Wim Vriend Date: Mon, 21 Mar 2011 21:32:13 +0000 Subject: New effort to embrace faceAPI 3.2.6 git-svn-id: svn+ssh://svn.code.sf.net/p/facetracknoir/code@54 19e81ba0-9b1a-49c3-bd6c-561e1906d5fb --- FaceTrackNoIR/AutoClosePtr.h | 89 ++++++++++++++++++++++++++++ FaceTrackNoIR/FaceTrackNoIR.cpp | 34 ++++------- FaceTrackNoIR/FaceTrackNoIR.h | 10 ++-- FaceTrackNoIR/FaceTrackNoIR.vcproj | 2 +- FaceTrackNoIR/main.cpp | 3 - FaceTrackNoIR/tracker.cpp | 117 +++++++++++++++---------------------- FaceTrackNoIR/tracker.h | 11 ++-- 7 files changed, 158 insertions(+), 108 deletions(-) create mode 100644 FaceTrackNoIR/AutoClosePtr.h (limited to 'FaceTrackNoIR') diff --git a/FaceTrackNoIR/AutoClosePtr.h b/FaceTrackNoIR/AutoClosePtr.h new file mode 100644 index 00000000..690d2c62 --- /dev/null +++ b/FaceTrackNoIR/AutoClosePtr.h @@ -0,0 +1,89 @@ +//////////////////////////////////////////////////////////////////////////////// +// Auto pointer template. + +#if !defined(AUTOCLOSEPTR_H) +#define AUTOCLOSEPTR_H + +////////////////////////////////////////////////////////////////////////////// +// T auto pointer (not suitable for containers). +// This auto pointer uses T's member function to perform clean up, rather +// than `operator Closeete'. +// +template +class AutoClosePtr +{ +public: + explicit AutoClosePtr(T* p = NULL) + : m_p(p) + { // construct from object pointer + } + + AutoClosePtr(AutoClosePtr& Other) + : m_p(Other.Release()) + { // construct from Other AutoClosePtr + } + + AutoClosePtr& operator=(AutoClosePtr& Other) + { // assign Other + Reset(Other.Release()); + return (*this); + } + + ~AutoClosePtr() + { // close and destroy + if(m_p) + { + (m_p->*Close)(); + m_p = NULL; + } + } + + T& operator*() const + { // return T + return (*m_p); + } + + T** operator&() + { // return the address of the wrapped pointer + Reset(); + return &m_p; + } + + T* operator->() const + { // return wrapped pointer + return Get(); + } + + operator bool() const + { // check wrapped pointer for NULL + return m_p != NULL; + } + + T* Get() const + { // return wrapped pointer + return m_p; + } + + T* Release() + { // return wrapped pointer and give up ownership + T* pTmp = m_p; + m_p = NULL; + return pTmp; + } + + void Reset(T* p = NULL) + { // destroy the object and store new pointer + if(p != m_p) + { + if(m_p) + (m_p->*Close)(); + } + + m_p = p; + } + +private: + T* m_p; // the wrapped raw pointer +}; + +#endif // AUTOCLOSEPTR_H \ No newline at end of file diff --git a/FaceTrackNoIR/FaceTrackNoIR.cpp b/FaceTrackNoIR/FaceTrackNoIR.cpp index 2acf8ec0..029ed5b7 100644 --- a/FaceTrackNoIR/FaceTrackNoIR.cpp +++ b/FaceTrackNoIR/FaceTrackNoIR.cpp @@ -34,9 +34,6 @@ #include "FGServer.h" #include "FTNServer.h" -using namespace sm::faceapi; -using namespace sm::faceapi::qt; - // // Setup the Main Dialog // @@ -56,7 +53,7 @@ QMainWindow(parent, flags) _curve_config = 0; tracker = 0; - _display = 0; +// _display = 0; l = 0; trayIcon = 0; @@ -204,6 +201,13 @@ void FaceTrackNoIR::updateSettings() { } } +// +// Get a pointer to the video-widget, to use in the DLL +// +QFrame *FaceTrackNoIR::getVideoWidget() { + return ui.video_frame; +} + /** read the name of the first video-capturing device at start up **/ /** FaceAPI can only use this first one... **/ void FaceTrackNoIR::GetCameraNameDX() { @@ -488,21 +492,13 @@ void FaceTrackNoIR::startTracker( ) { // // Create the Tracker and setup // - tracker = new Tracker ( ui.iconcomboBox->currentIndex(), ui.iconcomboTrackerSource->currentIndex() ); - - // Show the video widget - //ui.video_frame->show(); - //_display = new VideoDisplayWidget( tracker->getEngine(), ui.video_frame, 0 ); - //l = new QVBoxLayout(ui.video_frame); - //l->setMargin(0); - //l->setSpacing(0); - //l->addWidget(_display); + tracker = new Tracker ( ui.iconcomboBox->currentIndex(), ui.iconcomboTrackerSource->currentIndex(), this ); // // Setup the Tracker and send the settings. // This is necessary, because the events are only triggered 'on change' // - tracker->setup( ui.headPoseWidget , this); + tracker->setup(); tracker->setSmoothing ( ui.slideSmoothing->value() ); tracker->setUseFilter (ui.chkUseEWMA->isChecked() ); @@ -574,15 +570,7 @@ void FaceTrackNoIR::stopTracker( ) { // // Delete the video-display. // - if ( _display ) { - _display->disconnect(); - delete _display; - _display = 0; - delete l; - l = 0; - qDebug() << "stopTracker says: display deleted"; - } - ui.video_frame->hide(); +// ui.video_frame->hide(); if ( tracker ) { qDebug() << "stopTracker says: Deleting tracker!"; diff --git a/FaceTrackNoIR/FaceTrackNoIR.h b/FaceTrackNoIR/FaceTrackNoIR.h index 7518d896..7f73b5af 100644 --- a/FaceTrackNoIR/FaceTrackNoIR.h +++ b/FaceTrackNoIR/FaceTrackNoIR.h @@ -50,11 +50,11 @@ typedef AutoClosePtr ITrackerDia typedef ITrackerDialog *(WINAPI *importGetTrackerDialog)(void); -#include +//#include #include -using namespace sm::faceapi; -using namespace sm::faceapi::qt; +//using namespace sm::faceapi; +//using namespace sm::faceapi::qt; class Tracker; // pre-define class to avoid circular includes @@ -72,6 +72,8 @@ public: void getGameProgramName(); // Get the ProgramName from the game and display it. void updateSettings(); // Update the settings (let Tracker read INI-file). + QFrame *getVideoWidget(); // Get a pointer to the video-widget, to use in the DLL + private: Ui::FaceTrackNoIRClass ui; Tracker *tracker; @@ -82,7 +84,7 @@ private: ITrackerDialogPtr pTrackerDialog; // Pointer to Tracker dialog instance (in DLL) /** face api variables **/ - VideoDisplayWidget *_display; +// VideoDisplayWidget *_display; QVBoxLayout *l; QWidget *_engine_controls; QWidget *_server_controls; diff --git a/FaceTrackNoIR/FaceTrackNoIR.vcproj b/FaceTrackNoIR/FaceTrackNoIR.vcproj index 16a3d715..10245e4b 100644 --- a/FaceTrackNoIR/FaceTrackNoIR.vcproj +++ b/FaceTrackNoIR/FaceTrackNoIR.vcproj @@ -70,7 +70,7 @@ /> #include -using namespace sm::faceapi; -using namespace sm::faceapi::qt; - int main(int argc, char *argv[]) { //// QApplication a(argc, argv); diff --git a/FaceTrackNoIR/tracker.cpp b/FaceTrackNoIR/tracker.cpp index 18b9c0b8..39bc8dce 100644 --- a/FaceTrackNoIR/tracker.cpp +++ b/FaceTrackNoIR/tracker.cpp @@ -23,6 +23,7 @@ *********************************************************************************/ /* Modifications (last one on top): + 20110313 - WVR: Removed 'set_initial'. Less is more. 20110109 - WVR: Added setZero option to define behaviour after STOP tracking via shortkey. 20110104 - WVR: Removed a few nasty bugs (it was impossible to stop tracker without crash). 20101224 - WVR: Removed the QThread inheritance of the Base Class for the protocol-servers. @@ -57,7 +58,6 @@ // Flags bool Tracker::confid = false; -bool Tracker::set_initial = false; bool Tracker::do_tracking = true; bool Tracker::do_center = false; bool Tracker::do_inhibit = false; @@ -66,7 +66,6 @@ bool Tracker::setZero = true; bool Tracker::setEngineStop = true; HANDLE Tracker::hTrackMutex = 0; -long Tracker::prevHeadPoseTime = 0; THeadPoseDOF Tracker::Pitch; // One structure for each of 6DOF's THeadPoseDOF Tracker::Yaw; THeadPoseDOF Tracker::Roll; @@ -83,12 +82,15 @@ IFilterPtr Tracker::pFilter; // Pointer to Filter instance (in DLL) /** constructor **/ -Tracker::Tracker( int clientID, int facetrackerID ) { +Tracker::Tracker( int clientID, int facetrackerID, FaceTrackNoIR *parent ) { importGetTracker getIT; QLibrary *trackerLib; importGetFilter getFilter; QLibrary *filterLib; +QFrame *video_frame; + // Retieve the pointer to the parent + mainApp = parent; // Remember the selected client, from the ListBox // If the Tracker runs, this can NOT be changed... @@ -111,6 +113,13 @@ QLibrary *filterLib; Tracker::Y.initHeadPoseData(); Tracker::Z.initHeadPoseData(); + // + // Locate the video-frame, for the DLL + // + video_frame = 0; + video_frame = mainApp->getVideoWidget(); + qDebug() << "Tracker::setup VideoFrame = " << video_frame; + // // Start the selected Tracker-engine // @@ -125,7 +134,7 @@ QLibrary *filterLib; if (ptrXyz) { pTracker = ptrXyz; - pTracker->Initialize(); + pTracker->Initialize( video_frame ); qDebug() << "Tracker::setup Function Resolved!"; } } @@ -144,7 +153,7 @@ QLibrary *filterLib; if (ptrXyz) { pTracker = ptrXyz; - pTracker->Initialize(); + pTracker->Initialize( video_frame ); qDebug() << "Tracker::setup Function Resolved!"; } } @@ -255,12 +264,11 @@ Tracker::~Tracker() { } /** setting up the tracker engine **/ -void Tracker::setup(QWidget *head, FaceTrackNoIR *parent) { +void Tracker::setup() { bool DLL_Ok; // retrieve pointers to the User Interface and the main Application - mainApp = parent; - pTracker->StartTracker(); + pTracker->StartTracker( mainApp->winId() ); // // Check if the Protocol-server files were installed OK. @@ -296,14 +304,12 @@ void Tracker::run() { bool lastStartStopKey = false; bool lastInhibitKey = false; - SYSTEMTIME now; - long newHeadPoseTime; - float dT; - THeadPoseData current_camera_position; // Used for filtering THeadPoseData target_camera_position; THeadPoseData new_camera_position; + Tracker::do_center = true; // Center initially + current_camera_position.x = 0.0f; current_camera_position.y = 0.0f; current_camera_position.z = 0.0f; @@ -406,7 +412,6 @@ void Tracker::run() { if (Tracker::do_tracking) { Tracker::do_center = true; - Tracker::set_initial = false; Tracker::confid = false; Pitch.rawList.clear(); @@ -429,7 +434,7 @@ void Tracker::run() { current_camera_position.pitch = 0.0f; current_camera_position.roll = 0.0f; - pTracker->StartTracker(); + pTracker->StartTracker( mainApp->winId() ); } else { if (setEngineStop) { // Only stop engine when option is checked @@ -471,49 +476,21 @@ void Tracker::run() { THeadPoseData newpose; Tracker::confid = pTracker->GiveHeadPoseData(&newpose); - addHeadPose(newpose); - - // - // Get the System-time and substract the time from the previous call. - // dT will be used for the EWMA-filter. - // - GetSystemTime ( &now ); - newHeadPoseTime = (((now.wHour * 3600) + (now.wMinute * 60) + now.wSecond) * 1000) + now.wMilliseconds; - dT = (newHeadPoseTime - Tracker::prevHeadPoseTime) / 1000.0f; - - // Remember time for next call - Tracker::prevHeadPoseTime = newHeadPoseTime; - - //if the confidence is good enough the headpose will be updated **/ - if (Tracker::confid) { - - // - // Most games need an offset to the initial position and NOT the - // absolute distance to the camera: so remember the initial distance - // to substract that later... - // - if(Tracker::set_initial == false) { - Tracker::Pitch.initial_headPos = Tracker::Pitch.headPos; - Tracker::Yaw.initial_headPos = Tracker::Yaw.headPos; - Tracker::Roll.initial_headPos = Tracker::Roll.headPos; - Tracker::X.initial_headPos = Tracker::X.headPos; - Tracker::Y.initial_headPos = Tracker::Y.headPos; - Tracker::Z.initial_headPos = Tracker::Z.headPos; - MessageBeep (MB_ICONASTERISK); - Tracker::set_initial = true; - } + if ( Tracker::confid ) { + addHeadPose(newpose); } // // If Center is pressed, copy the current values to the offsets. // - if (Tracker::do_center && Tracker::set_initial) { - Pitch.offset_headPos = getSmoothFromList( &Pitch.rawList )- Tracker::Pitch.initial_headPos; - Yaw.offset_headPos = getSmoothFromList( &Yaw.rawList ) - Tracker::Yaw.initial_headPos; - Roll.offset_headPos = getSmoothFromList( &Roll.rawList ) - Tracker::Roll.initial_headPos; - X.offset_headPos = getSmoothFromList( &X.rawList ) - Tracker::X.initial_headPos; - Y.offset_headPos = getSmoothFromList( &Y.rawList ) - Tracker::Y.initial_headPos; - Z.offset_headPos = getSmoothFromList( &Z.rawList ) - Tracker::Z.initial_headPos; + if (Tracker::confid && Tracker::do_center) { + Pitch.offset_headPos = getSmoothFromList( &Pitch.rawList ); + Yaw.offset_headPos = getSmoothFromList( &Yaw.rawList ); + Roll.offset_headPos = getSmoothFromList( &Roll.rawList ); + X.offset_headPos = getSmoothFromList( &X.rawList ); + Y.offset_headPos = getSmoothFromList( &Y.rawList ); + Z.offset_headPos = getSmoothFromList( &Z.rawList ); + MessageBeep (MB_ICONASTERISK); Tracker::do_center = false; } @@ -521,23 +498,23 @@ void Tracker::run() { if (Tracker::do_tracking && Tracker::confid) { // Pitch - target_camera_position.x = getSmoothFromList( &X.rawList ) - X.offset_headPos - X.initial_headPos; - target_camera_position.y = getSmoothFromList( &Y.rawList ) - Y.offset_headPos - Y.initial_headPos; - target_camera_position.z = getSmoothFromList( &Z.rawList ) - Z.offset_headPos - Z.initial_headPos; - target_camera_position.pitch = getSmoothFromList( &Pitch.rawList ) - Pitch.offset_headPos - Pitch.initial_headPos; - target_camera_position.yaw = getSmoothFromList( &Yaw.rawList ) - Yaw.offset_headPos - Yaw.initial_headPos; - target_camera_position.roll = getSmoothFromList( &Roll.rawList ) - Roll.offset_headPos - Roll.initial_headPos; + target_camera_position.x = getSmoothFromList( &X.rawList ) - X.offset_headPos; + target_camera_position.y = getSmoothFromList( &Y.rawList ) - Y.offset_headPos; + target_camera_position.z = getSmoothFromList( &Z.rawList ) - Z.offset_headPos; + target_camera_position.pitch = getSmoothFromList( &Pitch.rawList ) - Pitch.offset_headPos; + target_camera_position.yaw = getSmoothFromList( &Yaw.rawList ) - Yaw.offset_headPos; + target_camera_position.roll = getSmoothFromList( &Roll.rawList ) - Roll.offset_headPos; if (Tracker::useFilter && pFilter) { pFilter->FilterHeadPoseData(¤t_camera_position, &target_camera_position, &new_camera_position, Tracker::Pitch.newSample); } else { - new_camera_position.x = getSmoothFromList( &X.rawList ) - X.offset_headPos - X.initial_headPos; - new_camera_position.y = getSmoothFromList( &Y.rawList ) - Y.offset_headPos - Y.initial_headPos; - new_camera_position.z = getSmoothFromList( &Z.rawList ) - Z.offset_headPos - Z.initial_headPos; - new_camera_position.pitch = getSmoothFromList( &Pitch.rawList ) - Pitch.offset_headPos - Pitch.initial_headPos; - new_camera_position.yaw = getSmoothFromList( &Yaw.rawList ) - Yaw.offset_headPos - Yaw.initial_headPos; - new_camera_position.roll = getSmoothFromList( &Roll.rawList ) - Roll.offset_headPos - Roll.initial_headPos; + new_camera_position.x = getSmoothFromList( &X.rawList ) - X.offset_headPos; + new_camera_position.y = getSmoothFromList( &Y.rawList ) - Y.offset_headPos; + new_camera_position.z = getSmoothFromList( &Z.rawList ) - Z.offset_headPos; + new_camera_position.pitch = getSmoothFromList( &Pitch.rawList ) - Pitch.offset_headPos; + new_camera_position.yaw = getSmoothFromList( &Yaw.rawList ) - Yaw.offset_headPos; + new_camera_position.roll = getSmoothFromList( &Roll.rawList ) - Roll.offset_headPos; } new_camera_position.x = X.invert * getOutputFromCurve(&X.curve, new_camera_position.x, X.NeutralZone, X.MaxInput); new_camera_position.y = Y.invert * getOutputFromCurve(&Y.curve, new_camera_position.y, Y.NeutralZone, Y.MaxInput); @@ -757,13 +734,13 @@ void Tracker::setPowCurve( int x ) { // Set the filter-value from the GUI. // void Tracker::getHeadPose( THeadPoseData *data ) { - data->x = Tracker::X.headPos - Tracker::X.initial_headPos; // centimeters - data->y = Tracker::Y.headPos - Tracker::Y.initial_headPos; - data->z = Tracker::Z.headPos - Tracker::Z.initial_headPos; + data->x = Tracker::X.headPos - Tracker::X.offset_headPos; // centimeters + data->y = Tracker::Y.headPos - Tracker::Y.offset_headPos; + data->z = Tracker::Z.headPos - Tracker::Z.offset_headPos; - data->pitch = Tracker::Pitch.headPos- Tracker::Pitch.initial_headPos; // degrees - data->yaw = Tracker::Yaw.headPos- Tracker::Yaw.initial_headPos; - data->roll = Tracker::Roll.headPos - Tracker::Roll.initial_headPos; + data->pitch = Tracker::Pitch.headPos- Tracker::Pitch.offset_headPos; // degrees + data->yaw = Tracker::Yaw.headPos- Tracker::Yaw.offset_headPos; + data->roll = Tracker::Roll.headPos - Tracker::Roll.offset_headPos; } // diff --git a/FaceTrackNoIR/tracker.h b/FaceTrackNoIR/tracker.h index 2ee26bba..bd29bf9f 100644 --- a/FaceTrackNoIR/tracker.h +++ b/FaceTrackNoIR/tracker.h @@ -94,7 +94,7 @@ class THeadPoseDOF { public: void initHeadPoseData(){ headPos = 0.0f; - initial_headPos = 0.0f; +// initial_headPos = 0.0f; offset_headPos = 0.0f; invert = 0.0f; red = 0.0f; @@ -109,7 +109,7 @@ public: newSample = FALSE; } float headPos; // Current position (from faceTracker, radials or meters) - float initial_headPos; // Position on startup (first valid value) +// float initial_headPos; // Position on startup (first valid value) float offset_headPos; // Offset for centering float invert; // Invert measured value (= 1.0f or -1.0f) float red; // Reduction factor (used for EWMA-filtering, between 0.0f and 1.0f) @@ -174,18 +174,15 @@ private: // Flags to start/stop/reset tracking static bool confid; // Tracker data is OK - static bool set_initial; // initial headpose is set static bool do_tracking; // Start/stop tracking, using the shortkey static bool do_center; // Center head-position, using the shortkey static bool do_inhibit; // Inhibit DOF-axis, using the shortkey static HANDLE hTrackMutex; // Prevent reading/writing the headpose simultaneously - static bool useFilter; // Use EWMA-filtering static bool setZero; // Set to zero's, when OFF (one-shot) static bool setEngineStop; // Stop tracker->engine, when OFF - static long prevHeadPoseTime; // Time from previous sample FaceTrackNoIR *mainApp; @@ -197,10 +194,10 @@ protected: void run(); public: - Tracker( int clientID, int facetrackerID ); + Tracker( int clientID, int facetrackerID, FaceTrackNoIR *parent ); ~Tracker(); - void setup(QWidget *head, FaceTrackNoIR *parent); + void setup(); // void registerHeadPoseCallback(); bool handleGameCommand ( int command ); -- cgit v1.2.3