在 QLabel 元素中实时显示 CV2



我目前正在为我用OpenCV制作的监控系统编写GUI。我想在设置框旁边的 QLabel 中看到实时视频输入,但我对发射/信号/插槽主题很陌生,所以我对代码顺序有点不知所措。 GUI是从QtCreator转换而来的,只是为了获得正确的布局。这些按钮尚没有任何功能。 这是我到目前为止的代码:

import sys
import cv2
from PyQt5 import QtCore, QtGui, QtWidgets
from PyQt5.QtWidgets import *
from PyQt5.QtGui import *
from PyQt5.QtCore import *

#getting the live vid
class Thread(QThread):
changePixmap = pyqtSignal(QImage)
def run(self):
cap1 = cv2.VideoCapture('single.mp4')
while True:
ret, frame = cap1.read()
rgb_image = cv2.cvtColor(frame, cv2.COLOR_BGR2RGB)
cvt2qt = QImage(rgb_image.data, rgb_image.shape[1], rgb_image.shape[0], QImage.Format_RGB888)
self.changePixmap.emit(cvt2qt)                         # I don't really understand this yet

class Ui_MainWindow(object):
def setImage(self, image):
self.label.setPixmap(QPixmap.fromImage(image))
@pyqtSlot(QImage)                                              # I'm not sure about this function
def setupUi(self, MainWindow):
MainWindow.setObjectName("MainWindow")
MainWindow.resize(1280, 779)
MainWindow.setMinimumSize(QtCore.QSize(920, 405))
self.centralWidget = QtWidgets.QWidget(MainWindow)
self.centralWidget.setMinimumSize(QtCore.QSize(400, 400))
self.centralWidget.setBaseSize(QtCore.QSize(800, 600))
self.centralWidget.setObjectName("centralWidget")
# here is where I want to put the image.
self.label = QtWidgets.QLabel(self.centralWidget)
self.label.setGeometry(QtCore.QRect(10, 10, 881, 671))
self.label.setScaledContents(True)
self.label.setObjectName("label")
th = Thread(self)                                           # Here is, where I struggle
th.changePixmap.connect(self.setImage)
th.start()
MainWindow.setCentralWidget(self.centralWidget)
self.dockWidget = QtWidgets.QDockWidget(MainWindow)
self.dockWidget.setMinimumSize(QtCore.QSize(200, 0))
self.dockWidget.setLayoutDirection(QtCore.Qt.LeftToRight)
self.dockWidget.setFeatures(QtWidgets.QDockWidget.DockWidgetMovable)
self.dockWidget.setAllowedAreas(QtCore.Qt.LeftDockWidgetArea|QtCore.Qt.RightDockWidgetArea)
self.dockWidget.setObjectName("dockWidget")
self.dockWidgetContents = QtWidgets.QWidget()
self.dockWidgetContents.setObjectName("dockWidgetContents")
self.groupBox = QtWidgets.QGroupBox(self.dockWidgetContents)
self.groupBox.setGeometry(QtCore.QRect(0, 30, 141, 281))
self.groupBox.setMinimumSize(QtCore.QSize(90, 0))
self.groupBox.setObjectName("groupBox")
self.pushButton = QtWidgets.QPushButton(self.groupBox)
self.pushButton.setGeometry(QtCore.QRect(10, 20, 121, 32))
self.pushButton.setObjectName("pushButton")
self.pushButton_2 = QtWidgets.QPushButton(self.groupBox)
self.pushButton_2.setGeometry(QtCore.QRect(10, 50, 121, 32))
self.pushButton_2.setObjectName("pushButton_2")
self.pushButton_3 = QtWidgets.QPushButton(self.groupBox)
self.pushButton_3.setGeometry(QtCore.QRect(10, 80, 121, 32))
self.pushButton_3.setObjectName("pushButton_3")
self.radioButton = QtWidgets.QRadioButton(self.groupBox)
self.radioButton.setGeometry(QtCore.QRect(20, 120, 100, 20))
self.radioButton.setObjectName("radioButton")
self.radioButton_2 = QtWidgets.QRadioButton(self.groupBox)
self.radioButton_2.setGeometry(QtCore.QRect(20, 150, 100, 20))
self.radioButton_2.setObjectName("radioButton_2")
self.radioButton_3 = QtWidgets.QRadioButton(self.groupBox)
self.radioButton_3.setGeometry(QtCore.QRect(20, 180, 100, 20))
self.radioButton_3.setObjectName("radioButton_3")
self.dockWidget.setWidget(self.dockWidgetContents)
MainWindow.addDockWidget(QtCore.Qt.DockWidgetArea(2), self.dockWidget)
self.retranslateUi(MainWindow)
QtCore.QMetaObject.connectSlotsByName(MainWindow)

