From 7c0bcbc7d4f8da28450e0b57a9e52fd50a212d4f Mon Sep 17 00:00:00 2001 From: Stanislaw Halik Date: Tue, 23 Sep 2014 20:32:39 +0200 Subject: no need for pragma here Revert part of ae8f78bf5e9096b44e700b1b2e1e4edc03a0b93d --- x-plane-plugin/plugin.c | 2 -- 1 file changed, 2 deletions(-) diff --git a/x-plane-plugin/plugin.c b/x-plane-plugin/plugin.c index b91151c1..62c9d6f0 100644 --- a/x-plane-plugin/plugin.c +++ b/x-plane-plugin/plugin.c @@ -52,8 +52,6 @@ static void reinit_offset() { # define OT_UNUSED(varname) varname #endif -#pragma GCC diagnostic ignored "-Wunused-result" - PortableLockedShm* PortableLockedShm_init(const char *shmName, const char *OT_UNUSED(mutexName), int mapSize) { PortableLockedShm* self = malloc(sizeof(PortableLockedShm)); -- cgit v1.2.3 From 9b3c04d1187ceeb83e7e1eead0714fd4578d07d7 Mon Sep 17 00:00:00 2001 From: Stanislaw Halik Date: Tue, 23 Sep 2014 20:56:57 +0200 Subject: initialize first union member (clang warning) --- ftnoir_tracker_freepie-udp/ftnoir_tracker_freepie-udp.cpp | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/ftnoir_tracker_freepie-udp/ftnoir_tracker_freepie-udp.cpp b/ftnoir_tracker_freepie-udp/ftnoir_tracker_freepie-udp.cpp index 39b1f4a2..ea44133c 100644 --- a/ftnoir_tracker_freepie-udp/ftnoir_tracker_freepie-udp.cpp +++ b/ftnoir_tracker_freepie-udp/ftnoir_tracker_freepie-udp.cpp @@ -41,7 +41,7 @@ void TrackerImpl::run() { while (sock.hasPendingDatagrams()) { - data = decltype(data){0,0, 0,0,0}; + data = decltype(data){0,0, {0,0,0, 0,0,0}}; int sz = sock.readDatagram(reinterpret_cast(&data), sizeof(data)); int flags = data.flags & F::Mask; -- cgit v1.2.3 From fadd2f3475aed347d2a06a08cc9c2e7fe53fbba9 Mon Sep 17 00:00:00 2001 From: Stanislaw Halik Date: Mon, 22 Sep 2014 15:25:19 +0200 Subject: fix Wine bitrot rather than only saying so name mangling has issues so partial revert --- .../opentrack-wrapper-wine-main.cxx | 75 ++++++++++++++-------- .../opentrack-wrapper-wine-posix.cxx | 12 ++-- .../opentrack-wrapper-wine-windows.cxx | 5 -- 3 files changed, 54 insertions(+), 38 deletions(-) diff --git a/ftnoir_protocol_wine/opentrack-wrapper-wine-main.cxx b/ftnoir_protocol_wine/opentrack-wrapper-wine-main.cxx index fe5a95f9..40f36f8d 100644 --- a/ftnoir_protocol_wine/opentrack-wrapper-wine-main.cxx +++ b/ftnoir_protocol_wine/opentrack-wrapper-wine-main.cxx @@ -10,33 +10,57 @@ #include "compat/compat.h" void create_registry_key(void); -ptr make_shm_posix(); -ptr make_shm_win32(); + +class ShmPosix { +public: + ShmPosix(const char *shmName, const char *mutexName, int mapSize); + ~ShmPosix(); + void lock(); + void unlock(); + bool success(); + inline void* ptr() { return mem; } +private: + void* mem; + int fd, size; +}; + +class ShmWine { +public: + ShmWine(const char *shmName, const char *mutexName, int mapSize); + ~ShmWine(); + void lock(); + void unlock(); + bool success(); + inline void* ptr() { return mem; } +private: + void* mem; + void *hMutex, *hMapFile; +}; +#include int main(void) { - ptr lck_posix = make_shm_posix(); - ptr lck_wine = make_shm_win32(); - if(!lck_posix->success()) { - printf("Can't open posix map: %d\n", errno); - return 1; - } - if(!lck_wine->success()) { - printf("Can't open Wine map\n"); - return 1; - } - WineSHM* shm_posix = (WineSHM*) lck_posix->ptr(); - FTHeap* shm_wine = (FTHeap*) lck_wine->ptr(); + ShmPosix lck_posix(WINE_SHM_NAME, WINE_MTX_NAME, sizeof(WineSHM)); + ShmWine lck_wine("FT_SharedMem", "FT_Mutext", sizeof(FTHeap)); + if(!lck_posix.success()) { + printf("Can't open posix map: %d\n", errno); + return 1; + } + if(!lck_wine.success()) { + printf("Can't open Wine map\n"); + return 1; + } + WineSHM* shm_posix = (WineSHM*) lck_posix.ptr(); + FTHeap* shm_wine = (FTHeap*) lck_wine.ptr(); FTData* data = &shm_wine->data; create_registry_key(); - while (1) { - (void) Sleep(4); - lck_posix->lock(); - if (shm_posix->stop) { - lck_posix->unlock(); - break; - } - lck_wine->lock(); + while (1) { + lck_posix.lock(); + if (shm_posix->stop) { + lck_posix.unlock(); + break; + } + lck_wine.lock(); data->Yaw = shm_posix->data[Yaw]; data->Pitch = shm_posix->data[Pitch]; data->Roll = shm_posix->data[Roll]; @@ -50,7 +74,8 @@ int main(void) shm_posix->gameid = shm_wine->GameID; for (int i = 0; i < 8; i++) shm_wine->table[i] = shm_posix->table[i]; - lck_wine->unlock(); - lck_posix->unlock(); - } + lck_wine.unlock(); + lck_posix.unlock(); + (void) Sleep(4); + } } diff --git a/ftnoir_protocol_wine/opentrack-wrapper-wine-posix.cxx b/ftnoir_protocol_wine/opentrack-wrapper-wine-posix.cxx index ea01ff03..010c4440 100644 --- a/ftnoir_protocol_wine/opentrack-wrapper-wine-posix.cxx +++ b/ftnoir_protocol_wine/opentrack-wrapper-wine-posix.cxx @@ -1,12 +1,8 @@ #define OPENTRACK_COMPAT_BUNDLED +#ifdef _WIN32 +# undef _WIN32 +#endif + #define PortableLockedShm ShmPosix -#undef _WIN32 -#include "ftnoir_protocol_ft/fttypes.h" -#include "wine-shm.h" #include "compat/compat.h" #include "compat/compat.cpp" - -ptr make_shm_posix() -{ - return std::make_shared(FREETRACK_HEAP, FREETRACK_MUTEX, sizeof(FTHeap)); -} diff --git a/ftnoir_protocol_wine/opentrack-wrapper-wine-windows.cxx b/ftnoir_protocol_wine/opentrack-wrapper-wine-windows.cxx index 715dcc69..b7dc531c 100644 --- a/ftnoir_protocol_wine/opentrack-wrapper-wine-windows.cxx +++ b/ftnoir_protocol_wine/opentrack-wrapper-wine-windows.cxx @@ -8,11 +8,6 @@ #include "compat/compat.cpp" #include "wine-shm.h" -ptr make_shm_win32() -{ - return std::make_shared(WINE_SHM_NAME, WINE_MTX_NAME, sizeof(WineSHM)); -} - void create_registry_key(void) { char dir[8192]; -- cgit v1.2.3 From 0d80cd4a9c77b2ecbb515fb9d20c78f400c40851 Mon Sep 17 00:00:00 2001 From: Stanislaw Halik Date: Tue, 23 Sep 2014 23:13:17 +0200 Subject: nix needless include --- ftnoir_tracker_hydra/ftnoir_tracker_hydra.cpp | 1 - 1 file changed, 1 deletion(-) diff --git a/ftnoir_tracker_hydra/ftnoir_tracker_hydra.cpp b/ftnoir_tracker_hydra/ftnoir_tracker_hydra.cpp index 42de16c1..b7d078c2 100644 --- a/ftnoir_tracker_hydra/ftnoir_tracker_hydra.cpp +++ b/ftnoir_tracker_hydra/ftnoir_tracker_hydra.cpp @@ -1,7 +1,6 @@ /* Copyright: "i couldn't care less what anyone does with the 5 lines of code i wrote" - mm0zct */ #include "ftnoir_tracker_hydra.h" #include "facetracknoir/plugin-support.h" -#include "facetracknoir/rotation.h" #include #ifdef _WIN32 # define SIXENSE_STATIC_LIB -- cgit v1.2.3 From ea1c5f78af31c91521fac2a1f170eb668074f751 Mon Sep 17 00:00:00 2001 From: Stanislaw Halik Date: Tue, 23 Sep 2014 23:13:34 +0200 Subject: unbreak hopefully --- x-plane-plugin/plugin.c | 6 ++++-- 1 file changed, 4 insertions(+), 2 deletions(-) diff --git a/x-plane-plugin/plugin.c b/x-plane-plugin/plugin.c index 62c9d6f0..3958c895 100644 --- a/x-plane-plugin/plugin.c +++ b/x-plane-plugin/plugin.c @@ -13,8 +13,6 @@ #include #include -#include "ftnoir_tracker_base/ftnoir_tracker_types.h" - #ifndef PLUGIN_API #define PLUGIN_API #endif @@ -23,6 +21,10 @@ #define WINE_SHM_NAME "facetracknoir-wine-shm" #define WINE_MTX_NAME "facetracknoir-wine-mtx" +enum Axis { + TX = 0, TY, TZ, Yaw, Pitch, Roll +}; + typedef struct PortableLockedShm { void* mem; int fd, size; -- cgit v1.2.3 From 6c7f296a3dd11be3612af0e172280712ba8028a8 Mon Sep 17 00:00:00 2001 From: Stanislaw Halik Date: Tue, 23 Sep 2014 23:30:36 +0200 Subject: fix dos2unix fiasco --- ftnoir_tracker_pt/Resources/Logo_IR.png | Bin 10385 -> 10386 bytes ftnoir_tracker_pt/Resources/cap_front.png | Bin 1163 -> 1164 bytes ftnoir_tracker_pt/Resources/cap_side.png | Bin 1732 -> 1733 bytes ftnoir_tracker_pt/Resources/clip_front.png | Bin 570 -> 571 bytes ftnoir_tracker_pt/Resources/clip_side.png | Bin 2676 -> 2677 bytes ftnoir_tracker_pt/doc/logo.png | Bin 10385 -> 10386 bytes ftnoir_tracker_pt/doc/settings1.png | Bin 25012 -> 25013 bytes ftnoir_tracker_pt/doc/settings2.png | Bin 26840 -> 26841 bytes ftnoir_tracker_pt/doc/settings3.png | Bin 29546 -> 29547 bytes 9 files changed, 0 insertions(+), 0 deletions(-) diff --git a/ftnoir_tracker_pt/Resources/Logo_IR.png b/ftnoir_tracker_pt/Resources/Logo_IR.png index 85590691..95032a25 100644 Binary files a/ftnoir_tracker_pt/Resources/Logo_IR.png and b/ftnoir_tracker_pt/Resources/Logo_IR.png differ diff --git a/ftnoir_tracker_pt/Resources/cap_front.png b/ftnoir_tracker_pt/Resources/cap_front.png index cbee28c9..14207a67 100644 Binary files a/ftnoir_tracker_pt/Resources/cap_front.png and b/ftnoir_tracker_pt/Resources/cap_front.png differ diff --git a/ftnoir_tracker_pt/Resources/cap_side.png b/ftnoir_tracker_pt/Resources/cap_side.png index 27c28341..5ad4ee65 100644 Binary files a/ftnoir_tracker_pt/Resources/cap_side.png and b/ftnoir_tracker_pt/Resources/cap_side.png differ diff --git a/ftnoir_tracker_pt/Resources/clip_front.png b/ftnoir_tracker_pt/Resources/clip_front.png index 63fd70eb..04880138 100644 Binary files a/ftnoir_tracker_pt/Resources/clip_front.png and b/ftnoir_tracker_pt/Resources/clip_front.png differ diff --git a/ftnoir_tracker_pt/Resources/clip_side.png b/ftnoir_tracker_pt/Resources/clip_side.png index 1c295506..72667ac7 100644 Binary files a/ftnoir_tracker_pt/Resources/clip_side.png and b/ftnoir_tracker_pt/Resources/clip_side.png differ diff --git a/ftnoir_tracker_pt/doc/logo.png b/ftnoir_tracker_pt/doc/logo.png index 85590691..95032a25 100644 Binary files a/ftnoir_tracker_pt/doc/logo.png and b/ftnoir_tracker_pt/doc/logo.png differ diff --git a/ftnoir_tracker_pt/doc/settings1.png b/ftnoir_tracker_pt/doc/settings1.png index 0725f5f4..35b84c5c 100644 Binary files a/ftnoir_tracker_pt/doc/settings1.png and b/ftnoir_tracker_pt/doc/settings1.png differ diff --git a/ftnoir_tracker_pt/doc/settings2.png b/ftnoir_tracker_pt/doc/settings2.png index 382ed13a..c6cfd1f3 100644 Binary files a/ftnoir_tracker_pt/doc/settings2.png and b/ftnoir_tracker_pt/doc/settings2.png differ diff --git a/ftnoir_tracker_pt/doc/settings3.png b/ftnoir_tracker_pt/doc/settings3.png index 821453d1..5922403d 100644 Binary files a/ftnoir_tracker_pt/doc/settings3.png and b/ftnoir_tracker_pt/doc/settings3.png differ -- cgit v1.2.3 From e41e19fb072caf7598f18b5244b4d32c10eed161 Mon Sep 17 00:00:00 2001 From: Stanislaw Halik Date: Wed, 24 Sep 2014 17:54:28 +0200 Subject: timer: convert to ms on demand --- facetracknoir/timer.hpp | 3 +++ 1 file changed, 3 insertions(+) diff --git a/facetracknoir/timer.hpp b/facetracknoir/timer.hpp index d2df1efd..8eb6b943 100644 --- a/facetracknoir/timer.hpp +++ b/facetracknoir/timer.hpp @@ -62,4 +62,7 @@ public: (void) clock_gettime(CLOCK_MONOTONIC, &cur); return conv(cur); } + long elapsed_ms() { + return elapsed() / 1000000L; + } }; -- cgit v1.2.3 From d1b51c8c818e3b5745d926976799842a714a6e30 Mon Sep 17 00:00:00 2001 From: Stanislaw Halik Date: Wed, 24 Sep 2014 17:54:53 +0200 Subject: core: fix timer units --- facetracknoir/tracker.cpp | 384 +++++++++++++++++++++++----------------------- 1 file changed, 192 insertions(+), 192 deletions(-) diff --git a/facetracknoir/tracker.cpp b/facetracknoir/tracker.cpp index 90e9bdad..6d5a7ec9 100644 --- a/facetracknoir/tracker.cpp +++ b/facetracknoir/tracker.cpp @@ -1,192 +1,192 @@ -/* Copyright (c) 2012-2013 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. - */ - -/* - * this file appeared originally in facetracknoir, was rewritten completely - * following opentrack fork. - * - * originally written by Wim Vriend. - */ - -#include "tracker.h" -#include "facetracknoir.h" -#include -#include -#include - -#if defined(_WIN32) -# include -#endif - -Tracker::Tracker(FaceTrackNoIR *parent , main_settings& s) : - mainApp(parent), - s(s), - should_quit(false), - do_center(false), - enabled(true) -{ -} - -Tracker::~Tracker() -{ - should_quit = true; - wait(); -} - -static void get_curve(double pos, double& out, THeadPoseDOF& axis) { - bool altp = (pos < 0) && axis.opts.altp; - axis.curve.setTrackingActive( !altp ); - axis.curveAlt.setTrackingActive( altp ); - auto& fc = altp ? axis.curveAlt : axis.curve; - out = (axis.opts.invert ? -1 : 1) * fc.getValue(pos); - - out += axis.opts.zero; -} - -static void t_compensate(double* input, double* output, bool rz) -{ - const auto H = input[Yaw] * M_PI / -180; - const auto P = input[Pitch] * M_PI / -180; - const auto B = input[Roll] * M_PI / 180; - - const auto cosH = cos(H); - const auto sinH = sin(H); - const auto cosP = cos(P); - const auto sinP = sin(P); - const auto cosB = cos(B); - const auto sinB = sin(B); - - double foo[] = { - cosH * cosB - sinH * sinP * sinB, - - sinB * cosP, - sinH * cosB + cosH * sinP * sinB, - cosH * sinB + sinH * sinP * cosB, - cosB * cosP, - sinB * sinH - cosH * sinP * cosB, - - sinH * cosP, - - sinP, - cosH * cosP, - }; - - cv::Mat rmat(3, 3, CV_64F, foo); - const cv::Mat tvec(3, 1, CV_64F, input); - cv::Mat ret = rmat * tvec; - - const int max = !rz ? 3 : 2; - - for (int i = 0; i < max; i++) - output[i] = ret.at(i); -} - -void Tracker::run() { - T6DOF offset_camera; - - double newpose[6] = {0}; - int sleep_ms = 15; - - if (Libraries->pTracker) - sleep_ms = std::min(sleep_ms, 1000 / Libraries->pTracker->preferredHz()); - - qDebug() << "tracker Hz:" << 1000 / sleep_ms; - -#if defined(_WIN32) - (void) timeBeginPeriod(1); -#endif - - for (;;) - { - t.start(); - - if (should_quit) - break; - - if (Libraries->pTracker) { - Libraries->pTracker->GetHeadPoseData(newpose); - } - - { - QMutexLocker foo(&mtx); - - for (int i = 0; i < 6; i++) - { - raw_6dof.axes[i] = newpose[i]; - - auto& axis = mainApp->axis(i); - - int k = axis.opts.src; - if (k < 0 || k >= 6) - continue; - - axis.headPos = newpose[k]; - } - - if (do_center) { - for (int i = 0; i < 6; i++) - offset_camera.axes[i] = mainApp->axis(i).headPos; - - do_center = false; - - if (Libraries->pFilter) - Libraries->pFilter->reset(); - } - - T6DOF target_camera, target_camera2, new_camera; - - if (enabled) - { - for (int i = 0; i < 6; i++) - target_camera.axes[i] = mainApp->axis(i).headPos; - - target_camera2 = target_camera - offset_camera; - } - - if (Libraries->pFilter) { - Libraries->pFilter->FilterHeadPoseData(target_camera2.axes, new_camera.axes); - } else { - new_camera = target_camera2; - } - - for (int i = 0; i < 6; i++) { - get_curve(new_camera.axes[i], output_camera.axes[i], mainApp->axis(i)); - } - - if (mainApp->s.tcomp_p) - t_compensate(output_camera.axes, output_camera.axes, mainApp->s.tcomp_tz); - - if (Libraries->pProtocol) { - Libraries->pProtocol->sendHeadposeToGame( output_camera.axes ); - } - } - - const long q = std::max(0L, sleep_ms * 1000L - std::max(0L, t.elapsed())); - - usleep(q); - } -#if defined(_WIN32) - (void) timeEndPeriod(1); -#endif - - for (int i = 0; i < 6; i++) - { - mainApp->axis(i).curve.setTrackingActive(false); - mainApp->axis(i).curveAlt.setTrackingActive(false); - } -} - -void Tracker::getHeadPose( double *data ) { - QMutexLocker foo(&mtx); - for (int i = 0; i < 6; i++) - { - data[i] = raw_6dof.axes[i]; - } -} - -void Tracker::getOutputHeadPose( double *data ) { - QMutexLocker foo(&mtx); - for (int i = 0; i < 6; i++) - data[i] = output_camera.axes[i]; -} +/* Copyright (c) 2012-2013 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. + */ + +/* + * this file appeared originally in facetracknoir, was rewritten completely + * following opentrack fork. + * + * originally written by Wim Vriend. + */ + +#include "tracker.h" +#include "facetracknoir.h" +#include +#include +#include + +#if defined(_WIN32) +# include +#endif + +Tracker::Tracker(FaceTrackNoIR *parent , main_settings& s) : + mainApp(parent), + s(s), + should_quit(false), + do_center(false), + enabled(true) +{ +} + +Tracker::~Tracker() +{ + should_quit = true; + wait(); +} + +static void get_curve(double pos, double& out, THeadPoseDOF& axis) { + bool altp = (pos < 0) && axis.opts.altp; + axis.curve.setTrackingActive( !altp ); + axis.curveAlt.setTrackingActive( altp ); + auto& fc = altp ? axis.curveAlt : axis.curve; + out = (axis.opts.invert ? -1 : 1) * fc.getValue(pos); + + out += axis.opts.zero; +} + +static void t_compensate(double* input, double* output, bool rz) +{ + const auto H = input[Yaw] * M_PI / -180; + const auto P = input[Pitch] * M_PI / -180; + const auto B = input[Roll] * M_PI / 180; + + const auto cosH = cos(H); + const auto sinH = sin(H); + const auto cosP = cos(P); + const auto sinP = sin(P); + const auto cosB = cos(B); + const auto sinB = sin(B); + + double foo[] = { + cosH * cosB - sinH * sinP * sinB, + - sinB * cosP, + sinH * cosB + cosH * sinP * sinB, + cosH * sinB + sinH * sinP * cosB, + cosB * cosP, + sinB * sinH - cosH * sinP * cosB, + - sinH * cosP, + - sinP, + cosH * cosP, + }; + + cv::Mat rmat(3, 3, CV_64F, foo); + const cv::Mat tvec(3, 1, CV_64F, input); + cv::Mat ret = rmat * tvec; + + const int max = !rz ? 3 : 2; + + for (int i = 0; i < max; i++) + output[i] = ret.at(i); +} + +void Tracker::run() { + T6DOF offset_camera; + + double newpose[6] = {0}; + int sleep_ms = 15; + + if (Libraries->pTracker) + sleep_ms = std::min(sleep_ms, 1000 / Libraries->pTracker->preferredHz()); + + qDebug() << "tracker Hz:" << 1000 / sleep_ms; + +#if defined(_WIN32) + (void) timeBeginPeriod(1); +#endif + + for (;;) + { + t.start(); + + if (should_quit) + break; + + if (Libraries->pTracker) { + Libraries->pTracker->GetHeadPoseData(newpose); + } + + { + QMutexLocker foo(&mtx); + + for (int i = 0; i < 6; i++) + { + raw_6dof.axes[i] = newpose[i]; + + auto& axis = mainApp->axis(i); + + int k = axis.opts.src; + if (k < 0 || k >= 6) + continue; + + axis.headPos = newpose[k]; + } + + if (do_center) { + for (int i = 0; i < 6; i++) + offset_camera.axes[i] = mainApp->axis(i).headPos; + + do_center = false; + + if (Libraries->pFilter) + Libraries->pFilter->reset(); + } + + T6DOF target_camera, target_camera2, new_camera; + + if (enabled) + { + for (int i = 0; i < 6; i++) + target_camera.axes[i] = mainApp->axis(i).headPos; + + target_camera2 = target_camera - offset_camera; + } + + if (Libraries->pFilter) { + Libraries->pFilter->FilterHeadPoseData(target_camera2.axes, new_camera.axes); + } else { + new_camera = target_camera2; + } + + for (int i = 0; i < 6; i++) { + get_curve(new_camera.axes[i], output_camera.axes[i], mainApp->axis(i)); + } + + if (mainApp->s.tcomp_p) + t_compensate(output_camera.axes, output_camera.axes, mainApp->s.tcomp_tz); + + if (Libraries->pProtocol) { + Libraries->pProtocol->sendHeadposeToGame( output_camera.axes ); + } + } + + const long q = std::max(0L, sleep_ms * 1000000L - std::max(0L, t.elapsed())); + + usleep(q); + } +#if defined(_WIN32) + (void) timeEndPeriod(1); +#endif + + for (int i = 0; i < 6; i++) + { + mainApp->axis(i).curve.setTrackingActive(false); + mainApp->axis(i).curveAlt.setTrackingActive(false); + } +} + +void Tracker::getHeadPose( double *data ) { + QMutexLocker foo(&mtx); + for (int i = 0; i < 6; i++) + { + data[i] = raw_6dof.axes[i]; + } +} + +void Tracker::getOutputHeadPose( double *data ) { + QMutexLocker foo(&mtx); + for (int i = 0; i < 6; i++) + data[i] = output_camera.axes[i]; +} -- cgit v1.2.3 From d5cf8540bf5d04fdcdce543b3cf0dc531dfd464f Mon Sep 17 00:00:00 2001 From: Stanislaw Halik Date: Wed, 24 Sep 2014 17:55:05 +0200 Subject: half gain logic done --- facetracknoir/gain-control.hpp | 175 +++++++++++++++++++++++++++++++++++++++++ 1 file changed, 175 insertions(+) create mode 100644 facetracknoir/gain-control.hpp diff --git a/facetracknoir/gain-control.hpp b/facetracknoir/gain-control.hpp new file mode 100644 index 00000000..28887700 --- /dev/null +++ b/facetracknoir/gain-control.hpp @@ -0,0 +1,175 @@ +#pragma once + +#include +#undef NDEBUG +#include +#include +#include +#include +#include + +#include "timer.hpp" + +#include +#include +#include + +#include + +namespace detail { + template + class zip_iterator : public std::iterator + { + private: + using self = zip_iterator; + t1 x1, z1; + t2 x2, z2; + void maybe_end() { if (x1 == z1 || x2 == z2) *this = end(); } + public: + zip_iterator(const t1& it1, const t1& end1, const t2& it2, const t2& end2) + : x1(it1), z1(end1), x2(it2), z2(end2) { maybe_end(); } + constexpr zip_iterator() {} + + static constexpr self end() { return self(); } + + self operator++() { x1++; x2++; self tmp = *this; maybe_end(); return tmp; } + self operator++(int) { self tmp(*this); x1++; x2++; maybe_end(); return tmp; } + bool operator==(const self& rhs) const { return x1 == rhs.x1 && x2 == rhs.x2; } + bool operator!=(const self& rhs) const { return !this->operator ==(rhs); } + t operator*() { return m(*x1, *x2); } + }; +} + +class Gain { +private: + static constexpr bool use_box_filter = true; + static constexpr int box_size = 20 / 640.; + static constexpr double control_upper_bound = 1.0; // XXX FIXME implement for logitech crapola + static constexpr int GAIN_HISTORY_COUNT = 15, GAIN_HISTORY_EVERY_MS = 200; + + int control; + double step, eps; + + std::deque means_history; + + Timer debug_timer, history_timer; + + typedef unsigned char px; + template + using zip_iterator = detail::zip_iterator; + + static double mean(const cv::Mat& frame) + { + // grayscale only + assert(frame.channels() == 1); + assert(frame.elemSize() == 1); + assert(!frame.empty()); + + return std::accumulate(frame.begin(), frame.end(), 0.) / (frame.rows * frame.cols); + } + + static double get_variance(const cv::Mat& frame, double mean) + { + struct variance { + private: + double mu; + public: + variance(double mu) : mu(mu) {} + double operator()(double seed, px p) + { + double tmp = p - mu; + return seed + tmp * tmp; + } + } logic(mean); + + return std::accumulate(frame.begin(), frame.end(), 0., logic) / (frame.rows * frame.cols); + } + + static double get_covariance(const cv::Mat& frame, double mean, double prev_mean) + { + struct covariance { + public: + using pair = std::tuple; + private: + double mu_0, mu_1; + + inline double Cov(double seed, const pair& t) + { + px p0 = std::get<0>(t); + px p1 = std::get<1>(t); + return seed + (p0 - mu_0) * (p1 - mu_1); + } + public: + covariance(double mu_0, double mu_1) : mu_0(mu_0), mu_1(mu_1) {} + + double operator()(double seed, const pair& t) + { + return Cov(seed, t); + } + } logic(mean, prev_mean); + + const double N = frame.rows * frame.cols; + + using zipper = zip_iterator, + cv::MatConstIterator_, + std::tuple>; + + zipper zip(frame.begin(), + frame.end(), + frame.begin(), + frame.end()); + std::vector values(zip, zipper::end()); + + return std::accumulate(values.begin(), values.end(), 0., logic) / N; + } + +#pragma GCC diagnostic ignored "-Wsign-compare" + +public: + Gain(int control = CV_CAP_PROP_GAIN, double step = 0.3, double eps = 0.02) : + control(control), step(step), eps(eps) + { + } + + void tick(cv::VideoCapture&, const cv::Mat& frame_) + { + cv::Mat frame; + + if (use_box_filter) + { + cv::Mat tmp(frame_); + static constexpr int min_box = 3; + static constexpr int box = 2 * box_size; + cv::blur(frame_, tmp, cv::Size(min_box + box * frame_.cols, min_box + box * frame_.rows)); + frame = tmp; + } + else + frame = frame_; + + const double mu = mean(frame); + const double var = get_variance(frame, mu); + + if (debug_timer.elapsed_ms() > 500) + { + debug_timer.start(); + qDebug() << "gain:" << "mean" << mu << "variance" << var; + } + + const int sz = means_history.size(); + + for (int i = 0; i < sz; i++) + { + const double cov = get_covariance(frame, mu, means_history[i]); + + qDebug() << "cov" << i << cov; + } + + if (GAIN_HISTORY_COUNT > means_history.size() && history_timer.elapsed_ms() > GAIN_HISTORY_EVERY_MS) + { + means_history.push_front(mu); + + if (GAIN_HISTORY_COUNT == means_history.size()) + means_history.pop_back(); + } + } +}; -- cgit v1.2.3 From 8f12f50a6b06e6c1104efcee37c2f29087dbd3da Mon Sep 17 00:00:00 2001 From: Stanislaw Halik Date: Wed, 24 Sep 2014 17:55:27 +0200 Subject: use gain class already for debugging sake --- ftnoir_tracker_aruco/ftnoir_tracker_aruco.cpp | 2 ++ ftnoir_tracker_aruco/ftnoir_tracker_aruco.h | 5 ++++- 2 files changed, 6 insertions(+), 1 deletion(-) diff --git a/ftnoir_tracker_aruco/ftnoir_tracker_aruco.cpp b/ftnoir_tracker_aruco/ftnoir_tracker_aruco.cpp index 97830c9a..e216d319 100644 --- a/ftnoir_tracker_aruco/ftnoir_tracker_aruco.cpp +++ b/ftnoir_tracker_aruco/ftnoir_tracker_aruco.cpp @@ -214,6 +214,8 @@ void Tracker::run() grayscale = channel[2]; } else cv::cvtColor(color, grayscale, cv::COLOR_BGR2GRAY); + + gain.tick(camera, grayscale); const int scale = frame.cols > 480 ? 2 : 1; detector.setThresholdParams(scale > 1 ? 11 : 7, 4); diff --git a/ftnoir_tracker_aruco/ftnoir_tracker_aruco.h b/ftnoir_tracker_aruco/ftnoir_tracker_aruco.h index 81332a26..5416bb52 100644 --- a/ftnoir_tracker_aruco/ftnoir_tracker_aruco.h +++ b/ftnoir_tracker_aruco/ftnoir_tracker_aruco.h @@ -21,6 +21,9 @@ #include "facetracknoir/options.h" #include "ftnoir_tracker_aruco/trans_calib.h" #include "facetracknoir/plugin-api.hpp" + +#include "facetracknoir/gain-control.hpp" + using namespace options; struct settings { @@ -65,9 +68,9 @@ private: cv::VideoCapture camera; cv::Matx33f r; cv::Vec3f t; + Gain gain; }; -// Widget that has controls for FTNoIR protocol client-settings. class TrackerControls : public QWidget, public ITrackerDialog { Q_OBJECT -- cgit v1.2.3