Home > Net >  Resize livestream frame size from camera Pyqt5
Resize livestream frame size from camera Pyqt5

Time:11-23

I have created three windows using pyqt5. They are as given below.

1. Main Window

enter image description here

When the start button is clicked, the next window opens, which is as given below.

2. Middle Window

enter image description here

This window accepts the streaming link to connect the camera. For normal usb cameras it is '0'. When 0 is given as input, next window opens.

3.Output Window

enter image description here

The problem that I am facing here is that I am not able to resize the size of the output frame, although I am able to resize the screen size.

** The code for the last window is attached below,**

import sys
from PyQt5.QtGui import *
from PyQt5.QtWidgets import *
from PyQt5.QtCore import *
import cv2
class Ui_OutputDialog(QWidget):
    def __init__(self):
        super(Ui_OutputDialog, self).__init__()

        self.VBL = QVBoxLayout()

        self.FeedLabel = QLabel()
        self.VBL.addWidget(self.FeedLabel)

        self.CancelBTN = QPushButton("Cancel")
        self.CancelBTN.clicked.connect(self.CancelFeed)
        self.VBL.addWidget(self.CancelBTN)

        self.Worker1 = Worker1()

        self.Worker1.start()
        self.Worker1.ImageUpdate.connect(self.ImageUpdateSlot)
        self.setLayout(self.VBL)

    def ImageUpdateSlot(self, Image):
        self.FeedLabel.setPixmap(QPixmap.fromImage(Image))

    def CancelFeed(self):
        self.Worker1.stop()

class Worker1(QThread):
    ImageUpdate = pyqtSignal(QImage)
    def run(self):
        self.ThreadActive = True
        Capture = cv2.VideoCapture(0)
        while self.ThreadActive:
            ret, frame = Capture.read()
            if ret:
                Image = cv2.cvtColor(frame, cv2.COLOR_BGR2RGB)
                FlippedImage = cv2.flip(Image, 1)
                ConvertToQtFormat = QImage(FlippedImage.data, FlippedImage.shape[1], FlippedImage.shape[0], QImage.Format_RGB888)
                Pic = ConvertToQtFormat.scaled(720, 480, Qt.KeepAspectRatio)
                self.ImageUpdate.emit(Pic)
    def stop(self):
        self.ThreadActive = False
        self.quit()

if __name__ == "__main__":
    App = QApplication(sys.argv)
    Root = Ui_OutputDialog()
    Root.show()
    sys.exit(App.exec())

The code for the first file is attached herewith

import sys
from PyQt5.uic import loadUi
from PyQt5 import QtWidgets
from PyQt5.QtCore import pyqtSlot
from PyQt5.QtWidgets import QApplication, QDialog
import resource
from middlewindow import Ui_MiddleDialog 

class Ui_Dialog(QDialog):
    def __init__(self):
        super(Ui_Dialog, self).__init__()
        loadUi("mainwindow.ui", self)

        self.main_click.clicked.connect(self.runmiddlewindow)


    def runmiddlewindow(self):
        """
        Called when the user presses the Run button
        """
        print("Clicked Run")
        ui.hide()  # hide the main window
        self.middleWindow_()  # Create and open new output window

    def middleWindow_(self):
        """
        Created new window for vidual output of the video in GUI
        """
        self._new_window = Ui_MiddleDialog()
        self._new_window.show()
        #self._new_window.startVideo(self.Videocapture_)
        #print("Video Played")


if __name__ == "__main__":
    app = QApplication(sys.argv)
    ui = Ui_Dialog()
    ui.show()
    sys.exit(app.exec_())

The UI for the first file is attached herewith

<?xml version="1.0" encoding="UTF-8"?>
<ui version="4.0">
 <class>Dialog</class>
 <widget class="QDialog" name="Dialog">
  <property name="geometry">
   <rect>
    <x>0</x>
    <y>0</y>
    <width>508</width>
    <height>259</height>
   </rect>
  </property>
  <property name="minimumSize">
   <size>
    <width>508</width>
    <height>259</height>
   </size>
  </property>
  <property name="maximumSize">
   <size>
    <width>508</width>
    <height>259</height>
   </size>
  </property>
  <property name="windowTitle">
   <string>Face Recognition Time Attendance App</string>
  </property>
  <property name="windowIcon">
   <iconset>
    <normaloff>:iconer.png</normaloff>:iconer.png</iconset>
  </property>
  <property name="styleSheet">
   <string notr="true">background-color: rgb(255, 255, 255);
border-color: rgb(0, 0, 0);</string>
  </property>
  <widget class="QWidget" name="verticalLayoutWidget_2">
   <property name="geometry">
    <rect>
     <x>40</x>
     <y>20</y>
     <width>436</width>
     <height>224</height>
    </rect>
   </property>
   <layout class="QGridLayout" name="gridLayout">
    <item row="2" column="0">
     <widget class="QPushButton" name="main_click">
      <property name="font">
       <font>
        <family>Roboto Condensed Light</family>
        <pointsize>13</pointsize>
       </font>
      </property>
      <property name="styleSheet">
       <string notr="true">background-color: rgb(170, 0, 0);
background-color: qlineargradient(spread:pad, x1:0, y1:0, x2:1, y2:0, stop:0 rgba(0, 0, 0, 255), stop:1 rgba(255, 255, 255, 255));
border-color: rgb(8, 8, 8);
background-color: rgb(147, 147, 147);</string>
      </property>
      <property name="text">
       <string>START</string>
      </property>
     </widget>
    </item>
    <item row="1" column="0">
     <layout class="QHBoxLayout" name="horizontalLayout_3">
      <item>
       <widget class="QLabel" name="logolabel_2">
        <property name="styleSheet">
         <string notr="true">border-color: rgb(11, 11, 11);</string>
        </property>
        <property name="text">
         <string/>
        </property>
        <property name="pixmap">
         <pixmap>loger.png</pixmap>
        </property>
       </widget>
      </item>
      <item>
       <widget class="QLabel" name="filelabel_3">
        <property name="enabled">
         <bool>true</bool>
        </property>
        <property name="font">
         <font>
          <family>Roboto Condensed</family>
          <pointsize>14</pointsize>
          <weight>75</weight>
          <bold>true</bold>
         </font>
        </property>
        <property name="styleSheet">
         <string notr="true">border-color: rgb(12, 12, 12);
border-color: rgb(0, 0, 0);</string>
        </property>
        <property name="text">
         <string>&lt;html&gt;&lt;head/&gt;&lt;body&gt;&lt;p&gt;&lt;span style=&quot; color:#1113aa;&quot;&gt;BARCODE SCANNER&lt;/span&gt;&lt;/p&gt;&lt;/body&gt;&lt;/html&gt;</string>
        </property>
       </widget>
      </item>
     </layout>
    </item>
   </layout>
  </widget>
 </widget>
 <resources>
  <include location="resource.qrc"/>
  <include location="resource.qrc"/>
 </resources>
 <connections/>
</ui>

The code for the second file is attached herewith

from PyQt5.QtGui import QImage, QPixmap
from PyQt5.uic import loadUi
from PyQt5.QtCore import pyqtSlot, QTimer
from PyQt5.QtWidgets import QDialog
import cv2
import numpy as np
import datetime
import os
from lastwindow import Ui_OutputDialog

class Ui_MiddleDialog(QDialog):
    def __init__(self):
        
        super(Ui_MiddleDialog, self).__init__()
        loadUi("./middlewindow.ui", self)
        

        self.press.clicked.connect(self.connect_camera)
        self._new_window = None


    def runmiddlewindow(self):
    
        print("Clicked Run")
        #print(self.Videocapture_)
    
    def connect_camera(self):
        
        stream = self.stream.text()
        self.Videocapture_ = stream
        #ui.hide()  # hide the main window
        self.outputWindow_()  # Create and open new output window

    def outputWindow_(self):
        
        self._new_window = Ui_OutputDialog()
        self._new_window.show()
        #self._new_window.controlTimer(self.Videocapture_)
        

The UI file for the second file is attached herewith

