I have a video player GUI that is crashing when I try to save an image. I don’t get any error message in the terminal so I am not sure what is happening - this is only happening on one of the many PCs that I am running this code on and it typically happens when I spam the save image button at a high rate. Video player looks like below (camera plays on left, not currently plugged in)
The same issue was actually happening with start/stop videos but I added a small delay which fixed my issue. I tried the same thing in my saveImage function but it did not fix the crashes. I also tried completely stopping the video player while the save image process is happening but that did not seem to fix the issue either. Here is my code:
# -*- coding: utf-8 -*-
# Form implementation generated from reading ui file 'untitled.ui'
#
# Created by: PyQt5 UI code generator 5.15.6
#
# WARNING: Any manual changes made to this file will be lost when pyuic5 is
# run again. Do not edit this file unless you know what you are doing.
from PyQt5 import QtCore, QtGui, QtWidgets
import sys
from types import FrameType
from PyQt5.QtGui import *
from PyQt5.QtWidgets import *
from PyQt5.QtCore import *
import cv2
import datetime
import numpy as np
import time
class Ui_MainWindow(object):
def setupUi(self, MainWindow):
MainWindow.setObjectName("MainWindow")
MainWindow.resize(1920, 1080)
self.cameraViewer = QtWidgets.QWidget(MainWindow)
self.cameraViewer.setObjectName("cameraViewer")
self.cameraFeed = QtWidgets.QLabel(self.cameraViewer)
self.cameraFeed.setGeometry(QtCore.QRect(10, 10, 1280, 960))
self.cameraFeed.setObjectName("cameraFeed")
self.startBTN = QtWidgets.QPushButton(self.cameraViewer)
self.startBTN.setGeometry(QtCore.QRect(1330, 10, 100, 100))
self.startBTN.setObjectName("startBTN")
self.startBTN.clicked.connect(self.StartFeed)
self.stopBTN = QtWidgets.QPushButton(self.cameraViewer)
self.stopBTN.setGeometry(QtCore.QRect(1440, 10, 100, 100))
self.stopBTN.setObjectName("stopBTN")
self.stopBTN.clicked.connect(self.StopFeed)
self.saveImageBTN = QtWidgets.QPushButton(self.cameraViewer)
self.saveImageBTN.setGeometry(QtCore.QRect(1550, 10, 100, 100))
self.saveImageBTN.setObjectName("saveImageBTN")
self.saveImageBTN.clicked.connect(self.SaveImage)
self.startVideoBTN = QtWidgets.QPushButton(self.cameraViewer)
self.startVideoBTN.setGeometry(QtCore.QRect(1660, 10, 100, 100))
self.startVideoBTN.setObjectName("startVideoBTN")
self.startVideoBTN.clicked.connect(self.StartVideo)
self.stopVideoBTN = QtWidgets.QPushButton(self.cameraViewer)
self.stopVideoBTN.setGeometry(QtCore.QRect(1770, 10, 100, 100))
self.stopVideoBTN.setObjectName("stopVideoBTN")
self.stopVideoBTN.clicked.connect(self.StopVideo)
self.brightnessSlider = QtWidgets.QSlider(self.cameraViewer)
self.brightnessSlider.setFocusPolicy(Qt.StrongFocus)
self.brightnessSlider.setTickPosition(QSlider.TicksBothSides)
self.brightnessSlider.setMinimum(-255)
self.brightnessSlider.setMaximum(255)
self.brightnessSlider.setTickInterval(11)
self.brightnessSlider.setSingleStep(1)
self.brightnessSlider.setGeometry(QtCore.QRect(1330, 120, 50, 100))
self.brightnessSlider.setObjectName("brightnessSlider")
self.brightnessSlider.valueChanged.connect(self.BrightnessSliderChange)
self.brightnessLabel = QtWidgets.QLabel(self.cameraViewer)
self.brightnessLabel.setGeometry(QtCore.QRect(1330, 230, 150, 50))
self.brightnessLabel.setText("Brightness: " + str(self.brightnessSlider.value()))
self.brightnessLabel.setObjectName("brightnessLabel")
MainWindow.setCentralWidget(self.cameraViewer)
self.menubar = QtWidgets.QMenuBar(MainWindow)
self.menubar.setGeometry(QtCore.QRect(0, 0, 800, 26))
self.menubar.setObjectName("menubar")
MainWindow.setMenuBar(self.menubar)
self.statusbar = QtWidgets.QStatusBar(MainWindow)
self.statusbar.setObjectName("statusbar")
MainWindow.setStatusBar(self.statusbar)
self.retranslateUi(MainWindow)
QtCore.QMetaObject.connectSlotsByName(MainWindow)
self.Worker1 = Worker1()
self.Worker1.start()
self.Worker1.ImageUpdate.connect(self.ImageUpdateSlot)
def ImageUpdateSlot(self, Image):
self.cameraFeed.setPixmap(QPixmap.fromImage(Image))
def StartFeed(self):
self.Worker1.start()
def StopFeed(self):
self.Worker1.stop()
def SaveImage(self):
self.Worker1.saveImage()
def StartVideo(self):
self.Worker1.startVideo()
def StopVideo(self):
self.Worker1.stopVideo()
def BrightnessSliderChange(self, value):
self.brightnessLabel.setText("Brightness: " + str(value))
self.Worker1.updateBrightness(value)
def retranslateUi(self, MainWindow):
_translate = QtCore.QCoreApplication.translate
MainWindow.setWindowTitle(_translate("MainWindow", "MainWindow"))
self.startBTN.setText(_translate("MainWindow", "Start Feed"))
self.stopBTN.setText(_translate("MainWindow", "Stop Feed"))
self.saveImageBTN.setText(_translate("MainWindow", "Save Image"))
self.startVideoBTN.setText(_translate("MainWindow", "Start Video"))
self.stopVideoBTN.setText(_translate("MainWindow", "Stop Video"))
class Worker1(QThread):
def __init__(self):
super(Worker1, self).__init__()
self.ThreadActive = None
self.Capture = None
self.frame = None
self.videoCapture = None
self.videoFile = None
self.brightnessValue = 0
ImageUpdate = pyqtSignal(QImage)
def run(self):
self.ThreadActive = True
self.Capture = cv2.VideoCapture(0)
while self.ThreadActive:
ret, self.frame = self.Capture.read()
if ret:
#self.FlippedImage = cv2.flip(frame, 1)
Image = cv2.cvtColor(self.frame, cv2.COLOR_BGR2RGB)
BrightnessMatrix = np.ones(Image.shape, dtype = "uint8") * abs(self.brightnessValue)
if (self.brightnessValue > 0):
Image = cv2.add(Image, BrightnessMatrix)
elif (self.brightnessValue < 0):
Image = cv2.subtract(Image, BrightnessMatrix)
ConvertToQtFormat = QImage(Image.data, Image.shape[1], Image.shape[0], QImage.Format_RGB888)
Pic = ConvertToQtFormat.scaled(1280, 960, Qt.KeepAspectRatio)
self.ImageUpdate.emit(Pic)
if self.videoCapture:
self.videoFile.write(self.frame)
self.Capture.release()
def stop(self):
self.ThreadActive = False
self.quit()
def saveImage(self):
time = datetime.datetime.now()
img_name = "image_{}.png".format(time.strftime("%Hh%Mm%Ss"))
if self.Capture.isOpened():
cv2.imwrite(img_name, self.frame)
def startVideo(self):
time = datetime.datetime.now()
video_name = "video_{}.avi".format(time.strftime("%Hh%Mm%Ss"))
codec = cv2.VideoWriter_fourcc(*'MJPG')
self.videoFile = cv2.VideoWriter(video_name, codec, 30.0, (640, 480))
self.videoCapture = True
def stopVideo(self):
self.videoCapture = False
time.sleep(0.1)
self.videoFile.release()
def updateBrightness(self, value):
self.brightnessValue = value
if __name__ == "__main__":
import sys
app = QtWidgets.QApplication(sys.argv)
MainWindow = QtWidgets.QMainWindow()
ui = Ui_MainWindow()
ui.setupUi(MainWindow)
MainWindow.show()
sys.exit(app.exec_())