2017-06-07 74 views
3

嘗試鏈接PyQt和Opencv視頻源,無法理解如何應用while循環以連續流式傳輸視頻。它只是拍攝靜物。請任何人都可以幫助解決問題。PyQt沒有顯示來自opencv的視頻流

  • PtQt = 5

  • 的Python = 3.6.1


class App(QWidget): 
    def __init__(self): 
     super().__init__() 
     self.title = 'PyQt5 Video' 
     self.left = 100 
     self.top = 100 
     self.width = 640 
     self.height = 480 
     self.initUI() 


    def initUI(self): 
     self.setWindowTitle(self.title) 
     self.setGeometry(self.left, self.top, self.width, self.height) 
     self.resize(1800, 1200) 
     #create a label 
     label = QLabel(self) 
     cap = cv2.VideoCapture(0) 
     ret, frame = cap.read() 
     rgbImage = cv2.cvtColor(frame, cv2.COLOR_BGR2RGB) 
     convertToQtFormat = QtGui.QImage(rgbImage.data, rgbImage.shape[1], rgbImage.shape[0], 
             QtGui.QImage.Format_RGB888) 
     convertToQtFormat = QtGui.QPixmap.fromImage(convertToQtFormat) 
     pixmap = QPixmap(convertToQtFormat) 
     resizeImage = pixmap.scaled(640, 480, QtCore.Qt.KeepAspectRatio) 
     QApplication.processEvents() 
     label.setPixmap(resizeImage) 
     self.show() 

if __name__ == '__main__': 
    app = QApplication(sys.argv) 
    ex = App() 
    sys.exit(app.exec_()) 

回答

3

的問題是,獲得圖像的功能只執行一次,而不是更新標籤。
正確的方法是將它放在一個循環中,但它會導致阻塞主窗口。主窗口的阻塞可以通過使用QThread類來解決,並通過信號QPixmap發送來更新標籤。例如:

class Thread(QThread): 
    changePixmap = pyqtSignal(QPixmap) 

    def __init__(self, parent=None): 
     QThread.__init__(self, parent=parent) 

    def run(self): 
     cap = cv2.VideoCapture(0) 
     while True: 
      ret, frame = cap.read() 
      rgbImage = cv2.cvtColor(frame, cv2.COLOR_BGR2RGB) 
      convertToQtFormat = QImage(rgbImage.data, rgbImage.shape[1], rgbImage.shape[0], QImage.Format_RGB888) 
      convertToQtFormat = QPixmap.fromImage(convertToQtFormat) 
      p = convertToQtFormat.scaled(640, 480, Qt.KeepAspectRatio) 
      self.changePixmap.emit(p) 


class App(QWidget): 
    def __init__(self): 
     super().__init__() 
     [...] 
     self.initUI() 

    def initUI(self): 
     self.setWindowTitle(self.title) 
     self.setGeometry(self.left, self.top, self.width, self.height) 
     self.resize(1800, 1200) 
     # create a label 
     label = QLabel(self) 
     label.move(280, 120) 
     label.resize(640, 480) 
     th = Thread(self) 
     th.changePixmap.connect(label.setPixmap) 
     th.start() 
+0

謝謝:) :) –

0

謝謝泰穆伊斯蘭教的問題。 謝謝eyllanesc的精彩回答,我修改了一下你的代碼。我用PtQt = 4 Python = 2.7,我沒有使用opencv

import sys  
import numpy as np 
import flycapture2 as fc2 

from PyQt4.QtCore import (QThread, Qt, pyqtSignal) 
from PyQt4.QtGui import (QPixmap, QImage, QApplication, QWidget, QLabel) 

class Thread(QThread): 
    changePixmap = pyqtSignal(QImage) 

    def __init__(self, parent=None): 
     QThread.__init__(self, parent=parent)  
     self.cameraSettings() 


    def run(self):  
     while True: 
      im = fc2.Image() 
      self.c.retrieve_buffer(im) 
      a = np.array(im)  

      rawImage = QImage(a.data, a.shape[1], a.shape[0], QImage.Format_Indexed8) 

      self.changePixmap.emit(rawImage) 

    def cameraSettings(self): 
     print(fc2.get_library_version()) 
     self.c = fc2.Context() 
     numberCam = self.c.get_num_of_cameras() 
     print(numberCam)  
     self.c.connect(*self.c.get_camera_from_index(0)) 
     print(self.c.get_camera_info()) 
     m, f = self.c.get_video_mode_and_frame_rate() 
     print(m, f) 
     print(self.c.get_property_info(fc2.FRAME_RATE)) 
     p = self.c.get_property(fc2.FRAME_RATE) 
     print(p) 
     self.c.set_property(**p) 
     self.c.start_capture() 


class App(QWidget): 
    def __init__(self): 
      super(App,self).__init__() 
      self.title = 'PyQt4 Video' 
      self.left = 100 
      self.top = 100 
      self.width = 640 
      self.height = 480 
      self.initUI() 

    def initUI(self): 
      self.setWindowTitle(self.title) 
      self.setGeometry(self.left, self.top, self.width, self.height) 
      self.resize(800, 600) 
      # create a label 
      self.label = QLabel(self) 
      self.label.move(0, 0) 
      self.label.resize(640, 480) 
      th = Thread(self) 
      th.changePixmap.connect(lambda p: self.setPixMap(p)) 
      th.start() 

    def setPixMap(self, p):  
     p = QPixmap.fromImage(p)  
     p = p.scaled(640, 480, Qt.KeepAspectRatio) 
     self.label.setPixmap(p) 


if __name__ == '__main__': 
    app = QApplication(sys.argv) 
    ex = App() 
    ex.show() 
    sys.exit(app.exec_())