def retranslateUi(self, MainWindow):
_translate = QtCore.QCoreApplication.translate
MainWindow.setWindowTitle(_translate("MainWindow", "ARCV"))
self.groupBox.setTitle(_translate("MainWindow", "Settings"))
self.pushButton.setText(_translate("MainWindow", "Start Recording"))
self.pushButton_2.setText(_translate("MainWindow", "Stop Recording"))
self.pushButton_3.setText(_translate("MainWindow", "Quit GUI"))
self.radioButton.setText(_translate("MainWindow", "Camera 1"))
self.radioButton_2.setText(_translate("MainWindow", "Camera 2"))
self.radioButton_3.setText(_translate("MainWindow", "Camera 3"))

class Prog(QMainWindow):
def __init__(self):
super().__init__();
self.ui = Ui_MainWindow()
self.ui.setupUi(self)
if __name__=='__main__':
Program =  QApplication(sys.argv)
MyProg = Prog()
MyProg.show()
sys.exit(Program.exec_())

我希望,你能帮助我。谢谢。 阿罗克奈特

QThread作为父级的参数等待,必须是QObject,在您的情况下,self 是Ui_MainWindow类的对象,它不会从导致问题的QObject继承。

我看到您正在实现一个名为Prog的类,您必须执行逻辑而不是修改Qt Designer生成的代码。

因此,如果我们将逻辑移动到该类,应该没有问题。

另一方面,装饰器@pyqtSlot必须在连接到信号的功能中使用,将其放置在没有意义的构造函数中,它必须位于setImage()之上。

import sys
import cv2
from PyQt5 import QtCore, QtGui, QtWidgets

