Capture OpenCV video and present it on QVideoWidget
Solved
Qt for Python
-
Hello everyone ! I am trying to capture the output of a webcam and present it to a
QVideoWidget
using the following :import sys import cv2 from PyQt5.QtMultimedia import QVideoFrame, QVideoSurfaceFormat from PyQt5.QtMultimediaWidgets import QVideoWidget from PyQt5.QtWidgets import QWidget, QApplication, QVBoxLayout from PyQt5.QtCore import pyqtSignal, pyqtSlot, Qt, QThread, QSize from PyQt5.QtGui import QImage class Thread(QThread): changePixmap = pyqtSignal(QImage) def run(self): cap = cv2.VideoCapture(0) while True: ret, frame = cap.read() if ret: # https://stackoverflow.com/a/55468544/6622587 rgbImage = cv2.cvtColor(frame, cv2.COLOR_BGR2RGB) h, w, ch = rgbImage.shape bytesPerLine = ch * w convertToQtFormat = QImage(rgbImage.data, w, h, bytesPerLine, QImage.Format_RGB888) p = convertToQtFormat.scaled(600, 600, Qt.KeepAspectRatio) self.changePixmap.emit(p) class VideoPlayer(QWidget): def __init__(self, parent=None): super(VideoPlayer, self).__init__(parent) self.videoWidget = QVideoWidget() self.video_surface = self.videoWidget.videoSurface() video_surface_format = QVideoSurfaceFormat(QSize(600, 600), QVideoFrame.pixelFormatFromImageFormat(QImage.Format_RGB888)) self.video_surface.start(video_surface_format) layout = QVBoxLayout() layout.addWidget(self.videoWidget) self.setLayout(layout) th = Thread(self) th.changePixmap.connect(self.update_image) th.start() @pyqtSlot(QImage) def update_image(self, image): self.video_surface.present(QVideoFrame(image)) if __name__ == '__main__': app = QApplication(sys.argv) player = VideoPlayer() player.setWindowTitle("Player") player.resize(600, 600) player.show() sys.exit(app.exec_())
However I get a black frame and immediately a grey (like there is no output). I get no warnings or errors on the console.
An insight on this issue would be highly appreciated !Thank you
-
Hi,
th is local to your
__init__
. It will be destroyed when out of scope. -
In
PySide
we have a similar example (without the capture part) https://doc.qt.io/qtforpython/examples/example_external__opencv.html and there we do useself.th = Thread(self)
so I second @SGaist comment.