Skip to content

Instantly share code, notes, and snippets.

@bsdnoobz
Last active December 22, 2023 18:20
Show Gist options
  • Star 27 You must be signed in to star a gist
  • Fork 9 You must be signed in to fork a gist
  • Save bsdnoobz/8464000 to your computer and use it in GitHub Desktop.
Save bsdnoobz/8464000 to your computer and use it in GitHub Desktop.
Displaying webcam feed using OpenCV and Python+PySide.
#!/usr/bin/env python
from PySide.QtCore import *
from PySide.QtGui import *
import cv2
import sys
class MainApp(QWidget):
def __init__(self):
QWidget.__init__(self)
self.video_size = QSize(320, 240)
self.setup_ui()
self.setup_camera()
def setup_ui(self):
"""Initialize widgets.
"""
self.image_label = QLabel()
self.image_label.setFixedSize(self.video_size)
self.quit_button = QPushButton("Quit")
self.quit_button.clicked.connect(self.close)
self.main_layout = QVBoxLayout()
self.main_layout.addWidget(self.image_label)
self.main_layout.addWidget(self.quit_button)
self.setLayout(self.main_layout)
def setup_camera(self):
"""Initialize camera.
"""
self.capture = cv2.VideoCapture(0)
self.capture.set(cv2.cv.CV_CAP_PROP_FRAME_WIDTH, self.video_size.width())
self.capture.set(cv2.cv.CV_CAP_PROP_FRAME_HEIGHT, self.video_size.height())
self.timer = QTimer()
self.timer.timeout.connect(self.display_video_stream)
self.timer.start(30)
def display_video_stream(self):
"""Read frame from camera and repaint QLabel widget.
"""
_, frame = self.capture.read()
frame = cv2.cvtColor(frame, cv2.cv.CV_BGR2RGB)
frame = cv2.flip(frame, 1)
image = QImage(frame, frame.shape[1], frame.shape[0],
frame.strides[0], QImage.Format_RGB888)
self.image_label.setPixmap(QPixmap.fromImage(image))
if __name__ == "__main__":
app = QApplication(sys.argv)
win = MainApp()
win.show()
sys.exit(app.exec_())
@mutenroshi2
Copy link

mutenroshi2 commented Apr 7, 2017

image
There is a huge memory leak when I run this code, I have changed the streaming resolution to 1920x1080. If the self.timer.start(30) is changed to 250 milliseconds, the memory leak is slower but still present. Any way to stop the mem leak?

@mutenroshi2
Copy link

mutenroshi2 commented May 2, 2017

 import qimage2ndarray
def display_video_stream(self):
    """Read frame from camera and repaint QLabel widget.
    """
    _, frame = self.capture.read()
    frame = cv2.cvtColor(frame, cv2.COLOR_BGR2RGB)
    frame = cv2.flip(frame, 1)
    image = qimage2ndarray.array2qimage(frame)  #SOLUTION FOR MEMORY LEAK
    self.image_label.setPixmap(QPixmap.fromImage(image))

@dauwan
Copy link

dauwan commented May 21, 2018

thanks for the solution ragu25

@achimmihca
Copy link

achimmihca commented Jul 31, 2021

Thanks for the example!
I don't see a memory leak using PySide6.

For PySide6:

from PySide6.QtCore import *
from PySide6.QtGui import *
from PySide6.QtWidgets import *
import cv2
import sys
...

requirements.txt (install via pip install -r "requirements.txt"):

pyside6==6.1.2
opencv-python==4.5.2.52

@AIWintermuteAI
Copy link

AIWintermuteAI commented Oct 10, 2021

It needed some editing to work with
pyside2 5.15.2
opencv-python 4.3.0.36
Here is updated version:

#!/usr/bin/env python

from PySide2.QtCore import *
from PySide2.QtGui import *
from PySide2.QtWidgets import *
import qimage2ndarray

import cv2
import sys

class MainApp(QWidget):

    def __init__(self):
        QWidget.__init__(self)
        self.video_size = QSize(320, 240)
        self.setup_ui()
        self.setup_camera()

    def setup_ui(self):
        """Initialize widgets.
        """
        self.image_label = QLabel()
        self.image_label.setFixedSize(self.video_size)

        self.quit_button = QPushButton("Quit")
        self.quit_button.clicked.connect(self.close)

        self.main_layout = QVBoxLayout()
        self.main_layout.addWidget(self.image_label)
        self.main_layout.addWidget(self.quit_button)

        self.setLayout(self.main_layout)

    def setup_camera(self):
        """Initialize camera.
        """
        self.capture = cv2.VideoCapture(0)
        self.capture.set(cv2.CAP_PROP_FRAME_WIDTH, self.video_size.width())
        self.capture.set(cv2.CAP_PROP_FRAME_HEIGHT, self.video_size.height())

        self.timer = QTimer()
        self.timer.timeout.connect(self.display_video_stream)
        self.timer.start(30)

    def display_video_stream(self):
        """Read frame from camera and repaint QLabel widget.
        """
        _, frame = self.capture.read()
        frame = cv2.cvtColor(frame, cv2.COLOR_BGR2RGB)
        frame = cv2.flip(frame, 1)
        image = qimage2ndarray.array2qimage(frame)  #SOLUTION FOR MEMORY LEAK
        self.image_label.setPixmap(QPixmap.fromImage(image))

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

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment