adding histogram

master
Steffen Pohle 3 years ago
parent f26d9e7396
commit 1877e5951c

@ -7,7 +7,8 @@ APP = simpleskycam
OBJECTS := $(OBJECTS) gui.oo main.oo \ OBJECTS := $(OBJECTS) gui.oo main.oo \
video.oo videoframe.oo \ video.oo videoframe.oo \
videodev.oo videodev-v4l2.oo videodev-dumpfile.oo \ videodev.oo videodev-v4l2.oo videodev-dumpfile.oo \
convert.oo filter.oo detect.oo json.oo configuration.oo ser.oo dng.oo convert.oo filter.oo detect.oo histogram.oo \
json.oo configuration.oo ser.oo dng.oo
DISTNAME=simpleskycam-$(VERSION) DISTNAME=simpleskycam-$(VERSION)
DEPENDFILE=.depend DEPENDFILE=.depend

@ -62,10 +62,11 @@ void cb_window_show (GtkWidget *widget, gpointer data) {
GtkWidget *win_detect = GTK_WIDGET(gtk_builder_get_object (GTK_BUILDER(_builder_), "window-detect")); GtkWidget *win_detect = GTK_WIDGET(gtk_builder_get_object (GTK_BUILDER(_builder_), "window-detect"));
GtkWidget *win_input = GTK_WIDGET(gtk_builder_get_object (GTK_BUILDER(_builder_), "window-input")); GtkWidget *win_input = GTK_WIDGET(gtk_builder_get_object (GTK_BUILDER(_builder_), "window-input"));
GtkWidget *win_output = GTK_WIDGET(gtk_builder_get_object (GTK_BUILDER(_builder_), "window-output")); GtkWidget *win_output = GTK_WIDGET(gtk_builder_get_object (GTK_BUILDER(_builder_), "window-output"));
GtkWidget *win_histogram = GTK_WIDGET(gtk_builder_get_object (GTK_BUILDER(_builder_), "window-histogram"));
gtk_widget_show (win_detect); gtk_widget_show (win_detect);
gtk_widget_show (win_input); gtk_widget_show (win_input);
gtk_widget_show (win_output); gtk_widget_show (win_output);
gtk_widget_show (win_histogram);
// changing the value, will cause the 'change' event to be triggered // changing the value, will cause the 'change' event to be triggered
gtk_toggle_button_set_active(GTK_TOGGLE_BUTTON(rboff), true); gtk_toggle_button_set_active(GTK_TOGGLE_BUTTON(rboff), true);

@ -98,6 +98,12 @@ G_MODULE_EXPORT void cb_detect_btnsetsize (GtkWidget *widget, gpointer data);
G_MODULE_EXPORT void cb_detect_followtype (GtkWidget *widget, gpointer data); G_MODULE_EXPORT void cb_detect_followtype (GtkWidget *widget, gpointer data);
G_MODULE_EXPORT void cb_detect_detecttype (GtkWidget *widget, gpointer data); G_MODULE_EXPORT void cb_detect_detecttype (GtkWidget *widget, gpointer data);
//
// histogram elements
G_MODULE_EXPORT void cb_histogramda_draw(GtkWidget *area, cairo_t *cr, int w, int h, gpointer data);
#ifdef __cplusplus #ifdef __cplusplus
} }
#endif #endif

