From d026f1fa271a9c6e58e3543b78c3a1c1617aae05 Mon Sep 17 00:00:00 2001 From: Steffen Pohle Date: Sun, 10 Oct 2021 19:28:24 +0200 Subject: [PATCH] saving images works, basic image detection works. --- ChangeLog | 4 ++++ detect.cc | 30 ++++++++++++++++++++++++++--- gui.cc | 57 ++++++++++++++++++++++++++++++++++++++++++++++++++++++- 3 files changed, 87 insertions(+), 4 deletions(-) diff --git a/ChangeLog b/ChangeLog index 968d341..c1b3d20 100644 --- a/ChangeLog +++ b/ChangeLog @@ -1,4 +1,8 @@ +2021-10-10: +- basic object detection and image filter added +- save image works + 2021-09-21: - scaling the video to screensize works. - controls can be set via gui diff --git a/detect.cc b/detect.cc index a9f9686..66bf82a 100644 --- a/detect.cc +++ b/detect.cc @@ -30,7 +30,7 @@ Detect::Detect() { // @suppress("Class members should be properly initialized") image.SetSize(64, 64); imagegtk.SetSize(64, 64); thread = NULL; - thread = g_thread_new("Filter", _DetectThread, NULL); + thread = g_thread_new("Detect", _DetectThread, NULL); objectW = 300; objectH = 300; posmaxx = 0; @@ -112,10 +112,16 @@ void Detect::SetInputSize (int nw, int 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); @@ -124,6 +130,10 @@ void Detect::InputDetect(int *posx, int *posy) { *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; @@ -131,12 +141,20 @@ void Detect::InputDetect(int *posx, int *posy) { 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)); + 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; @@ -154,6 +172,12 @@ 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]; } +#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 } diff --git a/gui.cc b/gui.cc index e23ad07..5933bda 100644 --- a/gui.cc +++ b/gui.cc @@ -25,7 +25,7 @@ GdkPixbuf *detect_pixbuf = NULL; GtkWidget *image_da = NULL; GdkPixbuf *image_pixbuf = NULL; - +std::string filename = ""; ////////////////////////////////////////////////////////////////////////////////////////////////// // @@ -42,12 +42,18 @@ gboolean cb_window_delete_event (GtkWidget *widget, GdkEvent *event, gpointer 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")); + GtkWidget *w = GTK_WIDGET(gtk_builder_get_object (GTK_BUILDER(_builder_), "detect-entry-w")); + GtkWidget *h = GTK_WIDGET(gtk_builder_get_object (GTK_BUILDER(_builder_), "detect-entry-h")); printf ("%s:%d %s\n", __FILE__, __LINE__, __FUNCTION__); 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); + g_timeout_add(2000, videoctrl_update, NULL); }; @@ -193,9 +199,58 @@ void cb_detect_btnset (GtkWidget *widget, gpointer data) { void cb_image_btnnew (GtkWidget *widget, gpointer data) { + filter.NewImage(); }; void cb_image_btnsave (GtkWidget *widget, gpointer data) { + GtkBuilder *builder = (GtkBuilder *) data; + GtkWindow *window = GTK_WINDOW (gtk_builder_get_object (builder, "window-main")); + GtkWidget *dialog; + GtkFileChooser *chooser; + GtkFileChooserAction action = GTK_FILE_CHOOSER_ACTION_SAVE; + GtkFileFilter *filter; + gint res; + + if (image_pixbuf == NULL) return; + + dialog = gtk_file_chooser_dialog_new ("Save File", + window, + action, + "_Cancel", + GTK_RESPONSE_CANCEL, + "_Save", + GTK_RESPONSE_ACCEPT, + NULL); + chooser = GTK_FILE_CHOOSER (dialog); + + filter = gtk_file_filter_new(); + gtk_file_filter_add_pattern(filter, "*.modbus"); + gtk_file_filter_set_name(filter, "Test Modbus Config"); + gtk_file_chooser_add_filter(GTK_FILE_CHOOSER(dialog), filter); + filter = gtk_file_filter_new(); + gtk_file_filter_add_pattern(filter, "*.*"); + gtk_file_filter_set_name(filter, "All Files"); + gtk_file_chooser_add_filter(GTK_FILE_CHOOSER(dialog), filter); + + gtk_file_chooser_set_do_overwrite_confirmation (chooser, TRUE); + if (filename.length () == 0) + gtk_file_chooser_set_current_name (chooser, "capture-001.png"); + else + gtk_file_chooser_set_filename (chooser, filename.c_str()); + + res = gtk_dialog_run (GTK_DIALOG (dialog)); + + if (res == GTK_RESPONSE_ACCEPT) { + char *filename; + + filename = gtk_file_chooser_get_filename (chooser); + + gdk_pixbuf_save(image_pixbuf, filename, "png", NULL, "quality", "100", NULL); + g_free (filename); + } + + gtk_widget_destroy (dialog); }; +