You can not select more than 25 topics
Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.
198 lines
4.2 KiB
198 lines
4.2 KiB
|
|
|
|
#include <unistd.h>
|
|
#include <math.h>
|
|
#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("Detect", _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
|
|
// #define DEBUGTIMES 1
|
|
void Detect::InputDetect(int *posx, int *posy) {
|
|
int x, y, i, dx, dy, sy;
|
|
unsigned char *pxs, *pxi;
|
|
int idx, didx;
|
|
struct timeval t1, t2;
|
|
float f;
|
|
|
|
f = get_cycletime(&t1);
|
|
t2 = t1;
|
|
|
|
image.SetSize (objectW, objectH);
|
|
SetInputSize(inFrame.w, inFrame.h);
|
|
pxs = inFrame.data;
|
|
pxi = image.data;
|
|
*posx = 0;
|
|
*posy = 0;
|
|
|
|
#ifdef DEBUGTIMES
|
|
f = get_cycletime(&t1);
|
|
printf ("%s:%d setup memory time needed:%f\n", __FILE__, __LINE__, f);
|
|
#endif
|
|
//
|
|
// 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] + pxs[idx+1] + pxs[idx+2], POWERVAL);
|
|
maxy[y] += pow(pxs[idx+0] + pxs[idx+1] + pxs[idx+2], POWERVAL);
|
|
}
|
|
#ifdef DEBUGTIMES
|
|
f = get_cycletime(&t1);
|
|
printf ("%s:%d calculated maximum:%f\n", __FILE__, __LINE__, f);
|
|
// select maximum
|
|
#endif
|
|
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;
|
|
#ifdef DEBUGTIMES
|
|
f = get_cycletime(&t1);
|
|
printf ("%s:%d selected maximum:%f\n", __FILE__, __LINE__, f);
|
|
#endif
|
|
|
|
// 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];
|
|
}
|
|
#ifdef DEBUGTIMES
|
|
f = get_cycletime(&t1);
|
|
printf ("%s:%d copy output:%f\n", __FILE__, __LINE__, f);
|
|
f = get_cycletime(&t2);
|
|
printf ("%s:%d time needed:%f\n", __FILE__, __LINE__, f);
|
|
#endif
|
|
}
|
|
|
|
|
|
void Detect::SetObjectSize(int neww, int newh) {
|
|
LockImageMutex();
|
|
LockInMutex();
|
|
LockMutex();
|
|
|
|
objectH = newh;
|
|
objectW = neww;
|
|
|
|
UnLockMutex();
|
|
UnLockInMutex();
|
|
UnLockImageMutex();
|
|
}
|
|
|
|
|