From 9184ea73941814b95c2768d8bcca8bdb77655891 Mon Sep 17 00:00:00 2001 From: Wim Vriend Date: Sat, 17 Mar 2012 16:15:51 +0000 Subject: Changed Tracker code, so the DLL's are true plug-ins. FaceTrackNoIR will scan the bin folder for FTNoIR_Tracker*.dll and put the names in the combobox. All Trackers have 3 new member-functions (like the filters). git-svn-id: svn+ssh://svn.code.sf.net/p/facetracknoir/code@104 19e81ba0-9b1a-49c3-bd6c-561e1906d5fb --- FTNoIR_Tracker_FD/FTNoIR_FD_Controls.ui | 152 ++++++++ FTNoIR_Tracker_FD/FTNoIR_Tracker_FD.h | 108 ++++++ FTNoIR_Tracker_FD/FTNoIR_Tracker_FD.vcproj | 382 +++++++++++++++++++++ FTNoIR_Tracker_FD/Tracker.qrc | 5 + FTNoIR_Tracker_FD/face-detect.h | 39 +++ FTNoIR_Tracker_FD/ftnoir_tracker_facedetect.cpp | 251 ++++++++++++++ .../ftnoir_tracker_facedetect_dialog.cpp | 208 +++++++++++ FTNoIR_Tracker_FD/images/FaceDetect.ico | Bin 0 -> 5430 bytes 8 files changed, 1145 insertions(+) create mode 100644 FTNoIR_Tracker_FD/FTNoIR_FD_Controls.ui create mode 100644 FTNoIR_Tracker_FD/FTNoIR_Tracker_FD.h create mode 100644 FTNoIR_Tracker_FD/FTNoIR_Tracker_FD.vcproj create mode 100644 FTNoIR_Tracker_FD/Tracker.qrc create mode 100644 FTNoIR_Tracker_FD/face-detect.h create mode 100644 FTNoIR_Tracker_FD/ftnoir_tracker_facedetect.cpp create mode 100644 FTNoIR_Tracker_FD/ftnoir_tracker_facedetect_dialog.cpp create mode 100644 FTNoIR_Tracker_FD/images/FaceDetect.ico (limited to 'FTNoIR_Tracker_FD') diff --git a/FTNoIR_Tracker_FD/FTNoIR_FD_Controls.ui b/FTNoIR_Tracker_FD/FTNoIR_FD_Controls.ui new file mode 100644 index 00000000..0bb8028f --- /dev/null +++ b/FTNoIR_Tracker_FD/FTNoIR_FD_Controls.ui @@ -0,0 +1,152 @@ + + + UICFDClientControls + + + Qt::ApplicationModal + + + + 0 + 0 + 283 + 151 + + + + + 0 + 0 + + + + FaceDetect tracker settings + + + + images/FaceTrackNoIR.icoimages/FaceTrackNoIR.ico + + + Qt::LeftToRight + + + false + + + + QLayout::SetFixedSize + + + + + + + + + QFormLayout::AllNonFixedFieldsGrow + + + + + Changes take effect after tracker restart. + + + + + + + Camera (indices from 0) + + + + + + + 100 + + + + + + + Haar detection timeout (ms) + + + + + + + 2000 + + + 50 + + + 200 + + + + + + + Video Widget + + + + + + + Qt::RightToLeft + + + + + + + + + + + + + + Qt::Horizontal + + + + 40 + 20 + + + + + + + + OK + + + + + + + Cancel + + + + + + + + + + + + + + + startEngineClicked() + stopEngineClicked() + cameraSettingsClicked() + + diff --git a/FTNoIR_Tracker_FD/FTNoIR_Tracker_FD.h b/FTNoIR_Tracker_FD/FTNoIR_Tracker_FD.h new file mode 100644 index 00000000..ddb9afde --- /dev/null +++ b/FTNoIR_Tracker_FD/FTNoIR_Tracker_FD.h @@ -0,0 +1,108 @@ +#include "..\ftnoir_tracker_base\ftnoir_tracker_base.h" +#include "face-detect.h" +#include "ui_FTNoIR_FD_controls.h" + +#include +#include +#include + +#include +#include +#include +#include "math.h" +#include + +using namespace std; + +static LPTSTR prog_cmdline = (LPTSTR) TEXT("face-detect.exe"); +static LPTSTR fd_shm_name = (LPTSTR) TEXT("face-detect-shm"); +static LPTSTR fd_mutex_name = (LPTSTR) TEXT("face-detect-mutex"); + +class VideoWidget : public QWidget +{ + Q_OBJECT +public: + VideoWidget(HANDLE hMutex, unsigned char* data, struct face_detect_shm* shm); +protected: + void paintEvent(QPaintEvent*); +private: + HANDLE hMutex; + unsigned char* data; + struct face_detect_shm* shm; +}; + +class FTNoIR_Tracker : public ITracker +{ +public: + FTNoIR_Tracker(); + ~FTNoIR_Tracker(); + + void Release(); + void Initialize( QFrame *videoframe ); + void StartTracker( HWND parent_window ); + void StopTracker( bool exit ); + bool GiveHeadPoseData(THeadPoseData *data); // Returns true if confidence is good + void loadSettings(); +// bool setParameterValue(const int index, const float newvalue); + bool notifyZeroed(); + void refreshVideo(); + + void getFullName(QString *strToBeFilled); + void getShortName(QString *strToBeFilled); + void getDescription(QString *strToBeFilled); + +private: + bool activep; + //QList> parameterRange; + //QList parameterValueAsFloat; + void TerminateTracker(); + HANDLE hMutex, hMapFile; + struct face_detect_shm* shm; + PROCESS_INFORMATION procInfo; + VideoWidget* ctrl; + QFrame* qframe; + + QString trackerFullName; // Trackers' name and description + QString trackerShortName; + QString trackerDescription; + +}; + +class TrackerControls: public QWidget, Ui::UICFDClientControls, public ITrackerDialog +{ + Q_OBJECT +public: + + explicit TrackerControls(); + virtual ~TrackerControls(); + void Release(); // Member functions which are accessible from outside the DLL + void Initialize(QWidget *parent); + void NotifyZeroing(); + + void getFullName(QString *strToBeFilled); + void getShortName(QString *strToBeFilled); + void getDescription(QString *strToBeFilled); + void getIcon(QIcon *icon); + +private: + Ui::UICFDClientControls ui; + void loadSettings(); + void save(); + + bool settingsDirty; + HANDLE hMapFile, hMutex; + struct face_detect_shm* shm; + + QString trackerFullName; // Trackers' name and description + QString trackerShortName; + QString trackerDescription; + +private slots: + void doOK(); + void doCancel(); + void settingChanged() { settingsDirty = true; }; + void doSetRedetectMs(int val); + void doSetCameraId(int val); + void doSetVideoWidget(bool val); +signals: +}; \ No newline at end of file diff --git a/FTNoIR_Tracker_FD/FTNoIR_Tracker_FD.vcproj b/FTNoIR_Tracker_FD/FTNoIR_Tracker_FD.vcproj new file mode 100644 index 00000000..293e1ebf --- /dev/null +++ b/FTNoIR_Tracker_FD/FTNoIR_Tracker_FD.vcproj @@ -0,0 +1,382 @@ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + diff --git a/FTNoIR_Tracker_FD/Tracker.qrc b/FTNoIR_Tracker_FD/Tracker.qrc new file mode 100644 index 00000000..d988ba71 --- /dev/null +++ b/FTNoIR_Tracker_FD/Tracker.qrc @@ -0,0 +1,5 @@ + + + images/FaceDetect.ico + + diff --git a/FTNoIR_Tracker_FD/face-detect.h b/FTNoIR_Tracker_FD/face-detect.h new file mode 100644 index 00000000..fc359c53 --- /dev/null +++ b/FTNoIR_Tracker_FD/face-detect.h @@ -0,0 +1,39 @@ +#if defined(_WIN32) || defined(WIN32) +# ifdef __cplusplus +# define FDAPI_EXTERN extern "C" +# else +# define FDAPI_EXTERN +# endif +# define FDAPI(ret) FDAPI_EXTERN __declspec(dllexport) ret __cdecl +#else +# define FDAPI(ret) ret +#endif + +struct face_detect_settings { + unsigned char magic, quit, newOutput, widgetp; + int redetect_ms, camera_id; +}; + +struct face_detect; +FDAPI(struct face_detect*) face_detect_init(const char* eyes_model, + const char* nose_model, + const char* mouth_model, + const char* face_model, + int capture_no, + struct face_detect_settings* settings); +FDAPI(void) face_detect_free(struct face_detect *ctx); +FDAPI(int) face_detect_cycle(struct face_detect *ctx, float *data); +FDAPI(void) face_detect_zero(struct face_detect *ctx); + +FDAPI(unsigned char*) face_detect_video(struct face_detect* ctx); + +#define FD_VIDEO_WIDTH 252 +#define FD_VIDEO_HEIGHT 189 +#define FD_MAGIC 0x42 + +struct face_detect_shm { + unsigned char zerop, received; + float data[6]; + unsigned char pixels[FD_VIDEO_WIDTH * FD_VIDEO_HEIGHT * 3]; + struct face_detect_settings settings; +}; diff --git a/FTNoIR_Tracker_FD/ftnoir_tracker_facedetect.cpp b/FTNoIR_Tracker_FD/ftnoir_tracker_facedetect.cpp new file mode 100644 index 00000000..7f1c1529 --- /dev/null +++ b/FTNoIR_Tracker_FD/ftnoir_tracker_facedetect.cpp @@ -0,0 +1,251 @@ +/* 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 +#include +#include + +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"); + ////allocate memory for the parameters + //parameterValueAsFloat.clear(); + //parameterRange.clear(); + + //// Add the parameters to the list + //parameterRange.append(std::pair(1000.0f,9999.0f)); + //parameterValueAsFloat.append(0.0f); + ////setParameterValue(kPortAddress,5551.0f); + + 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; + + //populate the description strings + trackerFullName = "faceDetect V1.0.0"; + trackerShortName = "faceDetect"; + trackerDescription = "Stans' faceDetect V1.0.0"; + +} + +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::Release() +{ + qDebug("FTNoIR_Tracker::Release says: Starting "); + delete this; +} + +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; +} + +void FTNoIR_Tracker::getFullName(QString *strToBeFilled) +{ + *strToBeFilled = trackerFullName; +}; + + +void FTNoIR_Tracker::getShortName(QString *strToBeFilled) +{ + *strToBeFilled = trackerShortName; +}; + + +void FTNoIR_Tracker::getDescription(QString *strToBeFilled) +{ + *strToBeFilled = trackerDescription; +}; + +// +// 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 TRACKERHANDLE __stdcall GetTracker() +{ + return new FTNoIR_Tracker; +} diff --git a/FTNoIR_Tracker_FD/ftnoir_tracker_facedetect_dialog.cpp b/FTNoIR_Tracker_FD/ftnoir_tracker_facedetect_dialog.cpp new file mode 100644 index 00000000..a39d8bf2 --- /dev/null +++ b/FTNoIR_Tracker_FD/ftnoir_tracker_facedetect_dialog.cpp @@ -0,0 +1,208 @@ +/* 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 +#include +#include + +//******************************************************************************************************* +// faceDetect Settings-dialog. +//******************************************************************************************************* + +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 (); +} + + +// +// Constructor for server-settings-dialog +// +TrackerControls::TrackerControls() : +QWidget() +{ + qDebug("[!] TrackerControls::TrackerControls()"); + 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)); + hMutex = CreateMutex(NULL, false, fd_mutex_name); + ui.setupUi( this ); + + load_settings(&shm->settings); + + ui.redetect_ms->setValue(shm->settings.redetect_ms); + ui.cameraId->setValue(shm->settings.camera_id); + ui.videoWidget->setChecked(shm->settings.widgetp); + + settingsDirty = false; + + // what a load of boilerplate... + QObject::connect(ui.okButton, SIGNAL(clicked()), this, SLOT(doOK())); + QObject::connect(ui.cancelButton, SIGNAL(clicked()), this, SLOT(doCancel())); + QObject::connect(ui.redetect_ms, SIGNAL(valueChanged(int)), this, SLOT(doSetRedetectMs(int))); + QObject::connect(ui.cameraId, SIGNAL(valueChanged(int)), this, SLOT(doSetCameraId(int))); + QObject::connect(ui.videoWidget, SIGNAL(toggled(bool)), this, SLOT(doSetVideoWidget(bool))); + + //populate the description strings + trackerFullName = "faceDetect V1.0.0"; + trackerShortName = "faceDetect"; + trackerDescription = "Stans' faceDetect V1.0.0"; + +} + +void TrackerControls::save() { + save_settings(&shm->settings); + settingsDirty = false; +} + +void TrackerControls::doSetCameraId(int val) { + settingsDirty = true; + WaitForSingleObject(hMutex, INFINITE); + shm->settings.camera_id = val; + ReleaseMutex(hMutex); +} + +void TrackerControls::doSetVideoWidget(bool val) { + settingsDirty = true; + WaitForSingleObject(hMutex, INFINITE); + shm->settings.widgetp = val; + ReleaseMutex(hMutex); +} + +void TrackerControls::doSetRedetectMs(int val) { + settingsDirty = true; + WaitForSingleObject(hMutex, INFINITE); + shm->settings.redetect_ms = val; + ReleaseMutex(hMutex); +} + +// +// Destructor for server-dialog +// +TrackerControls::~TrackerControls() { + UnmapViewOfFile(shm); + //CloseHandle(hMutex); + //CloseHandle(hMapFile); +} + +void TrackerControls::Release() +{ + delete this; +} + +// +// Initialize tracker-client-dialog +// +void TrackerControls::Initialize(QWidget *parent) { + + QPoint offsetpos(200, 200); + if (parent) { + this->move(parent->pos() + offsetpos); + } + show(); +} + +// +// OK clicked on server-dialog +// +void TrackerControls::doOK() { + save(); + this->close(); +} + +// +// Cancel clicked on server-dialog +// +void TrackerControls::doCancel() { + // + // Ask if changed Settings should be saved + // + 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(); + } +} + +void TrackerControls::getFullName(QString *strToBeFilled) +{ + *strToBeFilled = trackerFullName; +}; + + +void TrackerControls::getShortName(QString *strToBeFilled) +{ + *strToBeFilled = trackerShortName; +}; + + +void TrackerControls::getDescription(QString *strToBeFilled) +{ + *strToBeFilled = trackerDescription; +}; + +void TrackerControls::getIcon(QIcon *icon) +{ + *icon = QIcon(":/images/SeeingMachines.ico"); +}; + +//////////////////////////////////////////////////////////////////////////////// +// 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 TRACKERDIALOGHANDLE __stdcall GetTrackerDialog( ) +{ + return new TrackerControls; +} diff --git a/FTNoIR_Tracker_FD/images/FaceDetect.ico b/FTNoIR_Tracker_FD/images/FaceDetect.ico new file mode 100644 index 00000000..8e862cee Binary files /dev/null and b/FTNoIR_Tracker_FD/images/FaceDetect.ico differ -- cgit v1.2.3