@ -0,0 +1,173 @@
/***************************************************************************************
*
* histogram.cc is part of SimpleSkyCam.
*
*****************************************************************************************/
#include "simpleskycam.h"
#include "histogram.h"
#include "gui.h"
#include "configuration.h"
#include "video.h"
GtkWidget *histogram_da = NULL;
GdkPixbuf *histogram_pixbuf = NULL;
int *hist_minmax = NULL; // 2* hist_width min, max, min , max.....
int hist_width = 0;
extern GtkBuilder *_builder_; // work around for threads
#define S_X(_x_) (((_x_) * clientw / pixbufw))
#define S_Y(_y_) (((_y_) * clienth / pixbufh))
void cb_histogramda_draw(GtkWidget *area, cairo_t *cr, int w, int h, gpointer data) {
int clientw, clienth, pixbufw, pixbufh;
GdkRGBA color;
if (histogram_da == NULL) // should only be called once
histogram_da = GTK_WIDGET(gtk_builder_get_object (GTK_BUILDER(_builder_), "histogram-da"));
//
// create or resize pixbuf if needed
clienth = gtk_widget_get_allocated_height(histogram_da);
clientw = gtk_widget_get_allocated_width(histogram_da);
if (histogram_pixbuf == NULL) {
histogram_pixbuf = gdk_pixbuf_new (GDK_COLORSPACE_RGB, false, 8, clientw, clienth);
memset (gdk_pixbuf_get_pixels(histogram_pixbuf), 0, 3 * gdk_pixbuf_get_height(histogram_pixbuf) * gdk_pixbuf_get_width(histogram_pixbuf));
}
pixbufh = gdk_pixbuf_get_height(histogram_pixbuf);
pixbufw = gdk_pixbuf_get_width(histogram_pixbuf);
if (pixbufw != clientw || pixbufh != clienth) {
g_object_unref(histogram_pixbuf);
histogram_pixbuf = gdk_pixbuf_new (GDK_COLORSPACE_RGB, false, 8, clientw, clienth);
memset (gdk_pixbuf_get_pixels(histogram_pixbuf), 0, 3 * gdk_pixbuf_get_height(histogram_pixbuf) * gdk_pixbuf_get_width(histogram_pixbuf));
}
//
// put the drawing area on the screen
gdk_cairo_set_source_pixbuf(cr, histogram_pixbuf, 0, 0);
cairo_paint(cr);
cairo_fill (cr);
//
// draw cross
color.blue = 1.0;
color.red = 0.0;
color.green = 1.0;
color.alpha = 1.0;
gdk_cairo_set_source_rgba(cr, &color);
cairo_move_to(cr, 0, 0);
cairo_line_to(cr, pixbufw, pixbufh);
cairo_move_to(cr, pixbufw, 0);
cairo_line_to(cr, 0, pixbufh);
cairo_stroke(cr);
//
// draw basic histogram
if (hist_minmax != NULL) {
//
// draw cross
color.blue = 0.75;
color.red = 0.75;
color.green = 0.75;
color.alpha = 0.8;
gdk_cairo_set_source_rgba(cr, &color);
int x, i; // position in histogram
int px, py1, py2; // screen pos x and line from to
for (i = 0, x = 0; x < hist_width; x++) {
px = (pixbufw * x) / hist_width;
py1 = (pixbufh * hist_minmax[i++]) / 255;
py2 = (pixbufh * hist_minmax[i++]) / 255;
cairo_move_to(cr, px, py1);
cairo_line_to(cr, px, py2);
cairo_stroke(cr);
}
}
// draw some text
for (int i = 0; i < 5; i++) {
int dx, dy;
switch (i) {
case 0:
cairo_set_source_rgb(cr, 1.0, 1.0, 1.0);
dx = -1;
dy = 0;
break;
case 1:
dx = +1;
dy = 0;
break;
case 2:
dx = 0;
dy = -1;
break;
case 3:
dx = 0;
dy = +1;
break;
case 4:
cairo_set_source_rgb(cr, 0.1, 0.1, 0.1);
dx = 0;
dy = 0;
break;
}
cairo_select_font_face (cr, "sans-serif", CAIRO_FONT_SLANT_NORMAL, CAIRO_FONT_WEIGHT_BOLD);
cairo_set_font_size (cr, 12);
cairo_move_to (cr, 10+dx, 15+dy);
cairo_show_text(cr, "Test");
cairo_stroke(cr);
}
};
/*
* test function
*/
void histogram_update(VideoFrame *vf) {
int i, x, y, min, max, v;
if (vf == NULL) return;
if (vf->w <= 0 ) return;
if (hist_minmax == NULL ) {
hist_minmax = (int*) malloc (2 * sizeof(int) * vf->w);
hist_width = vf->w;
}
if (hist_width != vf->w) {
free (hist_minmax);
hist_minmax = (int*) malloc (2 * sizeof(int) * vf->w);
hist_width = vf->w;
}
for (i = 0, x = 0; x < vf->w; x++) {
for (y = 0; y < vf->h; y++) {
v = (vf->data[3*y*vf->w+x + 0] +
vf->data[3*y*vf->w+x + 1] +
vf->data[3*y*vf->w+x + 2]) / 3;
if (y == 0) {
min = v;
max = v;
}
if (v < min) min = v;
if (v > max) max = v;
}
hist_minmax[i++] = min;
hist_minmax[i++] = max;
}
if (histogram_da)
gdk_window_invalidate_rect(gtk_widget_get_window(histogram_da), NULL, true);
};

