2016-10-30 10 views
1

正如標題所示,我正在從我的攝像頭讀取幀(使用openCV,我想跟隨它進行一些跟蹤功能檢測),並且想要將結果寫入pyGTK3 DrawableArea小部件。繼this答案,我將引用爲了方便:從網絡攝像頭畫框到pygtk3的DrawableArea時的分段錯誤

下,似乎做的工作:

def draw(self, widget, context): 
    Gdk.cairo_set_source_pixbuf(context, self.pixbuf, 0, 0) 
    context.paint() 

一個問題仍然存在:這是做事的最佳方式是什麼?

所以我現在使用:

def _on_drawablearea_draw(self, canvas, context): 
    frame = self.stream.read() 
    self.pixbuf = self._frame2pixbuf(frame) 
    Gdk.cairo_set_source_pixbuf(context, self.pixbuf, 0, 0) 
    context.paint() 

def _frame2pixbuf(self, frame): 
    height, width, rgb_stride = frame.shape 
    frame_to_list = frame.flatten() # must become list 
    return GdkPixbuf.Pixbuf.new_from_data(frame_to_list, 
              GdkPixbuf.Colorspace.RGB, 
              False, 8, 
              width, height, rgb_stride * width) 

frame是形狀(m,n,3)的numpy的陣列。

不幸的是,我在發言得到了segmentation fault

Gdk.cairo_set_source_pixbuf(context, self.pixbuf, 0, 0) 

這apparantly發生如被看見在評論上述引用的答案,提供的卻沒有解決方案和快速谷歌搜索產生了更多的成員沒有結果。

更新1:從文件加載PIXBUF按預期方式工作,即

def _image2pixbuf(self): 
    filename = 'some_test_image.jpg' 
    return GdkPixbuf.Pixbuf.new_from_file(filename) 

與除了改變._image2pixbuf同一呼叫到_on_drawablearea_draw在DrawableArea插件呈現some_test_image.jpg完美。

更新2:轉換爲字節,創建從字節PIXBUF中爲我的作品,即

def _frame2pixbuf(self, frame): 
    height, width, rgb_stride = frame.shape 
    frame_in_bytes = GLib.Bytes.new(frame.tobytes()) 
    return GdkPixbuf.Pixbuf.new_from_bytes(frame_in_bytes, 
              GdkPixbuf.Colorspace.RGB, 
              False, 8, 
              width, height, rgb_stride * width) 

,但它增加了一個「不必要」額外的幀數據轉換成字節的步驟(?)。

問題

  1. 如何解決在GdkPixbuf.Pixbuf.new_from_data的情況下,該段錯誤?現在看來,這個功能的論點被嚴重挑選出來了。

  2. 此外,正如上面引用的答案還問:這是從網絡攝像頭寫一個框架到DrawableArea小部件的首選方式?

回答

0

要回答你的第一個問題,這個問題是new_from_data()不會使您傳遞給它的圖像數據的副本,它直接使用它,你的情況的圖像數據被包含在frame_in_bytes變量這是_frame2pixbuf函數的本地特性。因此,該圖像數據很可能會被釋放,並且在您退出_frame2pixbuf功能範圍後不再有效。

當您使用分配圖像內存本身的new_from_file函數時,情況並非如此;也不適用於new_from_bytes,因爲您在堆上創建了一個新的Bytes對象,當您離開函數作用域時,該對象不會被釋放。

要使用new_from_data(),您必須確保在調用Gdk.cairo_set_source_pixbuf()之前,圖像數據不會失效。我認爲一種方法是將_frame2pixbuf函數的內容放入_on_drawablearea_draw函數中,以便frame_in_bytes var在該上下文中保持有效。