diff options
Diffstat (limited to 'ftnoir_tracker_fd/ftnoir_tracker_facedetect.cpp')
-rw-r--r-- | ftnoir_tracker_fd/ftnoir_tracker_facedetect.cpp | 214 |
1 files changed, 214 insertions, 0 deletions
diff --git a/ftnoir_tracker_fd/ftnoir_tracker_facedetect.cpp b/ftnoir_tracker_fd/ftnoir_tracker_facedetect.cpp new file mode 100644 index 00000000..620fb9fd --- /dev/null +++ b/ftnoir_tracker_fd/ftnoir_tracker_facedetect.cpp @@ -0,0 +1,214 @@ +/* Copyright (c) 2012 Stanislaw Halik
+ *
+ * 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_fd.h"
+#include <Qt>
+#include <QPainter>
+#include <QPaintEngine>
+
+static void load_settings(struct face_detect_settings* out) {
+ qDebug("[!] load_settings()");
+ QSettings settings("Abbequerque Inc.", "FaceTrackNoIR"); // Registry settings (in HK_USER)
+
+ QString currentFile = settings.value ( "SettingsFile", QCoreApplication::applicationDirPath() + "/Settings/default.ini" ).toString();
+ QSettings iniFile( currentFile, QSettings::IniFormat ); // Application settings (in INI-file)
+
+ iniFile.beginGroup ( "FaceDetectTracker" );
+ out->redetect_ms = iniFile.value("RedetectMs", 500).toInt();
+ out->camera_id = iniFile.value("CameraId", 0).toInt();
+ out->quit = 0;
+ out->newOutput = 0;
+ out->magic = FD_MAGIC;
+ out->widgetp = iniFile.value("VideoWidget", true).toBool();
+ iniFile.endGroup ();
+}
+
+static void save_settings(const struct face_detect_settings* in) {
+
+ QSettings settings("Abbequerque Inc.", "FaceTrackNoIR"); // Registry settings (in HK_USER)
+
+ QString currentFile = settings.value ( "SettingsFile", QCoreApplication::applicationDirPath() + "/Settings/default.ini" ).toString();
+ QSettings iniFile( currentFile, QSettings::IniFormat ); // Application settings (in INI-file)
+
+ iniFile.beginGroup ( "FaceDetectTracker" );
+ iniFile.setValue("RedetectMs", in->redetect_ms);
+ iniFile.setValue("CameraId", in->camera_id);
+ iniFile.setValue("VideoWidget", in->widgetp);
+ iniFile.endGroup ();
+}
+
+VideoWidget::VideoWidget(HANDLE hMutex, unsigned char* data, struct face_detect_shm* shm) {
+ this->hMutex = hMutex;
+ this->data = data;
+ this->shm = shm;
+}
+
+void VideoWidget::paintEvent(QPaintEvent*) {
+ WaitForSingleObject(hMutex, INFINITE);
+ if (!this->shm->settings.widgetp) {
+ ReleaseMutex(hMutex);
+ return;
+ }
+ QPainter painter(this);
+ QImage image(data, FD_VIDEO_WIDTH, FD_VIDEO_HEIGHT, QImage::Format_RGB888);
+ QRectF rect(0, 0, FD_VIDEO_WIDTH, FD_VIDEO_HEIGHT);
+ painter.paintEngine()->drawImage(rect, image.rgbSwapped(), rect);
+ ReleaseMutex(hMutex);
+}
+
+FTNoIR_Tracker::FTNoIR_Tracker()
+{
+ qDebug("making tracker FaceDetect");
+
+ hMutex = CreateMutex(NULL, false, fd_mutex_name);
+ hMapFile = CreateFileMapping(INVALID_HANDLE_VALUE, NULL, PAGE_READWRITE, 0, sizeof(struct face_detect_shm), fd_shm_name);
+ shm = (struct face_detect_shm*) MapViewOfFile(hMapFile, FILE_MAP_READ | FILE_MAP_WRITE, 0, 0, sizeof(struct face_detect_shm));
+ memset(shm, 0, sizeof(struct face_detect_shm));
+ activep = 0;
+ procInfo.hProcess = INVALID_HANDLE_VALUE;
+ ctrl = NULL;
+ qframe = NULL;
+}
+
+void FTNoIR_Tracker::TerminateTracker() {
+ if (procInfo.hProcess != INVALID_HANDLE_VALUE) {
+ shm->settings.quit = 1;
+ //TerminateProcess(procInfo.hProcess, 42);
+ CloseHandle(procInfo.hProcess);
+ CloseHandle(procInfo.hThread);
+ procInfo.hProcess = INVALID_HANDLE_VALUE;
+ }
+}
+
+FTNoIR_Tracker::~FTNoIR_Tracker()
+{
+ WaitForSingleObject(hMutex, INFINITE);
+ TerminateTracker();
+ UnmapViewOfFile(shm);
+ //CloseHandle(hMapFile);
+ ReleaseMutex(hMutex);
+ //CloseHandle(hMutex);
+}
+
+void FTNoIR_Tracker::Initialize( QFrame *videoframe )
+{
+ qDebug("FTNoIR_Tracker::Initialize()");
+ WaitForSingleObject(hMutex, INFINITE);
+ videoframe->setAttribute(Qt::WA_NativeWindow);
+ videoframe->show();
+ ctrl = new VideoWidget(hMutex, shm->pixels, shm);
+ QHBoxLayout* layout = new QHBoxLayout();
+ layout->setContentsMargins(0, 0, 0, 0);
+ layout->addWidget(ctrl);
+ videoframe->setLayout(layout);
+ ctrl->resize(FD_VIDEO_WIDTH, FD_VIDEO_HEIGHT);
+ qframe = videoframe;
+ loadSettings();
+ ReleaseMutex(hMutex);
+}
+
+void FTNoIR_Tracker::refreshVideo() {
+ QWidget* w;
+ WaitForSingleObject(hMutex, INFINITE);
+ w = ctrl;
+ ReleaseMutex(hMutex);
+ if (w != NULL)
+ w->update();
+}
+
+void FTNoIR_Tracker::StartTracker( HWND parent_window )
+{
+ WaitForSingleObject(hMutex, INFINITE);
+ qDebug("* tracker starting");
+ activep = true;
+ ReleaseMutex(hMutex);
+}
+
+void FTNoIR_Tracker::StopTracker( bool exit )
+{
+ WaitForSingleObject(hMutex, INFINITE);
+ qDebug("* tracker stopping");
+ activep = false;
+ if (exit) {
+ TerminateTracker();
+ if (qframe && qframe->layout()) {
+ delete qframe->layout();
+ qframe = NULL;
+ }
+ if (ctrl) {
+ delete ctrl;
+ ctrl = NULL;
+ }
+ }
+ ReleaseMutex(hMutex);
+}
+
+bool FTNoIR_Tracker::notifyZeroed() {
+ qDebug("notifying of zero");
+ WaitForSingleObject(hMutex, INFINITE);
+ shm->zerop = 1;
+ ReleaseMutex(hMutex);
+ return true;
+}
+
+bool FTNoIR_Tracker::GiveHeadPoseData(THeadPoseData *data)
+{
+ WaitForSingleObject(hMutex, INFINITE);
+ if (procInfo.hProcess == INVALID_HANDLE_VALUE) {
+ STARTUPINFO si;
+ SECURITY_ATTRIBUTES sa;
+ sa.bInheritHandle = 1;
+ sa.lpSecurityDescriptor = NULL;
+ sa.nLength = sizeof(SECURITY_ATTRIBUTES);
+ memset(&si, 0, sizeof(STARTUPINFO));
+ si.dwFlags = STARTF_USESHOWWINDOW | STARTF_USESTDHANDLES;
+ si.cb = sizeof(STARTUPINFO);
+ si.hStdOutput = NULL;
+ si.hStdError = NULL;
+ si.hStdInput = NULL;
+ if (!CreateProcess(prog_cmdline, NULL, NULL, NULL, true, 0, NULL, NULL, &si, &procInfo)) {
+ qDebug("Badness! %d", GetLastError());
+ }
+ }
+
+ shm->received = 1;
+
+ if (activep) {
+ shm->settings.newOutput = 0;
+ data->x = shm->data[3];
+ data->y = shm->data[4];
+ data->z = shm->data[5];
+ data->yaw = shm->data[0];
+ data->pitch = shm->data[1];
+ data->roll = shm->data[2];
+ ReleaseMutex(hMutex);
+ return true;
+ }
+ ReleaseMutex(hMutex);
+ return false;
+}
+
+//
+// Load the current Settings from the currently 'active' INI-file.
+//
+void FTNoIR_Tracker::loadSettings() {
+ load_settings(&shm->settings);
+}
+
+////////////////////////////////////////////////////////////////////////////////
+// Factory function that creates instances if the Tracker object.
+
+// Export both decorated and undecorated names.
+// GetTracker - Undecorated name, which can be easily used with GetProcAddress
+// Win32 API function.
+// _GetTracker@0 - Common name decoration for __stdcall functions in C language.
+#pragma comment(linker, "/export:GetTracker=_GetTracker@0")
+
+FTNOIR_TRACKER_BASE_EXPORT ITrackerPtr __stdcall GetTracker()
+{
+ return new FTNoIR_Tracker;
+}
|