parent
874796b87f
commit
32a1fd8f54
@ -0,0 +1,173 @@
|
||||
|
||||
|
||||
#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("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();
|
||||
}
|
||||
|
||||
|
@ -0,0 +1,77 @@
|
||||
/***************************************************************************************
|
||||
*
|
||||
* detect.h is part of SimpleSkyCam.
|
||||
*
|
||||
*****************************************************************************************/
|
||||
|
||||
|
||||
#ifndef _DETECT_H_
|
||||
#define _DETECT_H_
|
||||
|
||||
#include "gui.h"
|
||||
#include "config.h"
|
||||
#include "video.h"
|
||||
#include "videoframe.h"
|
||||
|
||||
|
||||
struct {
|
||||
VideoFrame *image; // detected image
|
||||
int posx; // position of the detected object
|
||||
int posy; // position of the detected object
|
||||
} typedef DetectOutput;
|
||||
|
||||
|
||||
|
||||
class Detect {
|
||||
private:
|
||||
int running;
|
||||
VideoFrame inFrame; // input frame
|
||||
VideoFrame oldFrame; // oldinput frame
|
||||
int inFrameNew; // new input frame;
|
||||
VideoFrame image; // output image
|
||||
VideoFrame imagegtk; // output image -- send to gtk
|
||||
GMutex muteximage;
|
||||
GMutex mutexin;
|
||||
GMutex mutex; // general mutex for changing settings
|
||||
GThread *thread;
|
||||
|
||||
float *maxx;
|
||||
float *maxy;
|
||||
int posmaxx;
|
||||
int posmaxy;
|
||||
|
||||
int objectW; // object Image Size Width
|
||||
int objectH; // object Image Size Height
|
||||
|
||||
void InputDetect(int *posx, int *posy);
|
||||
void SetInputSize (int nw, int nh);
|
||||
|
||||
public:
|
||||
Detect();
|
||||
~Detect();
|
||||
|
||||
int NewFrame(VideoFrame *newframe);
|
||||
|
||||
//
|
||||
// Thread Releated Functions (maybe soon private?)
|
||||
int TryLockInMutex() { return g_mutex_trylock(&mutexin); };
|
||||
void LockInMutex() { g_mutex_lock(&mutexin);};
|
||||
void UnLockInMutex() { g_mutex_unlock(&mutexin);};
|
||||
|
||||
int TryLockImageMutex() { return g_mutex_trylock(&muteximage); };
|
||||
void LockImageMutex() { g_mutex_lock(&muteximage);};
|
||||
void UnLockImageMutex() { g_mutex_unlock(&muteximage);};
|
||||
|
||||
void LockMutex() { g_mutex_lock(&mutex);};
|
||||
void UnLockMutex() { g_mutex_unlock(&mutex);};
|
||||
|
||||
|
||||
//
|
||||
// Object functions
|
||||
void SetObjectSize (int neww, int newh);
|
||||
void GetObjectPos (int *x, int *y);
|
||||
|
||||
void Thread();
|
||||
};
|
||||
|
||||
#endif
|
Loading…
Reference in new issue