From 41146c8902beeefb1cc166c612d5d7f855848c08 Mon Sep 17 00:00:00 2001 From: Benjamin Franzke Date: Fri, 25 May 2012 08:28:48 +0200 Subject: cvg: Add simple webcam capture --- cvg.c | 123 +++++++++++++++++++++++++++++++++++++++++++++++++++++++++++------- 1 file changed, 110 insertions(+), 13 deletions(-) diff --git a/cvg.c b/cvg.c index 293c2b1..da2062b 100644 --- a/cvg.c +++ b/cvg.c @@ -9,11 +9,15 @@ struct cvg { GtkWidget *drawing_area2; GtkButton *gauss_btn; GtkButton *open_btn; + CvCapture *capture; IplImage *image; IplImage *output; cairo_surface_t *input_surface; cairo_surface_t *output_surface; guint last_press; + int idle_source; + + IplImage *(*filter)(struct cvg *cvg, IplImage *image); }; static cairo_surface_t * @@ -100,6 +104,64 @@ destroy_images(struct cvg *cvg) cvg->output_surface = NULL; } +static void +update_right_drawing_area(struct cvg *cvg) +{ + if (!cvg->image) + return; + + if (cvg->output) + cvReleaseImage(&cvg->output); + + cvg->output = cvg->filter(cvg, cvg->image); + + if (cvg->output_surface) + cairo_surface_destroy(cvg->output_surface); + cvg->output_surface = NULL; + if (cvg->output) + cvg->output_surface = + cairo_surface_create_from_ipl_image(cvg->output); + gtk_widget_queue_draw(cvg->drawing_area2); +} + +static gboolean +capture(gpointer userdata) +{ + struct cvg *cvg = userdata; + IplImage *image; + + image = cvQueryFrame(cvg->capture); + if (!image) { + fprintf(stderr, "ERROR: frame is null...\n"); + exit(EXIT_FAILURE); + } + + if (cvg->image) + cvReleaseImage(&cvg->image); + if (cvg->input_surface) + cairo_surface_destroy(cvg->input_surface); + + cvg->image = cvCreateImage(cvSize(image->width, image->height), + image->depth, image->nChannels); + cvCopy(image, cvg->image, NULL); + if (!cvg->image) + return FALSE; + cvg->input_surface = cairo_surface_create_from_ipl_image(cvg->image); + gtk_widget_queue_draw(cvg->drawing_area1); + update_right_drawing_area(cvg); + + return TRUE; +} + +static void +stop_capture(struct cvg *cvg) +{ + if (cvg->idle_source) { + g_source_remove(cvg->idle_source); + cvg->idle_source = 0; + } +} + gboolean key_event(GtkWidget *widget, GdkEventKey *event, gpointer userdata) { @@ -136,6 +198,15 @@ key_event(GtkWidget *widget, GdkEventKey *event, gpointer userdata) gtk_widget_queue_draw(cvg->drawing_area1); gtk_widget_queue_draw(cvg->drawing_area2); break; + case GDK_KEY_s: + case GDK_KEY_S: + stop_capture(cvg); + break; + case GDK_KEY_c: + case GDK_KEY_C: + if (!cvg->idle_source) + cvg->idle_source = g_idle_add(capture, cvg); + break; case GDK_KEY_q: gtk_main_quit(); break; @@ -166,32 +237,40 @@ file_set(GtkFileChooserButton *widget, gpointer userdata) struct cvg *cvg = userdata; gchar *filename; + stop_capture(cvg); + filename = gtk_file_chooser_get_filename(GTK_FILE_CHOOSER(widget)); open_file(cvg, filename); g_free(filename); gtk_widget_queue_draw(cvg->drawing_area1); + update_right_drawing_area(cvg); } -void -on_gauss_button_click(GtkButton *button, gpointer userdata) +static IplImage * +gauss_filter(struct cvg *cvg, IplImage *image) { - struct cvg *cvg = userdata; + IplImage *output; - if (!cvg->image) - return; + output = cvCreateImage(cvGetSize(image), IPL_DEPTH_8U, 3); + cvSmooth(image, output, CV_GAUSSIAN, 9, 9, 0, 0); - if (cvg->output) - cvReleaseImage(&cvg->output); + return output; +} - cvg->output = cvCreateImage(cvGetSize(cvg->image), IPL_DEPTH_8U, 3); - cvSmooth(cvg->image, cvg->output, CV_GAUSSIAN, 9, 9, 0, 0); +static IplImage * +none_filter(struct cvg *cvg, IplImage *image) +{ + return NULL; +} - if (cvg->output_surface) - cairo_surface_destroy(cvg->output_surface); - cvg->output_surface = cairo_surface_create_from_ipl_image(cvg->output); +void +on_gauss_button_click(GtkButton *button, gpointer userdata) +{ + struct cvg *cvg = userdata; - gtk_widget_queue_draw(cvg->drawing_area2); + cvg->filter = gauss_filter; + update_right_drawing_area(cvg); } void @@ -216,6 +295,7 @@ main(int argc, char *argv[]) GtkBuilder *builder; GObject *file_chooser; gchar *path, *file; + int index = 0; memset(&cvg, 0, sizeof cvg); gtk_init(&argc, &argv); @@ -223,6 +303,21 @@ main(int argc, char *argv[]) if (argc >= 2) open_file(&cvg, argv[argc-1]); + cvg.capture = cvCreateCameraCapture(index); + if (!cvg.capture) { + fprintf(stderr, "ERROR: capture is NULL \n"); + exit(EXIT_FAILURE); + } + +#if 1 + cvSetCaptureProperty(cvg.capture, CV_CAP_PROP_FRAME_WIDTH, 10000); + cvSetCaptureProperty(cvg.capture, CV_CAP_PROP_FRAME_HEIGHT, 10000); +#endif + + printf("width: %.f, height: %.f\n", + cvGetCaptureProperty(cvg.capture, CV_CAP_PROP_FRAME_WIDTH), + cvGetCaptureProperty(cvg.capture, CV_CAP_PROP_FRAME_HEIGHT)); + builder = gtk_builder_new(); path = g_path_get_dirname(argv[0]); file = g_build_filename(path, "cvg.ui", NULL); @@ -245,6 +340,8 @@ main(int argc, char *argv[]) gtk_container_forall(GTK_CONTAINER(file_chooser), find_button, &cvg.open_btn); + cvg.idle_source = g_idle_add(capture, &cvg); + cvg.filter = none_filter; gtk_widget_show_all(GTK_WIDGET(gtk_builder_get_object(builder, "win"))); g_object_unref(builder); gtk_main(); -- cgit