@ -0,0 +1,21 @@
/***************************************************************************************
*
* histogram.h is part of SimpleSkyCam.
*
***************************************************************************************/
#ifndef _HISTOGRAM_H_
#define _HISTOGRAM_H_
#include <string>
#include <list>
#include <stdint.h>
#include "gui.h"
#include "config.h"
#include "videoframe.h"
void histogram_update(VideoFrame *vf);
#endif // _HISTOGRAM_H_

@ -11,6 +11,7 @@
</object> </object>
<object class="GtkWindow" id="window-detect"> <object class="GtkWindow" id="window-detect">
<property name="can-focus">False</property> <property name="can-focus">False</property>
<property name="title" translatable="yes">Detect</property>
<property name="default-width">440</property> <property name="default-width">440</property>
<property name="default-height">250</property> <property name="default-height">250</property>
<child> <child>
@ -447,8 +448,20 @@
</object> </object>
</child> </child>
</object> </object>
<object class="GtkWindow" id="window-histogram">
<property name="can-focus">False</property>
<property name="title" translatable="yes">Histogram</property>
<child>
<object class="GtkDrawingArea" id="histogram-da">
<property name="visible">True</property>
<property name="can-focus">False</property>
<signal name="draw" handler="cb_histogramda_draw" swapped="no"/>
</object>
</child>
</object>
<object class="GtkWindow" id="window-input"> <object class="GtkWindow" id="window-input">
<property name="can-focus">False</property> <property name="can-focus">False</property>
<property name="title" translatable="yes">Input</property>
<property name="default-width">400</property> <property name="default-width">400</property>
<property name="default-height">300</property> <property name="default-height">300</property>
<child> <child>
@ -665,6 +678,11 @@
<property name="can-focus">False</property> <property name="can-focus">False</property>
<property name="has-entry">True</property> <property name="has-entry">True</property>
<signal name="changed" handler="cb_video_cbox_videodev" swapped="no"/> <signal name="changed" handler="cb_video_cbox_videodev" swapped="no"/>
<child internal-child="entry">
<object class="GtkEntry">
<property name="can-focus">False</property>
</object>
</child>
</object> </object>
<packing> <packing>
<property name="expand">False</property> <property name="expand">False</property>
@ -767,6 +785,11 @@
<item translatable="yes">800x600</item> <item translatable="yes">800x600</item>
<item translatable="yes">640x480</item> <item translatable="yes">640x480</item>
</items> </items>
<child internal-child="entry">
<object class="GtkEntry">
<property name="can-focus">False</property>
</object>
</child>
</object> </object>
<packing> <packing>
<property name="expand">False</property> <property name="expand">False</property>
@ -796,6 +819,11 @@
<item translatable="yes">YUYV</item> <item translatable="yes">YUYV</item>
<item translatable="yes">RGB4</item> <item translatable="yes">RGB4</item>
</items> </items>
<child internal-child="entry">
<object class="GtkEntry">
<property name="can-focus">False</property>
</object>
</child>
</object> </object>
<packing> <packing>
<property name="expand">False</property> <property name="expand">False</property>
@ -959,6 +987,7 @@
</object> </object>
<object class="GtkWindow" id="window-output"> <object class="GtkWindow" id="window-output">
<property name="can-focus">False</property> <property name="can-focus">False</property>
<property name="title" translatable="yes">Output</property>
<property name="default-width">400</property> <property name="default-width">400</property>
<property name="default-height">300</property> <property name="default-height">300</property>
<child> <child>

@ -15,7 +15,7 @@
#include "configuration.h" #include "configuration.h"
#include "video.h" #include "video.h"
#include "videodev.h" #include "videodev.h"
#include "histogram.h"
VideoDev *videodev = NULL; VideoDev *videodev = NULL;
GThread *videodev_thread = NULL; GThread *videodev_thread = NULL;
@ -535,6 +535,7 @@ gboolean cb_thread_video (gpointer data) {
} }
vf->ToPixbuf(video_pixbuf); // convert Frame to pixeldata vf->ToPixbuf(video_pixbuf); // convert Frame to pixeldata
histogram_update(vf); // update histogram
detect.NewFrame(vf); // push new data to detect object detect.NewFrame(vf); // push new data to detect object
videodev->UnLockMutex(); videodev->UnLockMutex();

Loading…
Cancel
Save