2010-06-29 20 views
5

I'working auf diesem schönen Beispiel, das eine Webcam Ausgabe in einem GTK-Widget mit Python und GStreamer zeigt:Python GStreamer Webcam-Viewer

http://pygstdocs.berlios.de/pygst-tutorial/webcam-viewer.html hier ist der Code:

#!/usr/bin/env python 

import sys, os 
import pygtk, gtk, gobject 
import pygst 
pygst.require("0.10") 
import gst 

class GTK_Main: 

def __init__(self): 
    window = gtk.Window(gtk.WINDOW_TOPLEVEL) 
    window.set_title("Webcam-Viewer") 
    window.set_default_size(500, 400) 
    window.connect("destroy", gtk.main_quit, "WM destroy") 
    vbox = gtk.VBox() 
    window.add(vbox) 
    self.movie_window = gtk.DrawingArea() 
    vbox.add(self.movie_window) 
    hbox = gtk.HBox() 
    vbox.pack_start(hbox, False) 
    hbox.set_border_width(10) 
    hbox.pack_start(gtk.Label()) 
    self.button = gtk.Button("Start") 
    self.button.connect("clicked", self.start_stop) 
    hbox.pack_start(self.button, False) 
    self.button2 = gtk.Button("Quit") 
    self.button2.connect("clicked", self.exit) 
    hbox.pack_start(self.button2, False) 
    hbox.add(gtk.Label()) 
    window.show_all() 

    # Set up the gstreamer pipeline 
    self.player = gst.parse_launch ("v4l2src ! autovideosink") 

    bus = self.player.get_bus() 
    bus.add_signal_watch() 
    bus.enable_sync_message_emission() 
    bus.connect("message", self.on_message) 
    bus.connect("sync-message::element", self.on_sync_message) 

def start_stop(self, w): 
    if self.button.get_label() == "Start": 
     self.button.set_label("Stop") 
     self.player.set_state(gst.STATE_PLAYING) 
    else: 
     self.player.set_state(gst.STATE_NULL) 
     self.button.set_label("Start") 

def exit(self, widget, data=None): 
    gtk.main_quit() 

def on_message(self, bus, message): 
    t = message.type 
    if t == gst.MESSAGE_EOS: 
     self.player.set_state(gst.STATE_NULL) 
     self.button.set_label("Start") 
    elif t == gst.MESSAGE_ERROR: 
     err, debug = message.parse_error() 
     print "Error: %s" % err, debug 
     self.player.set_state(gst.STATE_NULL) 
     self.button.set_label("Start") 

def on_sync_message(self, bus, message): 
    if message.structure is None: 
     return 
    message_name = message.structure.get_name() 
    if message_name == "prepare-xwindow-id": 
     # Assign the viewport 
     imagesink = message.src 
     imagesink.set_property("force-aspect-ratio", True) 
     imagesink.set_xwindow_id(self.movie_window.window.xid) 

GTK_Main() 
gtk.gdk.threads_init() 
gtk.main() 

Was würde ich Es ist eine Methode, um einen Schnappschuss des aktuellen Rahmens zu erstellen und auf Festplatte zu speichern. Ich denke, es gibt zwei Möglichkeiten, es zu tun: - einige gstreamer-Methode (aber ich denke, ich sollte die Pipeline zumindest modifizieren) - mit GTK selbst

Jeder Hinweis auf das irgendwie das Bild greifen? ich keine Erfahrung mit gstreamer oder gtk haben, wird jede Hilfe wirklich

Vielen Dank Mauro

Antwort

5

Dank OpenCV ich es geschafft, geschätzt alles neu zu schreiben, mit wxPython (was ich besser wissen, als pyGTK). Hier ist ein vollständiges Arbeitsbeispiel (mit Schnappschuss!), Falls jemand interessiert ist. Auch die OpenCV Wiki Kasse hier: http://opencv.willowgarage.com/wiki/wxpython

import wx 
import opencv.cv as cv 
import opencv.highgui as gui 


