#include #include "config.h" #include "gui.h" #include "filter.h" extern Filter filter; gboolean cb_filtertemp_thread (gpointer data); gboolean cb_filterout_thread (gpointer data); // // C / C++ Wrapper for the thread function // gpointer _FilterThread (gpointer data) { filter.Thread (); return NULL; }; Filter::Filter() { // @suppress("Class members should be properly initialized") g_mutex_init (&mutexin); g_mutex_init (&mutexout); g_mutex_init (&mutextmp); g_mutex_init (&mutex); running = 1; inFrame.SetSize(64, 64); oldFrame.SetSize(64, 64); temp.SetSize(64, 64); tempgtk.SetSize(64, 64); image.SetSize(64, 64); imagegtk.SetSize(64, 64); thread = NULL; thread = g_thread_new("Filter", _FilterThread, NULL); }; Filter::~Filter() { running = 0; if (thread) { g_thread_join (thread); thread = NULL; } }; int Filter::NewFrame(VideoFrame *newframe) { LockInMutex(); inFrame.CopyFrom(newframe); inFrameNew = 1; UnLockInMutex(); return -1; }; // // NewFrame: will set new frame // Thread: newFrame |------> Find Object --- not found ---> send gui information void Filter::Thread() { while (running) { // check for new frame LockInMutex(); if (inFrameNew == 1) { inFrameNew = 0; // // do some input detection improvement InputDetect(); oldFrame.CopyFrom(&inFrame); UnLockInMutex(); // copy temporary image for gtk LockTempMutex(); tempgtk.CopyFrom(&temp); UnLockTempMutex(); gdk_threads_add_idle(cb_filtertemp_thread , &tempgtk); // // do some other stuff use if possible only the oldFrame data ComposeOutput(); // copy output image for gtk LockOutMutex(); imagegtk.CopyFrom(&image); UnLockOutMutex(); gdk_threads_add_idle(cb_filterout_thread , &imagegtk); } else UnLockInMutex(); usleep (10000); } } void Filter::InputDetect() { int x, y; float vo, v; unsigned char *pxs, *pxso, *pxstemp; unsigned char pixel; int idx; FloatImage fi;; float fmin, fmax; temp.SetSize (inFrame.w, inFrame.h); fi.SetSize (inFrame.w, inFrame.h); pxs = inFrame.data; pxso = oldFrame.data; pxstemp = temp.data; for (x = 0; x < temp.w && x < inFrame.w && x < oldFrame.w; x++) for (y = 0; y < temp.h && y < inFrame.h && y < oldFrame.h; y++) { idx = (inFrame.w * y + x); vo = pxso[3*idx+0] + pxso[3*idx+1] + pxso[3*idx+2]; v = pxs[3*idx+0] + pxs[3*idx+1] + pxs[3*idx+2]; fi.data[idx] = v - vo; if (idx == 0 || fmin > fi.data[idx]) fmin = fi.data[idx]; if (idx == 0 || fmax < fi.data[idx]) fmax = fi.data[idx]; } for (x = 0; x < temp.w && x < inFrame.w && x < oldFrame.w; x++) for (y = 0; y < temp.h && y < inFrame.h && y < oldFrame.h; y++) { idx = (inFrame.w * y + x); pixel = (unsigned char)((float)( (fi.data[idx]-fmin) / (fmax-fmin)) * 256.0); pxstemp[3*idx+0] = pixel; pxstemp[3*idx+1] = pixel; pxstemp[3*idx+2] = pixel; } } #define FACTOR 100.0 void Filter::ComposeOutput() { int x, y, idx, i; float *pixd; // destination unsigned char *pixs; // source image.SetSize(oldFrame.w, oldFrame.h); pixd = image.data; pixs = oldFrame.data; for (x = 0; x < temp.w && x < inFrame.w && x < oldFrame.w; x++) for (y = 0; y < temp.h && y < inFrame.h && y < oldFrame.h; y++) { idx = 3 * (oldFrame.w * y + x); for (i = 0; i < 3; i++) pixd[idx+i] = (FACTOR * pixd[idx+i]/FACTOR) + (pixs[idx+i] / FACTOR); } }