Как в PyQt6 вывести информацию в QLabel о количестве кадров в секунду камеры?

Рейтинг: 1Ответов: 1Опубликовано: 02.04.2023

Данный код отображает количество FPS в QLabel "ui_video".
В интерфейсе есть другой QLabel "ui_text", предусмотренный специально для вывода текстовой информации.

Как вместо "Привет" вывести информацию о количестве FPS в "ui_text"?

main.py

from PyQt6.QtGui import QPixmap
from PyQt6.QtWidgets import QApplication, QMainWindow
from PyQt6.uic import loadUi
import sys

from threadOpenCV import ThreadOpenCV


class MainWindow(QMainWindow):
    def __init__(self):
        super(MainWindow, self).__init__()
        loadUi("Test.ui", self)

        self.thread_1 = ThreadOpenCV(0)

        self.ui_StartCamera.clicked.connect(self.onCapture)
        self.ui_StopCamera.clicked.connect(self.offCapture)
        self.ui_StopCamera.setChecked(True)

        self.ui_text.setText("Привет")

    def setImage(self, image):
        self.ui_video.setPixmap(QPixmap.fromImage(image))

    def onCapture(self):
        self.thread_1.changePixmap.connect(self.setImage)
        self.thread_1.start()


    def offCapture(self):
        self.ui_StartCamera.setEnabled(True)
        self.thread_1.stopCam()


if __name__ == '__main__':
    app = QApplication(sys.argv)
    window = MainWindow()
    window.show()

    sys.exit(app.exec())

threadOpenCV.py

import time

import cv2
from PyQt6.QtCore import QThread, pyqtSignal, Qt
from PyQt6.QtGui import QImage


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

    def __init__(self, source):
        super().__init__()

        self.source = source
        self.running = False
        self.myFont = cv2.FONT_HERSHEY_DUPLEX

    def run(self):
        cap = cv2.VideoCapture(self.source)
        self.running = True
        tlast = time.time()
        fpsFILT = 60
        time.sleep(.1)

        while self.running:
            self.fpsFILT = self.fps(tlast, fpsFILT)
            tlast = time.time()
            ret, frame = cap.read()
            h, w, ch = frame.shape
            cv2.putText(frame, 'fps: ' + str(int(self.fpsFILT)), (5, 30), self.myFont, 1, (0, 0, 255), 2)
            frame = cv2.cvtColor(frame, cv2.COLOR_BGR2RGB)
            self.displayImage(frame, w, h, ch)

    def fps(self, tlast, fpsFILT):
        dT = time.time() - tlast
        fps = 1 / dT
        fpsFILT = fpsFILT * .97 + fps * .03
        return fpsFILT

    def displayImage(self, frame, w, h, ch):
        bytes_per_line = ch * w
        image = QImage(frame.data, w, h, bytes_per_line,
                       QImage.Format.Format_RGB888)
        image = image.scaled(720, 480, Qt.AspectRatioMode.KeepAspectRatio)
        self.changePixmap.emit(image)

    def stopCam(self):
        self.running = False

Test.ui

<?xml version="1.0" encoding="UTF-8"?>
<ui version="4.0">
 <class>MainWindow</class>
 <widget class="QMainWindow" name="MainWindow">
  <property name="geometry">
   <rect>
    <x>0</x>
    <y>0</y>
    <width>732</width>
    <height>539</height>
   </rect>
  </property>
  <property name="windowTitle">
   <string>MainWindow</string>
  </property>
  <widget class="QWidget" name="centralwidget">
   <widget class="QGroupBox" name="groupBox">
    <property name="geometry">
     <rect>
      <x>10</x>
      <y>10</y>
      <width>701</width>
      <height>491</height>
     </rect>
    </property>
    <property name="title">
     <string>GroupBox</string>
    </property>
    <widget class="QLabel" name="ui_video">
     <property name="enabled">
      <bool>true</bool>
     </property>
     <property name="geometry">
      <rect>
       <x>30</x>
       <y>30</y>
       <width>411</width>
       <height>301</height>
      </rect>
     </property>
     <property name="styleSheet">
      <string notr="true">background-color: rgb(0, 0, 0);</string>
     </property>
     <property name="text">
      <string>TextLabel</string>
     </property>
     <property name="textFormat">
      <enum>Qt::PlainText</enum>
     </property>
     <property name="alignment">
      <set>Qt::AlignLeading|Qt::AlignLeft|Qt::AlignTop</set>
     </property>
    </widget>
    <widget class="QLabel" name="ui_text">
     <property name="geometry">
      <rect>
       <x>30</x>
       <y>360</y>
       <width>411</width>
       <height>71</height>
      </rect>
     </property>
     <property name="styleSheet">
      <string notr="true">background-color: rgb(0 0, 0);</string>
     </property>
     <property name="text">
      <string>TextLabel</string>
     </property>
    </widget>
    <widget class="QGroupBox" name="groupBox_5">
     <property name="geometry">
      <rect>
       <x>500</x>
       <y>30</y>
       <width>80</width>
       <height>301</height>
      </rect>
     </property>
     <property name="title">
      <string/>
     </property>
     <layout class="QVBoxLayout" name="verticalLayout">
      <item>
       <widget class="QRadioButton" name="ui_StartCamera">
        <property name="text">
         <string>Вкл</string>
        </property>
       </widget>
      </item>
      <item>
       <widget class="QRadioButton" name="ui_StopCamera">
        <property name="enabled">
         <bool>true</bool>
        </property>
        <property name="tabletTracking">
         <bool>false</bool>
        </property>
        <property name="text">
         <string>Выкл</string>
        </property>
       </widget>
      </item>
     </layout>
    </widget>
   </widget>
  </widget>
  <widget class="QMenuBar" name="menubar">
   <property name="geometry">
    <rect>
     <x>0</x>
     <y>0</y>
     <width>732</width>
     <height>26</height>
    </rect>
   </property>
  </widget>
  <widget class="QStatusBar" name="statusbar"/>
 </widget>
 <resources/>
 <connections/>
