#include #include #include "config.h" #include "gui.h" #include "detect.h" extern Detect detect; // // C / C++ Wrapper for the thread function // gpointer _DetectThread (gpointer data) { detect.Thread (); return NULL; }; Detect::Detect() { // @suppress("Class members should be properly initialized") printf ("%s:%d %s\n", __FILE__, __LINE__, __FUNCTION__); g_mutex_init (&mutexin); g_mutex_init (&muteximage); g_mutex_init (&mutex); running = 1; inFrame.SetSize(64, 64); oldFrame.SetSize(64, 64); image.SetSize(64, 64); imagegtk.SetSize(64, 64); thread = NULL; thread = g_thread_new("Filter", _DetectThread, NULL); objectW = 300; objectH = 300; posmaxx = 0; posmaxy = 0; maxx = NULL; maxy = NULL; }; Detect::~Detect() { running = 0; if (thread) { g_thread_join (thread); thread = NULL; } }; int Detect::NewFrame(VideoFrame *newframe) { if (newframe == NULL) return -1; LockInMutex(); inFrame.CopyFrom(newframe); inFrameNew = 1; UnLockInMutex(); return 0; }; // // NewFrame: will set new frame // Thread: newFrame |------> Find Object --- not found ---> send gui information void Detect::Thread() { DetectOutput output; int posx, posy; while (running) { // check for new frame LockInMutex(); if (inFrameNew == 1) { inFrameNew = 0; // // do some input detection improvement InputDetect(&posx, &posy); oldFrame.CopyFrom(&inFrame); UnLockInMutex(); // copy output image for gtk LockImageMutex(); imagegtk.CopyFrom(&image); UnLockImageMutex(); output.posx = posx; output.posy = posy; output.image = &imagegtk; gdk_threads_add_idle(cb_thread_detect , &output); } else UnLockInMutex(); usleep (10000); } } void Detect::SetInputSize (int nw, int nh) { if (posmaxx < nw) { if (maxx != NULL) free (maxx); maxx = (float*) malloc (nw * sizeof (float)); } if (posmaxy < nh) { if (maxy != NULL) free (maxy); maxy = (float*) malloc (nh * sizeof (float)); } posmaxx = nw; posmaxy = nh; } #define POWERVAL 10 void Detect::InputDetect(int *posx, int *posy) { int x, y, i, dx, dy, sy; unsigned char *pxs, *pxi; int idx, didx; image.SetSize (objectW, objectH); SetInputSize(inFrame.w, inFrame.h); pxs = inFrame.data; pxi = image.data; *posx = 0; *posy = 0; // // maximum brightness for (x = 0; x < posmaxx; x++) maxx[x] = 0.0; for (y = 0; y < posmaxy; y++) maxy[y] = 0.0; for (x = 0; x < inFrame.w; x++) for (y = 0; y < inFrame.h; y++) { idx = 3*(inFrame.w * y + x); maxx[x] += (pow(pxs[idx+0], POWERVAL) + pow(pxs[idx+1], POWERVAL) + pow(pxs[idx+2], POWERVAL)); maxy[y] += (pow(pxs[idx+0], POWERVAL) + pow(pxs[idx+1], POWERVAL) + pow(pxs[idx+2], POWERVAL)); } // select maximum for (x = 1; x < inFrame.w; x++) if (maxx[x] > maxx[*posx]) *posx = x; for (y = 1; y < inFrame.h; y++) if (maxy[y] > maxy[*posy]) *posy = y; // select start corner if (*posx < (objectW / 2)) x = 0; else if (*posx + (objectW /2) > inFrame.w) x = inFrame.w - objectW; else x = ((*posx) - (objectW / 2)); if (*posy < (objectH / 2)) sy = 0; else if (*posy + (objectH / 2) > inFrame.h) sy = inFrame.h - objectH; else sy = ((*posy) - (objectH / 2)); for (dx = 0; dx < image.w && x < inFrame.w; x++, dx++) for (dy = 0, y = sy; dy < image.h && y < inFrame.h; y++, dy++) { idx = 3* (inFrame.w * y + x); didx = 3* (image.w * dy + dx); // printf ("[%d , %d] --> [%d, %d] idx: %d --> %d Value:%d\n", x, y, dx, dy, idx, didx, pxs[idx+i]); for (i = 0; i < 3; i++) pxi[didx+i] = pxs[idx+i]; } } void Detect::SetObjectSize(int neww, int newh) { LockImageMutex(); LockInMutex(); LockMutex(); objectH = newh; objectW = neww; UnLockMutex(); UnLockInMutex(); UnLockImageMutex(); }