I trying to make an GUI application that takes a video (video from a mechanical compression test), apply some image processing and gives in real time the plotting result and the value of a mechanical coefficient (poisson coefficient).
I already manage to have the GUI in PYQT5 with upload and launch button, and the result of the video processing. What I'm now trying to do and didn't manage, is to plot simultaneously the result of a computation.
My architecture code is as follow:
Stylesheet.py
Content colors, background, icon, and geometry
uiQT.py
Contents the definition of all Widgets and the setup of the UI.
MainQT.py
Main program, inits the GUI and all the functions.
Above is my code uiQT and MainQT, if someone would be so kind to helps me.
I've tried following several tutorials, (here,here, and here) but nothing seems to works.
uiQT.py
from PyQt5 import QtCore, QtGui, QtWidgets
from PyQt5.QtWidgets import QDialog, QApplication, QPushButton, QVBoxLayout
from matplotlib.backends.backend_qt5agg import FigureCanvasQTAgg as FigureCanvas
from matplotlib.figure import Figure
import matplotlib.pyplot as plt
from stylesheet import colors, dimension, ressources
class Ui_MainWindow(object):
def setupUi(self, MainWindow):
MainWindow.setObjectName("MainWindow")
Mainx=dimension["MainWinSize"][0]
Mainy=dimension["MainWinSize"][1]
left = (int(QtWidgets.QDesktopWidget().screenGeometry().width()) - Mainx) /2
top = (int(QtWidgets.QDesktopWidget().screenGeometry().height()) - Mainy) /2
MainWindow.setGeometry(left, top, Mainx, Mainy)
#Main Centralwidget
MainWindow.setStyleSheet(colors["MainBackGr"])
self.centralwidget = QtWidgets.QWidget(MainWindow)
self.centralwidget.setStyleSheet(colors["EmptyBackGr"])
self.centralwidget.setObjectName("centralwidget")
#button to upload video
self.browse_button = QtWidgets.QPushButton(self.centralwidget)
self.browse_button.setIcon(QtGui.QIcon(ressources["UploadBtnNormal"]))
self.browse_button.setIconSize(QtCore.QSize(dimension["UploadBtnSize"][0],dimension["UploadBtnSize"][1]),)
self.browse_button.setGeometry(QtCore.QRect(dimension["UploadBtnposition"][0],dimension["UploadBtnposition"][1],dimension["UploadBtnposition"][2],dimension["UploadBtnposition"][3]))
self.browse_button.setObjectName("browse_button")
#button to launch processing
self.go_button = QtWidgets.QPushButton(self.centralwidget)
self.go_button.setIcon(QtGui.QIcon(ressources["GoBtninitial"]))
self.go_button.setIconSize(QtCore.QSize(dimension["UploadBtnSize"][0],dimension["UploadBtnSize"][1]),)
self.go_button.setGeometry(QtCore.QRect(QtCore.QRect(dimension["LaunchBtnNormalPosition"][0],dimension["LaunchBtnNormalPosition"][1],dimension["LaunchBtnNormalPosition"][2],dimension["LaunchBtnNormalPosition"][3])))
self.go_button.setStyleSheet(colors["EmptyBackGr"])
self.go_button.setObjectName("GO_button")
#Area that contains video rendering
self.render_video = QtWidgets.QLabel(self.centralwidget)
self.render_video.setGeometry(QtCore.QRect(dimension["render_video"][0],dimension["render_video"][1],dimension["render_video"][2],dimension["render_video"][3] ) )
self.render_video.setStyleSheet(colors["VideoBackGr"])
self.render_video.setText("")
self.render_video.setScaledContents(True)
self.render_video.setObjectName("render_video")
MainWindow.setCentralWidget(self.centralwidget)
self.statusbar = QtWidgets.QStatusBar(MainWindow)
self.statusbar.setObjectName("statusbar")
MainWindow.setStatusBar(self.statusbar)
self.retranslateUi(MainWindow)
QtCore.QMetaObject.connectSlotsByName(MainWindow)
def retranslateUi(self, MainWindow):
_translate = QtCore.QCoreApplication.translate
MainWindow.setWindowTitle(_translate("MainWindow", "Coefficient_poisson"))
self.go_button.setText(_translate("MainWindow", "GO_button"))
mainQT.py
import sys
import cv2
import os
from stylesheet import colors, dimension, ressources
from PyQt5.QtWidgets import QMainWindow, QApplication, QMessageBox, QFileDialog
from PyQt5.QtGui import QPixmap,QImage
from uiQT import *
from uiQT import Ui_MainWindow
import matplotlib.pyplot as plt
from mpl_toolkits.axes_grid1 import host_subplot
import mpl_toolkits.axisartist as AA
import numpy as np
from matplotlib.backends.backend_qt5agg import FigureCanvasQTAgg as FigureCanvas
from matplotlib.figure import Figure
playvid = True
class form(QMainWindow):
def __init__(self):
super().__init__()
self.ui = Ui_MainWindow()
self.ui.setupUi(self)
self.ui.browse_button.clicked.connect(self.SelectFile)
self.ui.go_button.clicked.connect(self.start_processing)
self.show()
def SelectFile(self):
self.fname = QFileDialog.getOpenFileName(None, 'Open Video file',"*.avi;*mp4", os.getenv('HOME'))
self.fname=str(self.fname[0])
print(self.fname)
#check file extension
if (os.path.splitext(self.fname)[1] == ".avi") or (os.path.splitext(self.fname)[1] == ".mp4"):
print("file valid")
self.ui.go_button.setIcon(QtGui.QIcon(ressources["GoBtnready"]))
self.ui.browse_button.setIcon(QtGui.QIcon(ressources["UploadBtnOk"]))
else:
QMessageBox.critical(self, "ERREUR", "Le format n'est pas valide, choisissez une vidéo")
def start_processing(self):
self.c = cv2.VideoCapture(self.fname)
if playvid == True:
print("PLAYVIDTRUE")
self.timer = QtCore.QTimer(self)
self.timer.timeout.connect(self.load_vid)
self.timer.start(100)
self.timerId=self.timer.timerId()
else: print("PLAYVID FALSE")
def load_vid(self):
print (self.c.grab())
print(self.c.get(cv2.CAP_PROP_POS_FRAMES),self.c.get(cv2.CAP_PROP_FRAME_COUNT))
while True:
if self.c.grab():
print(self.c.get(cv2.CAP_PROP_POS_FRAMES),self.c.get(cv2.CAP_PROP_FRAME_COUNT))
ret, frame = self.c.read()
height, width, bytesPerComponent = frame.shape
bytesPerLine = 3 * width
cv2.cvtColor(frame, cv2.COLOR_BGR2RGB, frame)
QImg = QImage(frame.data, width, height, bytesPerLine,QImage.Format_RGB888)
pixmap = QPixmap.fromImage(QImg)
self.ui.render_video.setPixmap(pixmap)
cv2.namedWindow("video",CV_GUI_NORMAL)
cv2.resizeWindow('video', 1,1)
cv2.imshow('video', frame)
#get value of frames
global currentframe
currentframe=self.c.get(cv2.CAP_PROP_POS_FRAMES)
totalFrames= self.c.get(cv2.CAP_PROP_FRAME_COUNT)
print(currentframe,totalFrames,"\n")
if currentframe+5>totalFrames:
print("last frame achieve")
global playvid
playvid= False
print(playvid)
cv2.destroyAllWindows()
self.c.release()
# quit timer when last frames (+/- 5 five frames,depends on frame rate and timer value)
if self.timer.isActive:
self.timer.disconnect()
self.timer.stop()
if __name__ == '__main__':
app = QApplication(sys.argv)
fm = form()
sys.exit(app.exec_())
GUI rendering
the current rendering is as follow
So my question is.
how to enable the dynamic plot in my GUI ? (ideally at the same time as my CV2 processing) without modifiyng to much my actual code, as simple as possible, QPIXmap QVboxlayout ?. Thanks a lot