OpenCV + Gtk - Framegrabbing (Problem)
-
Hey leute!
Ich bin derzeit daran, ein Programm zu schreiben, dass per Knopfdruck die (USB-)Kamera initialisiert und per weiterer Knopfdruck ein Bild von der Kamera holt, dieses anzeigt und abspeichert.
Dank Opensourceprojekte (OpenCV + Gtk) lässt sich dies recht einfach realisieren. Quellcode siehe unten.
Jetzt zu meinem Problem: Wenn ich die Kamera initialisiere, grabbt das Programm schon ein Frame. Zumindest vermute ich das. Denn wenn ich dann die Funktion aufrufe, die eigentlich genau zu diesem Zeitpunkt ein Frame grabben soll, zeigt mir das Programm das Bild an, bei der die Kamera bei der initialisierungsphase war.
Und wenn ich nochmal ein Frame grabbe, dann zeigt es mir das Bild an dass ich zuvor aufgenommen habe....Ich hoffe ihr versteht mein Problem, und könnt mir vllt. noch den ein oder anderen Tipp geben (bin selber noch Neuling und es is das erste Projekt dieser Art).
#include <stdlib.h> #include <windows.h> #include <gtk/gtk.h> #include <gdk-pixbuf/gdk-pixbuf.h> #include <cv.h> // OpenCV #include <highgui.h> // OpenCV-Highgui /* Eventuelle Variablen deklarieren */ GtkWidget *fenster; GtkWidget *button0, *button1, *button2; GtkWidget *hbox, *vbox; GtkWidget *aspect_frame; GtkWidget *drawing_area; CvCapture *capture = NULL; IplImage *frame; IplImage* rgbImage; GdkPixbuf *pix; void ocv_init_cam() { /* Kamera initialisieren */ capture = cvCaptureFromCAM(0); //Kamera-Index: 0 if(!capture) { g_print("Initialisierung der Kamera fehlgeschlagen!"); } } void ocv_grab_frame() { g_print("Funktion aufgerufen!\n\n"); if(capture) // Kamera initialisiert? { if(!cvGrabFrame(capture)) { g_print("Kein Bild aufgenommen!\n"); } else { g_print("Bild aufgenommen! \n"); frame = cvRetrieveFrame(capture, 0); cvSaveImage("bild.jpg", frame,0); rgbImage = cvCloneImage(frame); cvCvtColor( frame, rgbImage, CV_BGR2RGB ); // Usually opencv image is BGR, so we need to change it to RGB pix = gdk_pixbuf_new_from_data ((guchar*)rgbImage->imageData, GDK_COLORSPACE_RGB, FALSE, rgbImage->depth, rgbImage->width, rgbImage->height, (rgbImage->widthStep), NULL, NULL); } } } void ende(GtkObject *object) { cvReleaseCapture(&capture); gtk_main_quit(); } gboolean expose_event_callback (GtkWidget *widget, GdkEventExpose *event, gpointer data) { if(rgbImage != 0) // Frame aufgenommen? { gtk_widget_queue_draw(GTK_WIDGET(widget)); gdk_draw_pixbuf (widget->window, widget->style->fg_gc[GTK_WIDGET_STATE (widget)], pix, 0, 0, 0, 0, 320, 240, GDK_RGB_DITHER_MAX, 0, 0 ); } else // wenn nicht -> schwarzes Rechteck als Platzhalter { gtk_widget_queue_draw(GTK_WIDGET(widget)); gdk_draw_rectangle(widget->window,widget->style->fg_gc[GTK_WIDGET_STATE (widget)], TRUE, 0,0,320,240); } return TRUE; } int WINAPI WinMain (HINSTANCE hThisInstance, HINSTANCE hPrevInstance, LPSTR lpszArgument, int nFunsterStil) { /*GTK initialisieren - Anfang */ g_log_set_handler ("Gtk", G_LOG_LEVEL_WARNING, (GLogFunc) gtk_false, NULL); gtk_init (&_argc, &_argv); g_log_set_handler ("Gtk", G_LOG_LEVEL_WARNING, g_log_default_handler, NULL); /*GTK initialisieren - Ende */ // Ein neues Fenster erstellen fenster = gtk_window_new(GTK_WINDOW_TOPLEVEL); // Horizontaler Container hbox = gtk_hbox_new(TRUE, 0); // Vertikaler Container vbox = gtk_vbox_new(TRUE, 0); //Buttons erstellen button0 = gtk_button_new_with_label("Kamera initialisieren!"); button1 = gtk_button_new_with_label("Frame grabben"); button2 = gtk_button_new_with_label("Exit"); /* Create an aspect_frame*/ aspect_frame = gtk_aspect_frame_new ("1x1", /* label */ 0.5, /* center x */ 0.5, /* center y */ 1, /* xsize/ysize = 2 */ FALSE /* ignore child's aspect */); drawing_area = gtk_drawing_area_new (); gtk_widget_set_size_request (drawing_area, 320, 240); // Signale registrieren gtk_signal_connect(GTK_OBJECT(fenster), "destroy", GTK_SIGNAL_FUNC(ende),NULL); gtk_signal_connect(GTK_OBJECT(button2), "clicked", GTK_SIGNAL_FUNC(ende), GTK_OBJECT(fenster)); gtk_signal_connect(GTK_OBJECT(button0), "clicked", GTK_SIGNAL_FUNC(ocv_init_cam), NULL); gtk_signal_connect(GTK_OBJECT(button1), "clicked", GTK_SIGNAL_FUNC(ocv_grab_frame), NULL); gtk_signal_connect (GTK_OBJECT (drawing_area), "expose_event", G_CALLBACK (expose_event_callback), NULL); gtk_window_set_title(GTK_WINDOW(fenster), "GTK mit OpenCV!"); gtk_window_set_default_size(GTK_WINDOW(fenster), 800, 400); gtk_window_set_position(GTK_WINDOW(fenster),GTK_WIN_POS_CENTER); gtk_container_set_border_width(GTK_CONTAINER(fenster),25); //Nun alles in die Box... gtk_box_pack_start(GTK_BOX(vbox), button0, FALSE, FALSE, 0); gtk_box_pack_start(GTK_BOX(vbox), button1, FALSE, FALSE, 0); gtk_box_pack_start(GTK_BOX(vbox), button2, FALSE, FALSE, 0); gtk_box_pack_start(GTK_BOX(hbox), vbox, FALSE, FALSE, 20); gtk_box_pack_start(GTK_BOX(hbox), drawing_area, FALSE, FALSE, 0); gtk_box_pack_start(GTK_BOX(drawing_area), aspect_frame, FALSE, FALSE, 0); //Container(-box) in das Fenster einfügen gtk_container_add(GTK_CONTAINER(fenster),hbox); //Zeig uns... gtk_widget_show_all(fenster); gtk_main(); return 0; }
-
Ansi C?
-
Also wenn ich mir die Funktion ocv_grab_frame() anschaue dann muss auch bei cvSaveImage("bild.jpg", frame,0); dein aktuelles Image rauskommen.
Du könntest jedoch wenn Du zweifel an der initialisierung hast capture = cvCreateCameraCapture(0); testen.