From be57b6b8d3f8339980df08f196d23415f7974418 Mon Sep 17 00:00:00 2001 From: Wim Vriend Date: Tue, 22 Mar 2011 09:08:56 +0000 Subject: First success merging 3.2.6 git-svn-id: svn+ssh://svn.code.sf.net/p/facetracknoir/code@55 19e81ba0-9b1a-49c3-bd6c-561e1906d5fb --- FTNoIR_Tracker_Base/ftnoir_tracker_sm_types.h | 23 +++ FTNoIR_Tracker_SM/FTNoIR_Tracker_SM.h | 29 ++-- FTNoIR_Tracker_SM/FTNoIR_Tracker_SM.vcproj | 95 ------------- FTNoIR_Tracker_SM/ftnoir_tracker_faceapi.cpp | 194 ++++++++++++++++++-------- FaceTrackNoIR.suo | Bin 349184 -> 353280 bytes faceAPI/main.cpp | 54 ++++--- 6 files changed, 206 insertions(+), 189 deletions(-) create mode 100644 FTNoIR_Tracker_Base/ftnoir_tracker_sm_types.h diff --git a/FTNoIR_Tracker_Base/ftnoir_tracker_sm_types.h b/FTNoIR_Tracker_Base/ftnoir_tracker_sm_types.h new file mode 100644 index 00000000..9ebfd173 --- /dev/null +++ b/FTNoIR_Tracker_Base/ftnoir_tracker_sm_types.h @@ -0,0 +1,23 @@ +// +// Definitions for the Shared Memory to send the data to FaceTrackNoIR +// +static const char* SM_MM_DATA = "SM_SharedMem"; +static const char* SM_FACEAPI = "SM_FaceAPI"; +static const char* SM_MUTEX = "SM_Mutex"; + +#include "sm_api.h" + +struct TFaceData { + int DataID; + smEngineHeadPoseData new_pose; +}; +typedef TFaceData * PFaceData; + +struct SMMemMap { + int command; // Command from FaceTrackNoIR + int status; // Status from faceAPI + TFaceData data; + HANDLE handle; +}; +typedef SMMemMap * PSMMemMap; + diff --git a/FTNoIR_Tracker_SM/FTNoIR_Tracker_SM.h b/FTNoIR_Tracker_SM/FTNoIR_Tracker_SM.h index 9af25800..5bed0a16 100644 --- a/FTNoIR_Tracker_SM/FTNoIR_Tracker_SM.h +++ b/FTNoIR_Tracker_SM/FTNoIR_Tracker_SM.h @@ -1,18 +1,14 @@ #include "..\ftnoir_tracker_base\ftnoir_tracker_base.h" +#include "..\ftnoir_tracker_base\ftnoir_tracker_sm_types.h" #include "ui_FTNoIR_SMClientcontrols.h" -#include "mainwindow.h" -#include "sm_api_qt.h" #include #include +#include #include "Windows.h" #include "math.h" using namespace std; -//using namespace sm::faceapi::samplecode; -using namespace sm::faceapi; -using namespace sm::faceapi::qt; -using namespace sm::faceapi::samplecode; class FTNoIR_Tracker_SM : public ITracker { @@ -26,17 +22,28 @@ public: void StopTracker(); bool GiveHeadPoseData(THeadPoseData *data); // Returns true if confidence is good void loadSettings(); + bool SMCreateMapping(); bool setParameterValue(const int index, const float newvalue); private: /** face api variables **/ - APIScope *faceapi_scope; - QSharedPointer _engine; - VideoDisplayWidget *_display; - QVBoxLayout *l; - MainWindow *main_window; + //APIScope *faceapi_scope; + // QSharedPointer _engine; + //VideoDisplayWidget *_display; + //QVBoxLayout *l; + //MainWindow *main_window; //parameter list for the filter-function(s) + + // + // global variables + // + HANDLE hSMMemMap; + SMMemMap *pMemData; + HANDLE hSMMutex; +// smEngineHeadPoseData new_head_pose; + QProcess *faceAPI; + enum { kPortAddress=0, // Index in QList diff --git a/FTNoIR_Tracker_SM/FTNoIR_Tracker_SM.vcproj b/FTNoIR_Tracker_SM/FTNoIR_Tracker_SM.vcproj index b15c259b..9964af61 100644 --- a/FTNoIR_Tracker_SM/FTNoIR_Tracker_SM.vcproj +++ b/FTNoIR_Tracker_SM/FTNoIR_Tracker_SM.vcproj @@ -171,10 +171,6 @@ RelativePath=".\ftnoir_tracker_faceapi.cpp" > - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - diff --git a/FTNoIR_Tracker_SM/ftnoir_tracker_faceapi.cpp b/FTNoIR_Tracker_SM/ftnoir_tracker_faceapi.cpp index f2f18877..a7f0668e 100644 --- a/FTNoIR_Tracker_SM/ftnoir_tracker_faceapi.cpp +++ b/FTNoIR_Tracker_SM/ftnoir_tracker_faceapi.cpp @@ -1,10 +1,5 @@ #include "ftnoir_tracker_sm.h" -#include "mainwindow.h" - -using namespace sm::faceapi; -using namespace sm::faceapi::qt; -using namespace sm::faceapi::samplecode; -//using namespace sm::faceapi::qt; +#include FTNoIR_Tracker_SM::FTNoIR_Tracker_SM() { @@ -21,19 +16,18 @@ FTNoIR_Tracker_SM::FTNoIR_Tracker_SM() FTNoIR_Tracker_SM::~FTNoIR_Tracker_SM() { qDebug() << "stopTracker says: terminating"; - //if ( _display ) { - // _display->disconnect(); - // qDebug() << "stopTracker says: display disconnected"; - // delete _display; - // qDebug() << "stopTracker says: display deleted"; - // _display = 0; - // delete l; - // l = 0; - // qDebug() << "stopTracker says: l deleted"; - //} - _engine->stop(); - smAPIQuit(); + if ( pMemData != NULL ) { + pMemData->command = 100; // Issue 'stop' command + UnmapViewOfFile ( pMemData ); + } + + CloseHandle( hSMMutex ); + CloseHandle( hSMMemMap ); + hSMMemMap = 0; + + //_engine->stop(); + //smAPIQuit(); } void FTNoIR_Tracker_SM::Release() @@ -47,38 +41,52 @@ void FTNoIR_Tracker_SM::Initialize( QFrame *videoframe ) qDebug() << "FTNoIR_Tracker_SM::Initialize says: Starting "; loadSettings(); - try { - // Initialize the faceAPI Qt library - sm::faceapi::qt::initialize(); - smLoggingSetFileOutputEnable( false ); + if (SMCreateMapping()) { + qDebug() << "FTNoIR_Tracker_SM::Initialize Mapping created."; + } + else { + QMessageBox::warning(0,"FaceTrackNoIR Error","Memory mapping not created!",QMessageBox::Ok,QMessageBox::NoButton); + } - // Initialize the API - faceapi_scope = new APIScope(); + // + // Start FTNoIR_FaceAPI_EXE.exe. The exe contains all faceAPI-stuff and is non-Qt... + // + QString program = "FTNoIR_FaceAPI_EXE.exe"; + faceAPI = new QProcess(0); + faceAPI->start(program); - //if (APIScope::internalQtGuiIsDisabled()){ - // QMessageBox::warning(0,"faceAPI Error","Something Bad",QMessageBox::Ok,QMessageBox::NoButton); - //} + ////try { + //// // Initialize the faceAPI Qt library + //// sm::faceapi::qt::initialize(); + //// smLoggingSetFileOutputEnable( false ); - // Create head-tracking engine v2 using first detected webcam - CameraInfo::registerType(SM_API_CAMERA_TYPE_WDM); - _engine = QSharedPointer(new HeadTrackerV2()); + //// // Initialize the API + //// faceapi_scope = new APIScope(); - } - catch (sm::faceapi::Error &e) - { - /* ERROR with camera */ - QMessageBox::warning(0,"faceAPI Error",e.what(),QMessageBox::Ok,QMessageBox::NoButton); - } + //// //if (APIScope::internalQtGuiIsDisabled()){ + //// // QMessageBox::warning(0,"faceAPI Error","Something Bad",QMessageBox::Ok,QMessageBox::NoButton); + //// //} + + //// // Create head-tracking engine v2 using first detected webcam + //// CameraInfo::registerType(SM_API_CAMERA_TYPE_WDM); + //// _engine = QSharedPointer(new HeadTrackerV2()); + + ////} + ////catch (sm::faceapi::Error &e) + ////{ + //// /* ERROR with camera */ + //// QMessageBox::warning(0,"faceAPI Error",e.what(),QMessageBox::Ok,QMessageBox::NoButton); + ////} // Show the video widget qDebug() << "FTNoIR_Tracker_SM::Initialize says: videoframe = " << videoframe; - // QMainWindow derived class. See mainwindow.h - QSharedPointer camera; - main_window = new MainWindow(camera,_engine,0); - main_window->show(); + //// QMainWindow derived class. See mainwindow.h + // QSharedPointer camera; + // main_window = new MainWindow(camera,_engine,0); + // main_window->show(); //videoframe->show(); //_display = new VideoDisplayWidget( _engine, videoframe, 0 ); @@ -93,15 +101,15 @@ void FTNoIR_Tracker_SM::Initialize( QFrame *videoframe ) void FTNoIR_Tracker_SM::StartTracker( HWND parent_window ) { - // starts the faceapi engine - if (_engine->state() != SM_API_ENGINE_STATE_HT_TRACKING) { - _engine->start(); - } + //// starts the faceapi engine + //if (_engine->state() != SM_API_ENGINE_STATE_HT_TRACKING) { + // _engine->start(); + //} - // some parameteres [optional] - smHTSetHeadPosePredictionEnabled( _engine->handle(), false); - smHTSetLipTrackingEnabled( _engine->handle(), false); - smLoggingSetFileOutputEnable( false ); + //// some parameteres [optional] + //smHTSetHeadPosePredictionEnabled( _engine->handle(), false); + //smHTSetLipTrackingEnabled( _engine->handle(), false); + //smLoggingSetFileOutputEnable( false ); return; } @@ -110,26 +118,36 @@ void FTNoIR_Tracker_SM::StopTracker() qDebug() << "FTNoIR_Tracker_SM::StopTracker says: Starting "; // stops the faceapi engine - _engine->stop(); +//// _engine->stop(); return; } bool FTNoIR_Tracker_SM::GiveHeadPoseData(THeadPoseData *data) { - smEngineHeadPoseData head_pose; // headpose from faceAPI - smEngineHeadPoseData temp_head_pose; // headpose from faceAPI - smReturnCode smret = smHTCurrentHeadPose(_engine->handle(), &temp_head_pose); - memcpy(&head_pose, &temp_head_pose, sizeof(smEngineHeadPoseData)); + qDebug() << "FTNoIR_Tracker_SM::GiveHeadPoseData says: Starting "; - data->x = head_pose.head_pos.x * 100.0f; // From meters to centimeters - data->y = head_pose.head_pos.y * 100.0f; - data->z = head_pose.head_pos.z * 100.0f; - data->yaw = head_pose.head_rot.y_rads * 57.295781f; // From rads to degrees - data->pitch = head_pose.head_rot.x_rads * 57.295781f; - data->roll = head_pose.head_rot.z_rads * 57.295781f; + // + // Check if the pointer is OK and wait for the Mutex. + // + if ( (pMemData != NULL) && (WaitForSingleObject(hSMMutex, 100) == WAIT_OBJECT_0) ) { - return ( head_pose.confidence > 0 ); + qDebug() << "FTNoIR_Tracker_SM::GiveHeadPoseData says: Retrieving data."; + + // + // Copy the measurements to FaceTrackNoIR. + // + data->x = pMemData->data.new_pose.head_pos.x * 100.0f; // From meters to centimeters + data->y = pMemData->data.new_pose.head_pos.y * 100.0f; + data->z = pMemData->data.new_pose.head_pos.z * 100.0f; + data->yaw = pMemData->data.new_pose.head_rot.y_rads * 57.295781f; // From rads to degrees + data->pitch = pMemData->data.new_pose.head_rot.x_rads * 57.295781f; + data->roll = pMemData->data.new_pose.head_rot.z_rads * 57.295781f; + + ReleaseMutex(hSMMutex); + return ( pMemData->data.new_pose.confidence > 0 ); + } + return false; } bool FTNoIR_Tracker_SM::setParameterValue(const int index, const float newvalue) @@ -178,6 +196,62 @@ void FTNoIR_Tracker_SM::loadSettings() { iniFile.endGroup (); } +// +// Create a memory-mapping to the faceAPI data. +// It contains the tracking data, a command-code from FaceTrackNoIR +// +// +bool FTNoIR_Tracker_SM::SMCreateMapping() +{ + qDebug() << "FTNoIR_Tracker_SM::FTCreateMapping says: Starting Function"; + + // + // A FileMapping is used to create 'shared memory' between the faceAPI and FaceTrackNoIR. + // + // Try to create a FileMapping to the Shared Memory. + // If one already exists: close it. + // + hSMMemMap = CreateFileMappingA( INVALID_HANDLE_VALUE , 00 , PAGE_READWRITE , 0 , + sizeof( TFaceData ) + sizeof( HANDLE ) + 100, + (LPCSTR) SM_MM_DATA ); + + if ( hSMMemMap != 0 ) { + qDebug() << "FTNoIR_Tracker_SM::FTCreateMapping says: FileMapping Created!"; + } + + if ( ( hSMMemMap != 0 ) && ( (long) GetLastError == ERROR_ALREADY_EXISTS ) ) { + CloseHandle( hSMMemMap ); + hSMMemMap = 0; + } + + // + // Create a new FileMapping, Read/Write access + // + hSMMemMap = OpenFileMappingA( FILE_MAP_ALL_ACCESS , false , (LPCSTR) SM_MM_DATA ); + if ( ( hSMMemMap != 0 ) ) { + qDebug() << "FTNoIR_Tracker_SM::FTCreateMapping says: FileMapping Created again..." << hSMMemMap; + pMemData = (SMMemMap *) MapViewOfFile(hSMMemMap, FILE_MAP_ALL_ACCESS, 0, 0, sizeof(TFaceData)); + if (pMemData != NULL) { + qDebug() << "FTNoIR_Tracker_SM::FTCreateMapping says: MapViewOfFile OK."; +// pMemData->handle = handle; // The game uses the handle, to send a message that the Program-Name was set! + } + hSMMutex = CreateMutexA(NULL, false, SM_MUTEX); + } + else { + qDebug() << "FTNoIR_Tracker_SM::FTCreateMapping says: Error creating Shared Memory for faceAPI!"; + return false; + } + + //if (pMemData != NULL) { + // pMemData->data.DataID = 1; + // pMemData->data.CamWidth = 100; + // pMemData->data.CamHeight = 250; + //} + + return true; +} + + //////////////////////////////////////////////////////////////////////////////// // Factory function that creates instances if the Tracker object. diff --git a/FaceTrackNoIR.suo b/FaceTrackNoIR.suo index a0fb59e4..8240a44c 100644 Binary files a/FaceTrackNoIR.suo and b/FaceTrackNoIR.suo differ diff --git a/faceAPI/main.cpp b/faceAPI/main.cpp index 0aeb9bca..f1c5f768 100644 --- a/faceAPI/main.cpp +++ b/faceAPI/main.cpp @@ -10,6 +10,7 @@ //FaceAPI headers #include "sm_api.h" +#include "ftnoir_tracker_sm_types.h" #include "utils.h" //local headers @@ -19,27 +20,6 @@ using namespace std; using namespace sm::faceapi::samplecode; -// -// Definitions for the Shared Memory to send the data to FaceTrackNoIR -// -static const char* SM_MM_DATA = "SM_SharedMem"; -static const char* SM_FACEAPI = "SM_FaceAPI"; -static const char* SM_MUTEX = "SM_Mutex"; - -struct TFaceData { - int DataID; - smEngineHeadPoseData new_pose; -}; -typedef TFaceData * PFaceData; - -struct SMMemMap { - int command; // Command from FaceTrackNoIR - int status; // Status from faceAPI - TFaceData data; - HANDLE handle; -}; -typedef SMMemMap * PSMMemMap; - // // global variables // @@ -47,6 +27,7 @@ HANDLE hSMMemMap = NULL; SMMemMap *pMemData; HANDLE hSMMutex; smEngineHeadPoseData new_head_pose; +bool stopCommand = false; //enums enum GROUP_ID @@ -328,7 +309,7 @@ void run() THROW_ON_ERROR(smEngineStart(engine_handle)); // Loop on the keyboard - while (processKeyPress(engine_handle, video_display_handle)) + while (processKeyPress(engine_handle, video_display_handle) && !stopCommand) { // Read and print the current head-pose (if not using the callback mechanism) #if (USE_HEADPOSE_CALLBACK==0) @@ -360,6 +341,21 @@ void run() THROW_ON_ERROR(smEngineDestroy(&engine_handle)); // Destroy video display THROW_ON_ERROR(smVideoDisplayDestroy(&video_display_handle)); + + if ( pMemData != NULL ) { + UnmapViewOfFile ( pMemData ); + } + + if (hSMMutex != 0) { + CloseHandle( hSMMutex ); + } + hSMMutex = 0; + + if (hSMMemMap != 0) { + CloseHandle( hSMMemMap ); + } + hSMMemMap = 0; + } // run() // Application entry point @@ -386,17 +382,29 @@ int _tmain(int /*argc*/, _TCHAR** /*argv*/) // void updateHeadPose(smEngineHeadPoseData* temp_head_pose) { + char msg[100]; + + OutputDebugString(_T("updateHeadPose() says: Starting Function\n")); + // // Check if the pointer is OK and wait for the Mutex. // if ( (pMemData != NULL) && (WaitForSingleObject(hSMMutex, 100) == WAIT_OBJECT_0) ) { + + OutputDebugString(_T("updateHeadPose() says: Writing Data\n")); // // Copy the Raw measurements directly to the client. // if (temp_head_pose->confidence > 0.0f) { - memcpy(&pMemData->data,temp_head_pose,sizeof(smEngineHeadPoseData)); + memcpy(&pMemData->data.new_pose,temp_head_pose,sizeof(smEngineHeadPoseData)); + sprintf(msg, "HeadPose Yaw: %.2f\n", pMemData->data.new_pose.head_rot.x_rads); + OutputDebugStringA(msg); + } + + if (pMemData->command == 100) { + stopCommand = TRUE; } ReleaseMutex(hSMMutex); } -- cgit v1.2.3