<?xml version="1.0" encoding="UTF-8"?>
<ui version="4.0">
 <class>Dialog</class>
 <widget class="QDialog" name="Dialog">
  <property name="geometry">
   <rect>
    <x>0</x>
    <y>0</y>
    <width>508</width>
    <height>259</height>
   </rect>
  </property>
  <property name="minimumSize">
   <size>
    <width>508</width>
    <height>259</height>
   </size>
  </property>
  <property name="maximumSize">
   <size>
    <width>508</width>
    <height>259</height>
   </size>
  </property>
  <property name="windowTitle">
   <string>Face Recognition Time Attendance App</string>
  </property>
  <property name="windowIcon">
   <iconset>
    <normaloff>iconer.png</normaloff>iconer.png</iconset>
  </property>
  <property name="styleSheet">
   <string notr="true">border-color: rgb(7, 7, 7);</string>
  </property>
  <widget class="QLineEdit" name="stream">
   <property name="geometry">
    <rect>
     <x>10</x>
     <y>120</y>
     <width>481</width>
     <height>24</height>
    </rect>
   </property>
  </widget>
  <widget class="QPushButton" name="press">
   <property name="geometry">
    <rect>
     <x>0</x>
     <y>190</y>
     <width>511</width>
     <height>36</height>
    </rect>
   </property>
   <property name="font">
    <font>
     <family>Roboto Condensed Light</family>
     <pointsize>13</pointsize>
    </font>
   </property>
   <property name="styleSheet">
    <string notr="true">background-color: rgb(170, 0, 0);
background-color: qlineargradient(spread:pad, x1:0, y1:0, x2:1, y2:0, stop:0 rgba(0, 0, 0, 255), stop:1 rgba(255, 255, 255, 255));
border-color: rgb(8, 8, 8);
background-color: rgb(147, 147, 147);</string>
   </property>
   <property name="text">
    <string>CONFIRM</string>
   </property>
  </widget>
  <widget class="QLabel" name="label">
   <property name="geometry">
    <rect>
     <x>10</x>
     <y>40</y>
     <width>491</width>
     <height>51</height>
    </rect>
   </property>
   <property name="text">
    <string>&lt;html&gt;&lt;head/&gt;&lt;body&gt;&lt;p align=&quot;center&quot;&gt;&lt;span style=&quot; font-size:12pt; font-weight:600; color:#1113aa;&quot;&gt;ENTER THE STREAMLINK TO CONNECT&lt;/span&gt;&lt;/p&gt;&lt;/body&gt;&lt;/html&gt;</string>
   </property>
  </widget>
 </widget>
 <resources>
  <include location="../Face_Detection_PyQt_Final/resource.qrc"/>
 </resources>
 <connections/>
</ui>

CodePudding user response:

Reimplement resizeEvent to set the size the image should be scaled to. You need to set the layout's size constraint to SetNoConstraint in order to make the window smaller as well as larger. You should also release the capture after stopping.

class Ui_OutputDialog(QWidget):
    def __init__(self):
        super(Ui_OutputDialog, self).__init__()

        self.VBL = QVBoxLayout()

        self.FeedLabel = QLabel()
        self.VBL.addWidget(self.FeedLabel)

        self.CancelBTN = QPushButton("Cancel")
        self.CancelBTN.clicked.connect(self.CancelFeed)
        self.VBL.addWidget(self.CancelBTN)

        self.Worker1 = Worker1()
        
        self.Worker1.start()
        self.Worker1.ImageUpdate.connect(self.ImageUpdateSlot)
        self.setLayout(self.VBL)

        self.VBL.setSizeConstraint(QLayout.SetNoConstraint)
        self.resize(720, 480)

    def resizeEvent(self, event):
        super().resizeEvent(event)
        self.Worker1.size = self.FeedLabel.size()

    def ImageUpdateSlot(self, Image):
        self.FeedLabel.setPixmap(QPixmap.fromImage(Image))

    def CancelFeed(self):
        self.Worker1.stop()
        

class Worker1(QThread):
    ImageUpdate = pyqtSignal(QImage)
    def run(self):
        self.ThreadActive = True
        Capture = cv2.VideoCapture(0)
        while self.ThreadActive:
            ret, frame = Capture.read()
            if ret:
                Image = cv2.cvtColor(frame, cv2.COLOR_BGR2RGB)
                FlippedImage = cv2.flip(Image, 1)
                ConvertToQtFormat = QImage(FlippedImage.data, FlippedImage.shape[1], FlippedImage.shape[0], QImage.Format_RGB888)
                Pic = ConvertToQtFormat.scaled(self.size, Qt.KeepAspectRatio)
                self.ImageUpdate.emit(Pic)
                
        Capture.release()
        
    def stop(self):
        self.ThreadActive = False
        self.quit()
  • Related