2016-05-16 223 views
1

我有一個我在Python中編寫的GUI應用程序,我試圖在Qt應用程序中顯示視頻。試圖在QGraphicsScene和QGraphicsView中顯示opencv視頻,但沒有顯示

它使用QGraphicsScene和QGraphicsView來顯示圖像,但現在我必須顯示一個視頻。當我嘗試在這裏顯示視頻時,我是這樣做的:

首先,我從cv2包創建VideoCapture。之後,我運行循環並在每次迭代中讀取幀,然後將其輸入到QPixmap中(這是正確的,我檢查了一個幀)。我將該QPixmap對象返回給包含QGraphicsScene和QGraphicsView的類,並嘗試將其添加到場景中。

事情是,只有當視頻結束時,顯示的最後一幀,整個視頻播放時間,我這個瞄準

A blank non responsive screen

我前面提到看起來像這樣的循環:歡迎

self.imageViewer.start_capturing() 
    self.timer = QtCore.QTimer() 
    self.fps = 24 

    while True: 
     retVal = self.imageViewer.read_frame() 
     if not retVal: 
      self.timer.stop() 
      break 
     self.timer.start(1000./self.fps) 
    self.imageViewer.stop_capturing() 

self.ImageViewer是保持QGraphicsScene和的QGraphicsView 我也把計時器在這裏,以便它顯示FPS的正確ammount的,但它並不能幫助一個組成部分。

的GUI應用程序本身顯示的QGraphicsView一些按鈕

middleLayout.addWidget(self.imageViewer.view) 

這就是我的意思。所以它不顯示imageViewer,但它顯示了QGraphicsView的子類

以下是ImageViewer類中read_frame方法的代碼。

def read_frame(self): 
    """ 
    Reads a frame from the video, if video ended, then False is returned. 
    If there is a successful reading then True is returned 
    :return: True if video is read successfully, False otherwise. 
    """ 
    retVal, self.current_frame = self.capture.getFrame() 
    if not retVal: 
     return False 
    else: 
     self.pixmap = retVal 
     self.scene.addPixmap(self.pixmap) 
     return True 

方法self.capture.getFrame()只是返回QPixmap項目和CV :: mat項目。

這整個過程是正確完成的,因爲我試圖手動逐幀閱讀並一切正常,但是當我嘗試顯示視頻時,應用程序凍結,如上圖所示。所以我手動嘗試通過手動點擊一個按鈕來完成整個描述的過程,該按鈕加載我的框架並將其放到QGraphicsScene中,因此我假定該應用程序的核心工作正常(我甚至試圖通過單擊獲得大約5-7 fps快:D)

我希望我明確了我的問題,幷包括所需的所有代碼。

回答

1

我認爲你的計時邏輯是錯誤的..你沒有正確使用計時器..你可以使用connect或者你可以使用睡眠。

我會做這樣的事情:

def grabFrame 
    retVal = self.imageViewer.read_frame() 
    if not retVal: 
     self.timer.stop() 
     self.imageViewer.stop_capturing() 
在你的主邏輯

而且某處或你的一些類的初始化函數:

yourObject.connect(timer,SIGNAL("timeout()"),yourObject,SLOT("grabFrame()")) 
timer.start(1000./self.fps)  

或者你可以用某種時間模塊的睡眠之後

import time 
... 
while True: 
    retVal = self.imageViewer.read_frame() 
    if not retVal: 
     break 
    time.sleep(1./self.fps)//in fraction of second 
self.imageViewer.stop_capturing()