Python GStreamer 网络摄像头查看器

标签 python pygtk gstreamer

我正在研究这个很好的示例,它使用 python 和 GStreamer 在 GTK 小部件中显示网络摄像头输出:

http://pygstdocs.berlios.de/pygst-tutorial/webcam-viewer.html 这是代码:

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

我想做的是有一个方法来拍摄当前帧的快照并保存到磁盘。 我认为有两种方法可以做到: - 一些 gstreamer 方法(但我认为我至少应该修改管道) - 用 GTK 本身以某种方式抓取图片

有什么提示吗? 我没有使用 gstreamer 或 gtk 的经验,非常感谢任何帮助

非常感谢 毛罗

最佳答案

感谢 OpenCV,我设法用 wxPython 重写了所有内容(我比 pyGTK 更了解它)。这是一个完整的工作示例(带有快照!),如果有人感兴趣的话。 还可以在此处查看 OpenCV wiki: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()

关于Python GStreamer 网络摄像头查看器,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/3139747/

相关文章:

c++ - 你如何在 Linux 上用 C++ 播放或录制音频(到 .WAV)?

python - Spark MinMaxScaler 在数据帧上

Python 窗口调整大小

python - pocketsphinx python gstreamer 音频速率

Python/Glade/PyGTK - Glade 标签中的下载百分比

python - 如何在 pygtk 中创建新信号

ios7 - ios 7+ 中的 GStreamer 编译错误

python - float 代表的差异

Python Lxml - 用新数据附加现有的 xml

python - 对输出文件进行 A-Z 排序