2010-06-29 33 views
5

I'working trên ví dụ tốt đẹp này cho thấy một lượng webcam trong một widget GTK với trăn và GStreamer:Python GStreamer webcam xem

http://pygstdocs.berlios.de/pygst-tutorial/webcam-viewer.html đây là mã:

#!/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() 

Những gì tôi muốn thích làm là có một phương pháp để chụp nhanh khung hình hiện tại và lưu vào đĩa. Tôi nghĩ có 2 cách để làm điều đó: - một số phương pháp GStreamer (nhưng tôi nghĩ rằng tôi ít nhất nên sửa đổi các đường ống dẫn) - lấy các hình ảnh bằng cách nào đó với GTK bản thân

Bất kỳ gợi ý về vấn đề này? Tôi không có kinh nghiệm với GStreamer hoặc gtk, bất cứ sự giúp đỡ thực sự đánh giá cao

Thanks a lot Mauro

Trả lời

5

Nhờ OpenCV Tôi cố gắng viết lại tất cả mọi thứ với wxPython (mà tôi biết rõ hơn PyGTK). Đây là một ví dụ làm việc đầy đủ (whith snapshot!), Nếu có ai quan tâm. Cũng kiểm tra các wiki OpenCV ở đây: 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

bạn không trả lời câu hỏi của riêng bạn .. – elmarco

2

Tôi khá chắc chắn rằng bạn có thể làm:

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

Để có được một GtkImage với khung cuối cùng từ webcam. 500 và 400 là chiều rộng và chiều cao của cửa sổ.