</ui>

Ответы

▲ 1Принят

Если я вас правильно понял, поменяйте импорты и попробуйте:

import sys, os
import time
import cv2
'''                                                              # PyQt6
from PyQt6.QtGui import QPixmap, QImage
from PyQt6.QtWidgets import QApplication, QMainWindow
from PyQt6.QtCore import QThread, pyqtSignal, Qt
from PyQt6.uic import loadUi
'''
from PyQt5 import QtCore, QtGui, QtWidgets                       # PyQt5
from PyQt5.Qt import *
from PyQt5.uic import loadUi

#from threadOpenCV import ThreadOpenCV
class ThreadOpenCV(QThread):
# +++ ------------------------------> vvvvv <----------------------------
    changePixmap = pyqtSignal(QImage, float)

    def __init__(self, source):
        super().__init__()

        self.source = source
        self.running = False
        self.myFont = cv2.FONT_HERSHEY_DUPLEX
# +++        
        self.fpsFILT = 0                                          # +++

    def run(self):
        cap = cv2.VideoCapture(self.source)
        self.running = True
        tlast = time.time()
        fpsFILT = 60
        time.sleep(.1)

        while self.running:
            self.fpsFILT = self.fps(tlast, fpsFILT)
            tlast = time.time()
            ret, frame = cap.read()
            h, w, ch = frame.shape

#            cv2.putText(frame, 'fps: ' + str(int(self.fpsFILT)), (5, 30), self.myFont, 1, (0, 0, 255), 2)
            cv2.putText(frame, f'fps: {self.fpsFILT:.2f}', (5, 30), self.myFont, 1, (0, 0, 255), 2)

            frame = cv2.cvtColor(frame, cv2.COLOR_BGR2RGB)
            self.displayImage(frame, w, h, ch)

    def fps(self, tlast, fpsFILT):
        dT = time.time() - tlast
        fps = 1 / dT
        fpsFILT = fpsFILT * .97 + fps * .03
        return fpsFILT

    def displayImage(self, frame, w, h, ch):
        bytes_per_line = ch * w
        image = QImage(frame.data, w, h, bytes_per_line,
                       QImage.Format.Format_RGB888)
                       
#        image = image.scaled(720, 480, Qt.AspectRatioMode.KeepAspectRatio)
        image = image.scaled(411, 301, Qt.AspectRatioMode.KeepAspectRatio)
        
# +++ ------------------------------> vvvvvvvvvvvv <------------------------        
        self.changePixmap.emit(image, self.fpsFILT)

    def stopCam(self):
        self.running = False
        

class MainWindow(QMainWindow):
    def __init__(self):
        super(MainWindow, self).__init__()
        loadUi("Test.ui", self)

        self.thread_1 = ThreadOpenCV(0)

        self.ui_StartCamera.clicked.connect(self.onCapture)
        self.ui_StopCamera.clicked.connect(self.offCapture)
        self.ui_StopCamera.setChecked(True)

        self.ui_text.setText("Привет")
        
        
# +++ ----------------------> vvvvvvvv <---------------------------------
    def setImage(self, image, _fpsFILT):
        self.ui_video.setPixmap(QPixmap.fromImage(image))
# +++        
        self.ui_text.setText(f"{_fpsFILT}")                           # +++

    def onCapture(self):
        self.thread_1.changePixmap.connect(self.setImage)
        self.thread_1.start()

    def offCapture(self):
        self.ui_StartCamera.setEnabled(True)
        self.thread_1.stopCam()


if __name__ == '__main__':
    app = QApplication(sys.argv)
    window = MainWindow()
    window.show()
    sys.exit(app.exec())

введите сюда описание изображения