class Ui_MainWindow(object):
def setupUi(self, MainWindow):
MainWindow.setObjectName("MainWindow")
MainWindow.resize(1280, 779)
MainWindow.setMinimumSize(QtCore.QSize(920, 405))
self.centralWidget = QtWidgets.QWidget(MainWindow)
self.centralWidget.setMinimumSize(QtCore.QSize(400, 400))
self.centralWidget.setBaseSize(QtCore.QSize(800, 600))
self.centralWidget.setObjectName("centralWidget")
# here is where I want to put the image.
self.label = QtWidgets.QLabel(self.centralWidget)
self.label.setGeometry(QtCore.QRect(10, 10, 881, 671))
self.label.setScaledContents(True)
self.label.setObjectName("label")
MainWindow.setCentralWidget(self.centralWidget)
self.dockWidget = QtWidgets.QDockWidget(MainWindow)
self.dockWidget.setMinimumSize(QtCore.QSize(200, 0))
self.dockWidget.setLayoutDirection(QtCore.Qt.LeftToRight)
self.dockWidget.setFeatures(QtWidgets.QDockWidget.DockWidgetMovable)
self.dockWidget.setAllowedAreas(QtCore.Qt.LeftDockWidgetArea|QtCore.Qt.RightDockWidgetArea)
self.dockWidget.setObjectName("dockWidget")
self.dockWidgetContents = QtWidgets.QWidget()
self.dockWidgetContents.setObjectName("dockWidgetContents")
self.groupBox = QtWidgets.QGroupBox(self.dockWidgetContents)
self.groupBox.setGeometry(QtCore.QRect(0, 30, 141, 281))
self.groupBox.setMinimumSize(QtCore.QSize(90, 0))
self.groupBox.setObjectName("groupBox")
self.pushButton = QtWidgets.QPushButton(self.groupBox)
self.pushButton.setGeometry(QtCore.QRect(10, 20, 121, 32))
self.pushButton.setObjectName("pushButton")
self.pushButton_2 = QtWidgets.QPushButton(self.groupBox)
self.pushButton_2.setGeometry(QtCore.QRect(10, 50, 121, 32))
self.pushButton_2.setObjectName("pushButton_2")
self.pushButton_3 = QtWidgets.QPushButton(self.groupBox)
self.pushButton_3.setGeometry(QtCore.QRect(10, 80, 121, 32))
self.pushButton_3.setObjectName("pushButton_3")
self.radioButton = QtWidgets.QRadioButton(self.groupBox)
self.radioButton.setGeometry(QtCore.QRect(20, 120, 100, 20))
self.radioButton.setObjectName("radioButton")
self.radioButton_2 = QtWidgets.QRadioButton(self.groupBox)
self.radioButton_2.setGeometry(QtCore.QRect(20, 150, 100, 20))
self.radioButton_2.setObjectName("radioButton_2")
self.radioButton_3 = QtWidgets.QRadioButton(self.groupBox)
self.radioButton_3.setGeometry(QtCore.QRect(20, 180, 100, 20))
self.radioButton_3.setObjectName("radioButton_3")
self.dockWidget.setWidget(self.dockWidgetContents)
MainWindow.addDockWidget(QtCore.Qt.DockWidgetArea(2), self.dockWidget)
self.retranslateUi(MainWindow)
QtCore.QMetaObject.connectSlotsByName(MainWindow)

def retranslateUi(self, MainWindow):
_translate = QtCore.QCoreApplication.translate
MainWindow.setWindowTitle(_translate("MainWindow", "ARCV"))
self.groupBox.setTitle(_translate("MainWindow", "Settings"))
self.pushButton.setText(_translate("MainWindow", "Start Recording"))
self.pushButton_2.setText(_translate("MainWindow", "Stop Recording"))
self.pushButton_3.setText(_translate("MainWindow", "Quit GUI"))
self.radioButton.setText(_translate("MainWindow", "Camera 1"))
self.radioButton_2.setText(_translate("MainWindow", "Camera 2"))
self.radioButton_3.setText(_translate("MainWindow", "Camera 3"))

#getting the live vid
class Thread(QtCore.QThread):
changePixmap = QtCore.pyqtSignal(QtGui.QImage)
def __init__(self, *args, **kwargs):
QtCore.QThread.__init__(self, *args, **kwargs)
self.flag = False
def run(self):
cap1 = cv2.VideoCapture('single.mp4')
self.flag = True
while self.flag:
ret, frame = cap1.read()
if ret:
rgb_image = cv2.cvtColor(frame, cv2.COLOR_BGR2RGB)
cvt2qt = QtGui.QImage(rgb_image.data, rgb_image.shape[1], rgb_image.shape[0], QtGui.QImage.Format_RGB888)
self.changePixmap.emit(cvt2qt)                         # I don't really understand this yet
def stop(self):
self.flag = False

class Prog(QtWidgets.QMainWindow, Ui_MainWindow):
def __init__(self):
super().__init__()
self.setupUi(self)
self.th = Thread(self)
self.th.changePixmap.connect(self.setImage)
self.th.start()
@QtCore.pyqtSlot(QtGui.QImage) 
def setImage(self, image):
self.label.setPixmap(QtGui.QPixmap.fromImage(image))
def closeEvent(self, event):
self.th.stop()
self.th.wait()
super().closeEvent(event)
if __name__=='__main__':
Program =  QtWidgets.QApplication(sys.argv)
MyProg = Prog()
MyProg.show()
sys.exit(Program.exec_())

最新更新