diff --git a/detect.cc b/detect.cc index 66bf82a..c98228c 100644 --- a/detect.cc +++ b/detect.cc @@ -37,6 +37,8 @@ Detect::Detect() { // @suppress("Class members should be properly initialized") posmaxy = 0; maxx = NULL; maxy = NULL; + detmatrix = NULL; + inputtype = 0; }; @@ -66,7 +68,8 @@ int Detect::NewFrame(VideoFrame *newframe) { // Thread: newFrame |------> Find Object --- not found ---> send gui information void Detect::Thread() { DetectOutput output; - int posx, posy; + int errorinputtype = -1; + int posx = -1, posy = -1; while (running) { // check for new frame @@ -74,9 +77,32 @@ void Detect::Thread() { if (inFrameNew == 1) { inFrameNew = 0; + LockMutex(); // lock Config + // - // do some input detection improvement - InputDetect(&posx, &posy); + // 1. if no position of the object is known, search brightest + // object on the inFrame image. + // 2. check near the last known position. + + switch (inputtype) { + case 0: + InputDetect(&posx, &posy); + break; + + case 1: + if (posx < objectW/2 || posy < objectH/2 || + posx > (inFrame.w-objectW/2) || posy > (inFrame.h-objectH/2)) + InputDetect(&posx, &posy); + else InputDetectCrossC(&posx, &posy); + break; + + default: + if (errorinputtype != inputtype) + printf ("%s:%d %s error: inputtype (%d) not found\n", __FILE__, __LINE__, __FUNCTION__, inputtype); + errorinputtype = inputtype; + break; + } + oldFrame.CopyFrom(&inFrame); UnLockInMutex(); @@ -84,6 +110,9 @@ void Detect::Thread() { LockImageMutex(); imagegtk.CopyFrom(&image); UnLockImageMutex(); + + UnLockMutex(); // unlock Config + output.posx = posx; output.posy = posy; output.image = &imagegtk; @@ -106,6 +135,12 @@ void Detect::SetInputSize (int nw, int nh) { if (maxy != NULL) free (maxy); maxy = (float*) malloc (nh * sizeof (float)); } + + if ((posmaxx * posmaxy) < (nw * nh) || detmatrix != NULL) { + free (detmatrix); + detmatrix = (float*) malloc (sizeof(float) * nw * nh); + } + posmaxx = nw; posmaxy = nh; } @@ -172,6 +207,111 @@ void Detect::InputDetect(int *posx, int *posy) { // 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]; } + +// printf ("%s:%d %s pos: %d,%d \n", __FILE__, __LINE__, __FUNCTION__, *posx, *posy); + +#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 +} + + + +#define MAXSHIFT 20 +// #define DEBUGTIMES 1 +void Detect::InputDetectCrossC(int *posx, int *posy) { + unsigned char *pxi; // input image + unsigned char *pxd; // destination image + unsigned char *pxo; // old image + int inx, iny, oldx, oldy; + + struct timeval t1, t2; + int shiftx, shifty, x, y, ini, oldi, desti, mxi, mxx, mxy; + float f; + + if (oldFrame.h != inFrame.h || oldFrame.w != inFrame.w || *posx == -1 || *posy == -1) { + *posx = -1; + *posy = -1; + return; + } + +#ifdef DEBUGTIMES + f = get_cycletime(&t1); + t2 = t1; +#endif + + if (objectW > inFrame.w || objectH > inFrame.h) { + printf ("%s:%d %s objectW,H (%d,%d) > inFrame.W,H (%d, %d)\n", __FILE__, __LINE__, __FUNCTION__, + objectW, objectH, inFrame.w, inFrame.h); + *posx = -1; + *posy = -1; + return; + } + + image.SetSize (objectW, objectH); + SetInputSize(inFrame.w, inFrame.h); + pxi = inFrame.data; + pxo = oldFrame.data; + pxd = image.data; + +#ifdef DEBUGTIMES + f = get_cycletime(&t1); + printf ("%s:%d setup memory time needed:%f\n", __FILE__, __LINE__, f); +#endif + + mxx = mxy = 0; + for (shifty = 0; shifty < MAXSHIFT; shifty++) { + // printf ("%s:%d %s shift (%d)\n", __FILE__, __LINE__, __FUNCTION__, shifty); + mxi = shifty * objectW; + for (shiftx = 0; shiftx < MAXSHIFT; shiftx++, mxi++) { + // fixme: help help + f = 0.0; + + for (y = 0; y < objectH; y++) { + oldx = (*posx)- objectW/2; + oldy = (*posy)- objectH/2 + y; + oldi = 3 * (oldx + oldFrame.w * oldy); + + inx = oldx + shiftx - MAXSHIFT/2; + iny = oldy + shifty - MAXSHIFT/2; + ini = 3* (inx + inFrame.w * iny); + + for (x = 0; x < objectW; x++, oldi += 3, ini += 3, oldx++, inx++) { + if (oldx >= 0 && oldy >= 0 && oldx < oldFrame.w && oldy <= oldFrame.h && + inx >= 0 && inx < inFrame.w && iny >= 0 && iny < inFrame.h) { + f += (float)(pxo[oldi+0])*(float)(pxi[ini+0]); + } + } + } + detmatrix[mxi] = f; + if (detmatrix[mxx + (mxy * objectW)] < f) { + mxx = shiftx; + mxy = shifty; + } + } + } + +// printf ("%s:%d %s pos (%d,%d) dpos (%d,%d) newpos (%d,%d)\n", __FILE__, __LINE__, __FUNCTION__, +// *posx, *posy, (mxx-MAXSHIFT/2), (mxy-MAXSHIFT/2), *posx - (mxx-MAXSHIFT/2), *posy - (mxy-MAXSHIFT/2)); + + *posx -= (mxx-MAXSHIFT/2); + *posy -= (mxy-MAXSHIFT/2); + + // + // copy image data to destination + for (x = 0; x < objectW; x++) for (y = 0; y < objectH; y++) { + desti = 3*(x + y * objectW); + ini = 3*((x + *posx - objectW/2) + (y + *posy - objectH/2) * inFrame.w); + if (desti < 0 || desti > objectW*objectH*3) continue; + if (ini < 0 || ini > inFrame.w*inFrame.h*3) continue; + pxd[desti+0] = pxi[ini+0]; + pxd[desti+1] = pxi[ini+1]; + pxd[desti+2] = pxi[ini+2]; + } + #ifdef DEBUGTIMES f = get_cycletime(&t1); printf ("%s:%d copy output:%f\n", __FILE__, __LINE__, f); @@ -181,6 +321,14 @@ void Detect::InputDetect(int *posx, int *posy) { } + +void Detect::SetInputType(int intype) { + LockMutex(); + inputtype = intype; + UnLockMutex(); +} + + void Detect::SetObjectSize(int neww, int newh) { LockImageMutex(); LockInMutex(); @@ -195,3 +343,9 @@ void Detect::SetObjectSize(int neww, int newh) { } +void Detect::SetMinBrightness(int value) { + LockMutex(); + minBright = value; + UnLockMutex(); +} + diff --git a/detect.h b/detect.h index 3b6af1c..7b2d27c 100644 --- a/detect.h +++ b/detect.h @@ -39,11 +39,16 @@ private: float *maxy; int posmaxx; int posmaxy; + float *detmatrix; int objectW; // object Image Size Width int objectH; // object Image Size Height + int minBright; // min brightness - void InputDetect(int *posx, int *posy); + int inputtype; // input detection type to use + + void InputDetect (int *posx, int *posy); + void InputDetectCrossC (int *posx, int *posy); void SetInputSize (int nw, int nh); public: @@ -65,10 +70,11 @@ public: void LockMutex() { g_mutex_lock(&mutex);}; void UnLockMutex() { g_mutex_unlock(&mutex);}; - // // Object functions void SetObjectSize (int neww, int newh); + void SetMinBrightness (int value); + void SetInputType(int intype); void GetObjectPos (int *x, int *y); void Thread(); diff --git a/gui.cc b/gui.cc index 5933bda..4ed7fff 100644 --- a/gui.cc +++ b/gui.cc @@ -188,13 +188,13 @@ void cb_imagetempda_draw(GtkWidget *area, cairo_t *cr, int w, int h, gpointer da void cb_detect_btnset (GtkWidget *widget, gpointer data) { - GtkWidget *txtx = GTK_WIDGET(gtk_builder_get_object (GTK_BUILDER(_builder_), "detect-entry-x")); - GtkWidget *txty = GTK_WIDGET(gtk_builder_get_object (GTK_BUILDER(_builder_), "detect-entry-y")); +// GtkWidget *txtx = GTK_WIDGET(gtk_builder_get_object (GTK_BUILDER(_builder_), "detect-entry-x")); +// GtkWidget *txty = GTK_WIDGET(gtk_builder_get_object (GTK_BUILDER(_builder_), "detect-entry-y")); GtkWidget *txtw = GTK_WIDGET(gtk_builder_get_object (GTK_BUILDER(_builder_), "detect-entry-w")); GtkWidget *txth = GTK_WIDGET(gtk_builder_get_object (GTK_BUILDER(_builder_), "detect-entry-h")); detect.SetObjectSize( atoi(gtk_entry_get_text(GTK_ENTRY(txtw))), - atoi(gtk_entry_get_text(GTK_ENTRY(txtw)))); + atoi(gtk_entry_get_text(GTK_ENTRY(txth)))); }; @@ -254,3 +254,23 @@ void cb_image_btnsave (GtkWidget *widget, gpointer data) { }; +void cb_detect_bright (GtkRange *range, gpointer data) { + GtkWidget *scale = GTK_WIDGET(gtk_builder_get_object (GTK_BUILDER(_builder_), "detect-adj-bright")); + double value; + + value = gtk_range_get_value(range); + detect.SetMinBrightness(value); +}; + + +void cb_detect_inputtype (GtkWidget *widget, gpointer data) { + if (gtk_toggle_button_get_active (GTK_TOGGLE_BUTTON(widget)) == 1) { + if (widget == GTK_WIDGET(gtk_builder_get_object (GTK_BUILDER(_builder_), "detect-type-indet1"))) + detect.SetInputType(0); + if (widget == GTK_WIDGET(gtk_builder_get_object (GTK_BUILDER(_builder_), "detect-type-indet2"))) + detect.SetInputType(1); + if (widget == GTK_WIDGET(gtk_builder_get_object (GTK_BUILDER(_builder_), "detect-type-indet3"))) + detect.SetInputType(2); + } +}; + diff --git a/gui.h b/gui.h index 3ba28f5..d4eae7d 100644 --- a/gui.h +++ b/gui.h @@ -52,16 +52,19 @@ G_MODULE_EXPORT gboolean cb_thread_video (gpointer data); // -// filter new temp or image data +// filter detect or image data G_MODULE_EXPORT void cb_imagetempda_draw(GtkWidget *area, cairo_t *cr, int w, int h, gpointer data); G_MODULE_EXPORT gboolean cb_thread_filter (gpointer data); G_MODULE_EXPORT gboolean cb_thread_detect (gpointer data); G_MODULE_EXPORT void cb_image_btnnew (GtkWidget *widget, gpointer data); G_MODULE_EXPORT void cb_image_btnsave (GtkWidget *widget, gpointer data); +G_MODULE_EXPORT void cb_detect_bright (GtkRange *range, gpointer data); + // // detection elements G_MODULE_EXPORT void cb_detect_btnset (GtkWidget *widget, gpointer data); +G_MODULE_EXPORT void cb_detect_inputtype (GtkWidget *widget, gpointer data); #ifdef __cplusplus } diff --git a/simpleskycam.ui b/simpleskycam.ui index cf66afc..dd0fd4c 100644 --- a/simpleskycam.ui +++ b/simpleskycam.ui @@ -2,6 +2,13 @@ + + 255.99 + 50 + 1 + 10 + 1 + False 1024 @@ -219,7 +226,7 @@ False vertical - + True False @@ -421,25 +428,164 @@ 0 + + + False + True + 0 + + + + + True + False + True - + + True + False + start + + + True + False + 8 + 8 + Helligkeit Grenze: + + + False + True + 0 + + + + + True + True + detect-adj-bright + on + on + True + 255 + 1 + + + + True + True + 1 + + + + + False + True + 0 + - + + True + False + 8 + 8 + 8 + 8 + 0 + etched-out + + + True + False + 8 + 8 + 12 + + + True + False + vertical + + + InputDetect + True + True + False + True + True + detect-type-indet2 + + + + False + True + 0 + + + + + InputDetect + InputDetectCrossC + True + True + False + True + True + detect-type-indet1 + + + + False + True + 1 + + + + + unknown + True + True + False + True + True + detect-type-indet1 + + + + False + True + 2 + + + + + + + + + True + False + Detection Type + + + + + False + True + 4 + 1 + False True - 0 + 1 - - - 1