下面的代码是有问题的代码。
当接收到的网络摄像头数据为 640x480 时,此代码可以正常工作。 -.左键单击应用程序窗口的标题栏并等待 -.左键单击并按住最小化、最大化、关闭按钮 在这种情况下,GUI 冻结,但在释放左键单击一段时间后,GUI 开始正常工作。
但是,当网络摄像头的数据以 1920x1080 接收时,此代码会导致问题。 在以上两个应用程序窗口中操作会导致GUI卡死,最终进程终止。
我想解决这个问题 我想知道如何解决它以避免 pyqt5 GUI 冻结。
import cv2
import sys
from PyQt5 import QtCore
from PyQt5 import QtWidgets
from PyQt5 import QtGui
class ShowVideo(QtCore.QObject):
flag = 0
camera = cv2.VideoCapture(0)
camera.set(cv2.CAP_PROP_FRAME_WIDTH, 1920 ) # 1920
camera.set(cv2.CAP_PROP_FRAME_HEIGHT, 1080) # 1080
ret, image = camera.read()
height, width = image.shape[:2]
print(f"{height} / {width}")
VideoSignal1 = QtCore.pyqtSignal(QtGui.QImage)
VideoSignal2 = QtCore.pyqtSignal(QtGui.QImage)
def __init__(self, parent=None):
super().__init__()
@QtCore.pyqtSlot()
def startVideo(self):
global image
run_video = True
while run_video:
ret, image = self.camera.read()
color_swapped_image = cv2.cvtColor(image, cv2.COLOR_BGR2RGB)
qt_image1 = QtGui.QImage(color_swapped_image.data,
self.width,
self.height,
color_swapped_image.strides[0],
QtGui.QImage.Format_RGB888)
self.VideoSignal1.emit(qt_image1)
if self.flag:
img_gray = cv2.cvtColor(image, cv2.COLOR_BGR2GRAY)
img_canny = cv2.Canny(img_gray, 50, 100)
qt_image2 = QtGui.QImage(img_canny.data,
self.width,
self.height,
img_canny.strides[0],
QtGui.QImage.Format_Grayscale8)
self.VideoSignal2.emit(qt_image2)
loop = QtCore.QEventLoop()
QtCore.QTimer.singleShot(25, loop.quit) #25 ms
loop.exec_()
@QtCore.pyqtSlot()
def canny(self):
self.flag = 1 - self.flag
class ImageViewer(QtWidgets.QWidget):
def __init__(self, parent=None):
# super(ImageViewer, self).__init__(parent)
super().__init__()
self.image = QtGui.QImage()
self.setAttribute(QtCore.Qt.WA_OpaquePaintEvent)
def paintEvent(self, event):
painter = QtGui.QPainter(self)
painter.drawImage(0, 0, self.image)
# self.image = QtGui.QImage()
def initUI(self):
self.setWindowTitle('Test')
@QtCore.pyqtSlot(QtGui.QImage)
def setImage(self, image):
image = QtGui.QImage(image).scaled(400, 300, QtCore.Qt.KeepAspectRatio, QtCore.Qt.FastTransformation)
if image.isNull():
print("Viewer Dropped frame!")
self.image = image
if image.size() != self.size():
self.setFixedSize(image.size())
self.update()
if __name__ == '__main__':
app = QtWidgets.QApplication(sys.argv)
thread = QtCore.QThread()
thread.start()
vid = ShowVideo()
vid.moveToThread(thread)
image_viewer1 = ImageViewer()
image_viewer2 = ImageViewer()
vid.VideoSignal1.connect(image_viewer1.setImage)
vid.VideoSignal2.connect(image_viewer2.setImage)
push_button1 = QtWidgets.QPushButton('Start')
push_button2 = QtWidgets.QPushButton('Canny')
push_button1.clicked.connect(vid.startVideo)
push_button2.clicked.connect(vid.canny)
vertical_layout = QtWidgets.QVBoxLayout()
horizontal_layout = QtWidgets.QHBoxLayout()
horizontal_layout.addWidget(image_viewer1)
horizontal_layout.addWidget(image_viewer2)
vertical_layout.addLayout(horizontal_layout)
vertical_layout.addWidget(push_button1)
vertical_layout.addWidget(push_button2)
layout_widget = QtWidgets.QWidget()
layout_widget.setLayout(vertical_layout)
main_window = QtWidgets.QMainWindow()
main_window.setCentralWidget(layout_widget)
main_window.show()
sys.exit(app.exec_())