2016-06-20 56 views
0

我想拍攝300毫秒或更少的圖像。但我通過使用下面的代碼捕獲800毫秒的圖像。任何人都可以幫我解決這個問題?一直試圖這個相當長的時間,但不知道爲什麼我不能捕獲300毫秒的圖像。我使用覆盆子pi捕捉圖像。如何使用gstreamer快速捕捉圖像

import gi 
gi.require_version('Gst', '1.0') 
from gi.repository import GObject #,Gtk 
from gi.repository import Gst as gst 
class TakePhoto: 
    def __init__(self): 
    GObject.threads_init() 
    gst.init(None) 
    self.pipeline = gst.Pipeline() 
    self.video_source = gst.ElementFactory.make('v4l2src', 'video_source') 
    self.video_source.set_property("num-buffers", 1) 
    self.vconvert = gst.ElementFactory.make('videoconvert', 'vconvert') 
    self.clock = gst.ElementFactory.make('clockoverlay', 'clock') 
    self.timer= gst.ElementFactory.make('timeoverlay','timer') 
    self.vrate = gst.ElementFactory.make('videorate', 'vrate') 
    self.sconvert = gst.ElementFactory.make('videoconvert', 'sconvert') 
    self.png = gst.ElementFactory.make('jpegenc', 'png') 
    self.multi_sink = gst.ElementFactory.make('multifilesink', 'multi_sink') 

    self.caps = gst.caps_from_string ("video/x-raw,format=RGB,width=800,height=600,framerate=5/1") 
    self.timer.set_property('valignment','bottom') 
    self.timer.set_property('halignment','right') 
    self.clock.set_property('time-format','%Y/%m/%d %H:%M:%S') 
    self.clock.set_property('valignment','bottom') 
    self.caps1 = gst.caps_from_string("video/x-raw,framerate=1/1") 
    self.png.set_property('idct-method',1) 
    self.multi_sink.set_property('location','/home/pi/frame.jpeg') 
    self.filter = gst.ElementFactory.make("capsfilter", "filter") 
    self.filter.set_property("caps", self.caps) 
    self.filter1 = gst.ElementFactory.make("capsfilter", "filter1") 
    self.filter1.set_property("caps", self.caps1) 
    self.pipeline.add(self.video_source) 
    self.pipeline.add(self.vconvert) 
    self.pipeline.add(self.timer) 
    self.pipeline.add(self.clock) 
    self.pipeline.add(self.filter) 
    self.pipeline.add(self.vrate) 
    self.pipeline.add(self.filter1) 
    self.pipeline.add(self.sconvert) 
    self.pipeline.add(self.png) 
    self.pipeline.add(self.multi_sink) 
    self.video_source.link(self.filter) 
    self.filter.link(self.vconvert) 
    self.vconvert.link(self.timer) 
    self.timer.link(self.clock) 
    self.clock.link(self.vrate) 
    self.vrate.link(self.filter1) 
    self.filter1.link(self.sconvert) 
    self.sconvert.link(self.png) 
    self.png.link(self.multi_sink) 

def take_photo(self): #this is reusable 
    bus = self.pipeline.get_bus() 
    self.pipeline.set_state(gst.State.PLAYING) 
    print "Capture started" 
    msg = bus.timed_pop_filtered(gst.CLOCK_TIME_NONE,gst.MessageType.ERROR | gst.MessageType.EOS) 
    #print msg 

    self.pipeline.set_state(gst.State.READY) 
+1

RPI並不完全是CPU性能的高性能平臺。 jpeg編碼可能需要大量的CPU時間。嘗試將圖像保存爲原始位圖圖像,然後查看它是否有助於您的運行時。 –

+0

如果您始終運行程序,然後根據用戶輸入寫入JPEG,您可能會有更好的運氣。 800毫秒中的一部分將成爲啓動GStreamer,連接到v4l2等的行爲。您還可以看到v4l2src是否可以直接爲您提供jpeg(它確實具有cap/jpeg)。 – mpr

+0

@mpr你知道如何改變我的管道動態使用python? –

回答

0

什麼我建議是嘗試使用這種形式的管道:

v4l2src! videoconvert! clockoverlay!時間重疊! jpegenc! fakesink名稱=下沉take_photo

然後(),搶fakesink,訪問last-sample屬性。從樣本中提取數據並將其渲染到所需的文件。

我不知道多少時間,會給你,但至少你不會有任何的管道啓動時間和v4l2src元素將不必每次都重新訪問攝像機。

如果這樣的作品,我會再回去,並添加一個閥進入管道:

v4l2src!閥門名稱=閥門下降=真正! videoconvert! clockoverlay!時間重疊! jpegenc! fakesink name = sink

..並根據需要啓用/禁用,以在不需要屏幕截圖時減少Pi上的淨負載。

您可能還有一些事情是您正在嘗試處理造成問題的幀速率。我認爲你想以所需的分辨率以最高幀率拍攝視頻,否則可能會有內置的自然延遲,比如200ms,如果你的幀率是5/1。

+0

但我需要做動態管道,因爲我還需要做視頻。你有任何想法如何用python做到這一點,因爲我找不到任何可以用python做動態管道的源代碼。 –

+0

如果你想在stackoverflow上得到很好的幫助,你必須努力解決你的問題。除了在原始問題中進行JPEG捕捉之外,您甚至沒有提及播放視頻。我建議看看'tee'元素或執行一個單獨的進程來獲取原始視頻緩衝區並將其轉換爲jpeg。 – mpr

+0

但是最後一個示例屬性在1.0中不存在 –