diff --git a/detect.cc b/detect.cc index fa0e3d4..a5fc60f 100644 --- a/detect.cc +++ b/detect.cc @@ -39,7 +39,7 @@ Detect::Detect() { // @suppress("Class members should be properly initialized") maxy = NULL; detmatrix = NULL; detmatrixv2 = NULL; - inputtype = 0; + autodetecttype = 2; }; @@ -85,35 +85,33 @@ void Detect::Thread() { // object on the inFrame image. // 2. check near the last known position. - switch (inputtype) { + switch (autodetecttype) { + case -1: + // no detection + break; + 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)) { - printf ("%s:%d %s find new position (last known:%d,%d)\n", - __FILE__, __LINE__, __FUNCTION__, posx, posy); + posx > (inFrame.w-objectW/2) || posy > (inFrame.h-objectH/2)) InputDetect(&posx, &posy); - } else InputDetectCrossC(&posx, &posy); break; case 2: if (posx < objectW/2 || posy < objectH/2 || - posx > (inFrame.w-objectW/2) || posy > (inFrame.h-objectH/2)) { - printf ("%s:%d %s find new position (last known:%d,%d)\n", - __FILE__, __LINE__, __FUNCTION__, posx, posy); + posx > (inFrame.w-objectW/2) || posy > (inFrame.h-objectH/2)) InputDetect(&posx, &posy); - } else InputDetectCrossCv2(&posx, &posy); break; default: - if (errorinputtype != inputtype) - printf ("%s:%d %s error: inputtype (%d) not found\n", __FILE__, __LINE__, __FUNCTION__, inputtype); - errorinputtype = inputtype; + if (errorinputtype != autodetecttype) + printf ("%s:%d %s error: autodetecttype (%d) not found\n", __FILE__, __LINE__, __FUNCTION__, autodetecttype); + errorinputtype = autodetecttype; break; } @@ -236,7 +234,7 @@ void Detect::InputDetect(int *posx, int *posy) { #define OBJSIZE 50 -#define MAXSHIFT 20 +#define MAXSHIFT 40 // #define DEBUGTIMES 1 void Detect::InputDetectCrossC(int *posx, int *posy) { unsigned char *pxi; // input image @@ -443,22 +441,52 @@ void Detect::InputDetectCrossCv2(int *posx, int *posy) { void Detect::SetInputType(int intype) { LockMutex(); - inputtype = intype; + autodetecttype = intype; UnLockMutex(); } +int Detect::GetInputType() { + int i; + + LockMutex(); + i = autodetecttype; + UnLockMutex(); + + return i; +} + + +// +// to set a new size we need to disable the detection for some moments. +// this will not setup any memory for te calculation buffers void Detect::SetObjectSize(int neww, int newh) { - LockImageMutex(); - LockInMutex(); + int orgtype = autodetecttype; + + // save detection type LockMutex(); + autodetecttype = -1; + UnLockMutex(); + usleep (500000); // wait 0.5 sec + + LockImageMutex(); objectH = newh; objectW = neww; + UnLockImageMutex(); + // restore orginal detection type + LockMutex(); + autodetecttype = orgtype; + UnLockMutex(); +} + + +void Detect::GetObjectSize (int *ow, int *oh) { + LockMutex(); + *ow = objectW; + *oh = objectH; UnLockMutex(); - UnLockInMutex(); - UnLockImageMutex(); } @@ -468,3 +496,17 @@ void Detect::SetMinBrightness(int value) { UnLockMutex(); } + +int Detect::GetMinBrightness() { + int i; + + LockMutex(); + i = minBright; + UnLockMutex(); + + return i; +} + + + + diff --git a/detect.h b/detect.h index 6e26005..aa7a01e 100644 --- a/detect.h +++ b/detect.h @@ -46,7 +46,7 @@ private: int objectH; // object Image Size Height int minBright; // min brightness - int inputtype; // input detection type to use + int autodetecttype; // input detection type to use void InputDetect (int *posx, int *posy); void InputDetectCrossC (int *posx, int *posy); @@ -75,8 +75,14 @@ public: // // Object functions void SetObjectSize (int neww, int newh); + void GetObjectSize (int *ow, int *oh); + void SetMinBrightness (int value); + int GetMinBrightness(); + void SetInputType(int intype); + int GetInputType(); + void GetObjectPos (int *x, int *y); void Thread(); diff --git a/gui.cc b/gui.cc index 4ed7fff..1d15e6f 100644 --- a/gui.cc +++ b/gui.cc @@ -38,7 +38,9 @@ gboolean cb_window_delete_event (GtkWidget *widget, GdkEvent *event, gpointer }; - +// +// setup default values +// void cb_window_show (GtkWidget *widget, gpointer data) { GtkWidget *btnstart = GTK_WIDGET(gtk_builder_get_object (GTK_BUILDER(_builder_), "btn-video-rec")); GtkWidget *btnstop = GTK_WIDGET(gtk_builder_get_object (GTK_BUILDER(_builder_), "btn-video-stop")); @@ -50,9 +52,9 @@ void cb_window_show (GtkWidget *widget, gpointer data) { gtk_widget_set_sensitive(btnstart, true); gtk_widget_set_sensitive(btnstop, false); - gtk_entry_set_text(GTK_ENTRY(w),"600"); - gtk_entry_set_text(GTK_ENTRY(h),"600"); - detect.SetObjectSize(600, 600); + gtk_entry_set_text(GTK_ENTRY(w),"300"); + gtk_entry_set_text(GTK_ENTRY(h),"300"); + detect.SetObjectSize(300, 300); g_timeout_add(2000, videoctrl_update, NULL); }; @@ -117,6 +119,8 @@ gboolean cb_thread_filter (gpointer data) { // this is propabely the object detection // Access to this data must be Locked before use and pointers must be looked to gboolean cb_thread_detect (gpointer data) { + GtkWidget *e_x = GTK_WIDGET(gtk_builder_get_object (GTK_BUILDER(_builder_), "detect-entry-posx")); + GtkWidget *e_y = GTK_WIDGET(gtk_builder_get_object (GTK_BUILDER(_builder_), "detect-entry-posy")); DetectOutput *dout = (DetectOutput *) data; int pix_h, pix_w; @@ -126,6 +130,9 @@ gboolean cb_thread_detect (gpointer data) { if (dout == NULL) return false; if (dout->image == NULL) return false; + gtk_entry_set_text(GTK_ENTRY(e_x), std::to_string(dout->posx).c_str()); + gtk_entry_set_text(GTK_ENTRY(e_y), std::to_string(dout->posy).c_str()); + detect.LockImageMutex(); if (detect_pixbuf) { @@ -156,6 +163,7 @@ gboolean cb_thread_detect (gpointer data) { void cb_imagetempda_draw(GtkWidget *area, cairo_t *cr, int w, int h, gpointer data) { int clientw, clienth, pixbufw, pixbufh; float clientar, pixbufar; + GdkRGBA color; GdkPixbuf *pixbuf = NULL; GdkPixbuf *src = NULL; @@ -183,13 +191,12 @@ void cb_imagetempda_draw(GtkWidget *area, cairo_t *cr, int w, int h, gpointer da gdk_cairo_set_source_pixbuf(cr, pixbuf, 0, 0); cairo_paint(cr); cairo_fill (cr); + g_object_unref (pixbuf); }; -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")); +void cb_detect_btnsetsize (GtkWidget *widget, gpointer data) { 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")); diff --git a/gui.h b/gui.h index d4eae7d..aead4af 100644 --- a/gui.h +++ b/gui.h @@ -63,7 +63,8 @@ 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_btnsetpos (GtkWidget *widget, gpointer data); +G_MODULE_EXPORT void cb_detect_btnsetsize (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 608570f..a3c3789 100644 --- a/simpleskycam.ui +++ b/simpleskycam.ui @@ -19,7 +19,7 @@ True True - 800 + 700 True True @@ -226,7 +226,7 @@ False vertical - + True False @@ -292,7 +292,7 @@ - + True True 4 @@ -356,7 +356,7 @@ - + True True 4 @@ -405,12 +405,32 @@ 5 + 0 + + + + + Set Size + True + True + True + 8 + 8 + 8 + 8 + 4 + 4 + + + + + 6 1 - - Set Object + + Set Pos True True True @@ -420,14 +440,25 @@ 8 4 4 - - + + - 5 + 6 0 + + + True + False + _ + + + 5 + 1 + + False diff --git a/video.cc b/video.cc index 5e5512f..280eac0 100644 --- a/video.cc +++ b/video.cc @@ -64,12 +64,20 @@ void videoframe_to_pixbuf(GdkPixbuf* dest, VideoFrame *src) { } +#define S_X(_x_) (((_x_) * clientw / pixbufw)) +#define S_Y(_y_) (((_y_) * clienth / pixbufh)) void cb_videoda_draw(GtkWidget *area, cairo_t *cr, int w, int h, gpointer data) { int clientw, clienth, pixbufw, pixbufh; float clientar, pixbufar; - GdkPixbuf *pixbuf = NULL; + GdkRGBA color; + GtkWidget *e_x = GTK_WIDGET(gtk_builder_get_object (GTK_BUILDER(_builder_), "detect-entry-posx")); + GtkWidget *e_y = GTK_WIDGET(gtk_builder_get_object (GTK_BUILDER(_builder_), "detect-entry-posy")); + GtkWidget *e_w = GTK_WIDGET(gtk_builder_get_object (GTK_BUILDER(_builder_), "detect-entry-w")); + GtkWidget *e_h = GTK_WIDGET(gtk_builder_get_object (GTK_BUILDER(_builder_), "detect-entry-h")); + int x, y, w1, h1; + if (video_da == NULL) return; clienth = gtk_widget_get_allocated_height(video_da); @@ -94,7 +102,49 @@ void cb_videoda_draw(GtkWidget *area, cairo_t *cr, int w, int h, gpointer data) gdk_cairo_set_source_pixbuf(cr, pixbuf, 0, 0); cairo_paint(cr); cairo_fill (cr); + g_object_unref (pixbuf); + + + // + // draw red cross + cairo_set_line_width(cr, 1.0); + color.blue = 0.0; + color.red = 1.0; + color.green = 0.0; + color.alpha = 1.0; + gdk_cairo_set_source_rgba(cr, &color); + + x = atoi (gtk_entry_get_text(GTK_ENTRY(e_x))); + y = atoi (gtk_entry_get_text(GTK_ENTRY(e_y))); + w1 = atoi (gtk_entry_get_text(GTK_ENTRY(e_w))); + h1 = atoi (gtk_entry_get_text(GTK_ENTRY(e_h))); + + cairo_move_to(cr, S_X(x), S_Y(y)-10); + cairo_line_to(cr, S_X(x), S_Y(y)+10); + cairo_move_to(cr, S_X(x)-10, S_Y(y)); + cairo_line_to(cr, S_X(x)+10, S_Y(y)); + cairo_stroke(cr); + + // + // green width border + color.blue = 0.0; + color.red = 0.0; + color.green = 1.0; + color.alpha = 1.0; + gdk_cairo_set_source_rgba(cr, &color); + + cairo_move_to(cr, S_X(x-w1/2), S_Y(y-h1/2)+10); + cairo_line_to(cr, S_X(x-w1/2), S_Y(y-h1/2)); + cairo_line_to(cr, S_X(x+w1/2), S_Y(y-h1/2)); + cairo_line_to(cr, S_X(x+w1/2), S_Y(y-h1/2)+10); + + cairo_move_to(cr, S_X(x-w1/2), S_Y(y+h1/2)-10); + cairo_line_to(cr, S_X(x-w1/2), S_Y(y+h1/2)); + cairo_line_to(cr, S_X(x+w1/2), S_Y(y+h1/2)); + cairo_line_to(cr, S_X(x+w1/2), S_Y(y+h1/2)-10); + + cairo_stroke(cr); };