Running OpenCV in a Python venv

I successfully setup a virtual environmentusing venv.If i run an opencv application with no multithreading whatsoever, it works fine. However whenever i try to use opencv with multithreading i get the following error:

QObject::moveToThread: Current thread (0x563e422f8180) is not the object's thread (0x563e4262c6d0).
Cannot move to target thread (0x563e422f8180)

qt.qpa.plugin: Could not load the Qt platform plugin "xcb" in "/home/brighton/PycharmProjects/qc/venv/lib/python3.8/site-packages/cv2/qt/plugins" even though it was found.
This application failed to start because no Qt platform plugin could be initialized. Reinstalling the application may fix this problem.

Available platform plugins are: xcb, wayland-org.kde.kwin.qpa, dxcb, xcb, eglfs, linuxfb, minimal, minimalegl, offscreen, vnc, wayland-egl, wayland, wayland-xcomposite-egl, wayland-xcomposite-glx.

fish: “python main.py” terminated by signal SIGABRT (Abort)

I am using the code below which i took from a blog to test if opencv is working correctly:

from PyQt5 import QtGui
from PyQt5.QtWidgets import QWidget, QApplication, QLabel, QVBoxLayout
from PyQt5.QtGui import QPixmap
import sys
import cv2
from PyQt5.QtCore import pyqtSignal, pyqtSlot, Qt, QThread
import numpy as np


class VideoThread(QThread):
    change_pixmap_signal = pyqtSignal(np.ndarray)

    def __init__(self):
        super().__init__()
        self._run_flag = True

    def run(self):
        # capture from web cam
        cap = cv2.VideoCapture(0)
        while self._run_flag:
            ret, cv_img = cap.read()
            if ret:
                self.change_pixmap_signal.emit(cv_img)
        # shut down capture system
        cap.release()

    def stop(self):
        """Sets run flag to False and waits for thread to finish"""
        self._run_flag = False
        self.wait()


class App(QWidget):
    def __init__(self):
        super().__init__()
        self.setWindowTitle("Qt live label demo")
        self.disply_width = 640
        self.display_height = 480
        # create the label that holds the image
        self.image_label = QLabel(self)
        self.image_label.resize(self.disply_width, self.display_height)
        # create a text label
        self.textLabel = QLabel('Webcam')

        # create a vertical box layout and add the two labels
        vbox = QVBoxLayout()
        vbox.addWidget(self.image_label)
        vbox.addWidget(self.textLabel)
        # set the vbox layout as the widgets layout
        self.setLayout(vbox)

        # create the video capture thread
        self.thread = VideoThread()
        # connect its signal to the update_image slot
        self.thread.change_pixmap_signal.connect(self.update_image)
        # start the thread
        self.thread.start()

    def closeEvent(self, event):
        self.thread.stop()
        event.accept()



    @pyqtSlot(np.ndarray)
    def update_image(self, cv_img):
        """Updates the image_label with a new opencv image"""
        qt_img = self.convert_cv_qt(cv_img)
        self.image_label.setPixmap(qt_img)
    
    def convert_cv_qt(self, cv_img):
        """Convert from an opencv image to QPixmap"""
        rgb_image = cv2.cvtColor(cv_img, cv2.COLOR_BGR2RGB)
        h, w, ch = rgb_image.shape
        bytes_per_line = ch * w
        convert_to_Qt_format = QtGui.QImage(rgb_image.data, w, h, bytes_per_line, QtGui.QImage.Format_RGB888)
        p = convert_to_Qt_format.scaled(self.disply_width, self.display_height, Qt.KeepAspectRatio)
        return QPixmap.fromImage(p)
    
if __name__=="__main__":
    app = QApplication(sys.argv)
    a = App()
    a.show()
    sys.exit(app.exec_())
1 Like

Did you try reinstalling?

I can't see xorg :sweat_smile: but if it was running fine earlier with xorg, that shouldn't be cause of exception.

Well, what I would suggest in this case is restoring from snapshot. Because KDE use PyQt5. It would be a bit too much chaotic, imo, to install previous version of pyqt5 and other modules in venv.

But wait a minute, why did not this code run in Python 3.9? It looks fine.
Can you post exception you got in Python 3.9 ?

2 Likes

@Naman I guess this isn't his project code. This is a test code being used by @brighton64 to check the proper functioning of the openCV. :wink:

1 Like

Yeah, but in any case, it should work fine with 3.9, imo.

2 Likes

This runs perfectly fine on Python 3.9. The problems comes when i try to install tensorflow.

What's the problem? Can you share the errors?

They havent released tensorflow for python 3.9 yet

Yeah that's why tensorflow is always preferred to be used inside a virtual environment :slightly_smiling_face:

When i try to use it in a virtual environment thats when opencv starts acting up!!

did you try reinstalling the plugins?

i tried reinstalling opencv by pip uninstall opencv-python then installed it using pip install opencv-python

Demo video Can you try out this small tweak? The demo here is done in windows but it might work on linux too.