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; }
PS: Ich habe dieses Thema schonmal gepostet. Allerdings in das Forum "ANSI C" und habe jetzt festgestellt, dass es hierher besser passt. Wäre ein Moderator so lieb den anderen Thread zu löschen? Danke.
-
Wenn es nur darum geht beim ersten Capturen zwei Bilder auszulesen:
void ocv_grab_frame() { // snip if(!cvGrabFrame(capture)) // snip else { // snip static bool notFirstRun = false; if (! notFirstRun) // nur beim ersten Durchlauf erfüllt .... { // Bild auslesen und verwerfen ... notFirstRun = true; } // normal auslesen } } }
Ich hatte soetwas ähnliches beim einem USB Video Grabber ... der hat immer ein Bild gepuffert und musste ähnlich "gelöscht" werden
-
Wie einfach doch die Lösung ist, wenn man mal genau weiß was das Problem ist
Ich stand diesbezüglich etwas aufem SchlauchTausend Dank!
-
Dann editier doch den Beitragstitel als "[gelöst] OpenCV + Gtk - Framegrabbing (Problem)"
-
Würd ich ja gern
Aber ich hab mich nicht registriert, und kann deswegen meinen Post nichtmehr ändern....Sry