class CvMovieFrame(wx.Frame): 
    TIMER_PLAY_ID = 101 
    def __init__(self, parent):   

     wx.Frame.__init__(self, parent, -1,)   

     sizer = wx.BoxSizer(wx.VERTICAL)   

     self.capture = gui.cvCreateCameraCapture(0) 
     frame = gui.cvQueryFrame(self.capture) 
     cv.cvCvtColor(frame, frame, cv.CV_BGR2RGB) 

     self.SetSize((frame.width + 300, frame.height + 100)) 

     self.bmp = wx.BitmapFromBuffer(frame.width, frame.height, frame.imageData) 
     self.displayPanel= wx.StaticBitmap(self, -1, bitmap=self.bmp) 
     sizer.Add(self.displayPanel, 0, wx.ALL, 10) 

     self.shotbutton = wx.Button(self,-1, "Shot") 
     sizer.Add(self.shotbutton,-1, wx.GROW) 

     self.retrybutton = wx.Button(self,-1, "Retry") 
     sizer.Add(self.retrybutton,-1, wx.GROW)  
     self.retrybutton.Hide() 

     #events 
     self.Bind(wx.EVT_BUTTON, self.onShot, self.shotbutton) 
     self.Bind(wx.EVT_BUTTON, self.onRetry, self.retrybutton) 
     self.Bind(wx.EVT_PAINT, self.onPaint) 
     self.Bind(wx.EVT_CLOSE, self.onClose) 

     self.playTimer = wx.Timer(self, self.TIMER_PLAY_ID) 
     wx.EVT_TIMER(self, self.TIMER_PLAY_ID, self.onNextFrame) 

     self.fps = 8; 
     self.SetSizer(sizer) 
     sizer.Layout() 
     self.startTimer()   

    def startTimer(self): 
     if self.fps!=0: self.playTimer.Start(1000/self.fps)#every X ms 
     else: self.playTimer.Start(1000/15)#assuming 15 fps   

    def onRetry(self, event): 
     frame = gui.cvQueryFrame(self.capture) 
     cv.cvCvtColor(frame, frame, cv.CV_BGR2RGB) 
     self.bmp = wx.BitmapFromBuffer(frame.width, frame.height, frame.imageData) 
     self.startTimer() 
     self.shotbutton.Show() 
     self.retrybutton.Hide() 
     self.hasPicture = False 
     self.Layout() 
     event.Skip()  

    def onShot(self, event): 
     frame = gui.cvQueryFrame(self.capture) 
     self.playTimer.Stop() 
     gui.cvSaveImage("foo.png", frame)   

     self.hasPicture = True 
     self.shotbutton.Hide() 
     self.retrybutton.Show() 
     self.Layout() 
     event.Skip() 

    def onClose(self, event): 
     try: 
      self.playTimer.Stop() 
     except: 
      pass 

     self.Show(False) 
     self.Destroy()  

    def onPaint(self, evt): 
     if self.bmp: 
      self.displayPanel.SetBitmap(self.bmp) 
     evt.Skip() 

    def onNextFrame(self, evt): 

     frame = gui.cvQueryFrame(self.capture) 
     if frame: 
      cv.cvCvtColor(frame, frame, cv.CV_BGR2RGB) 
      self.bmp = wx.BitmapFromBuffer(frame.width, frame.height, frame.imageData) 
      self.Refresh()   
     evt.Skip() 

if __name__=="__main__": 
    app = wx.App() 
    f = CvMovieFrame(None) 
    f.Centre() 
    f.Show(True) 
    app.MainLoop() 
+6

Sie beantworten nicht Ihre eigene Frage .. – elmarco

2

Ich bin ziemlich sicher, dass Sie tun können:

self.movie_window.window.get_image(0, 0, 500, 400) 

Um einen GtkImage mit dem letzten Bild von der Webcam zu erhalten. Die 500 und 400 ist die Breite und die Höhe des Fensters.