0

I try to open a video "example.mp4" and get the coordinates of an object (selected by creating a square on the first frame). I use a tracker by OpenCV, and therefore installed the module opencv-contrib-python.

When plotting the position with matplotlib, I get the following error:

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

qt.qpa.plugin: Could not load the Qt platform plugin "xcb" in "/home/user/.local/lib/python3.10/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, eglfs, linuxfb, minimal, minimalegl, offscreen, vnc, wayland-egl, wayland, wayland-xcomposite-egl, wayland-xcomposite-glx.

I can't see any plot.

I saw that this kind of problems was already encountered (How to fix the error "QObject::moveToThread:" in opencv in python?) but I was unable to install the module with no-binaries neither to downgrade opencv-contrib-python in a good version so I wouldn't have this error. My distrib is Archcraft (made on top of Archlinux).

Here is the code I run:

import cv2
import matplotlib.pyplot as plt
import numpy as np

tracker = tracker = cv2.TrackerCSRT_create()
video = cv2.VideoCapture("example.mp4")

# Read first frame.
ok, frame = video.read()
bbox = cv2.selectROI(frame, False)
ok = tracker.init(frame, bbox)

x=[]
y=[]

while True:
    ok, frame = video.read()
    if not ok:
        break
    
    timer = cv2.getTickCount()
    ok, bbox = tracker.update(frame)

    # Draw bounding box
    if ok:
        # Tracking success
        p1 = (int(bbox[0]), int(bbox[1]))
        p2 = (int(bbox[0] + bbox[2]), int(bbox[1] + bbox[3]))
        cv2.rectangle(frame, p1, p2, (255,0,0), 2, 1)

        x.append((p1[0]+p2[0])/2)
        y.append((p1[1]+p2[1])/2)
    else :
        # Tracking failure
        cv2.putText(frame, "Tracking failure detected", (100,80), cv2.FONT_HERSHEY_SIMPLEX, 0.75,(0,0,255),2)

    # Display result
    cv2.imshow("Tracking", frame)

    # Exit if ESC pressed
    k = cv2.waitKey(1) & 0xff
    if k == 27 : break

fig , ax = plt.subplots(figsize=(13,4))
ax.plot(np.arange(len(x)), x, "o", label="x")
ax.plot(np.arange(len(y)), y, "o", label="y")
plt.show()

EDIT 1: Minimal reproductible example

import cv2
import matplotlib.pyplot as plt

video = cv2.VideoCapture("example.mp4")

while True:
    ok, frame = video.read()
    if not ok:
        break

fig , ax = plt.subplots()
plt.show()
TrissN
  • 35
  • 8
  • 1
    can you prepare a [mre]? I'm wondering whether OpenCV is required to reproduce this, or it's just an issue with matplotlib. – Christoph Rackwitz Mar 01 '22 at 17:27
  • I just edited my post to give you a minimal reproductible example. The error has something to deal with the interaction between opencv and matplotlib. Without matplotlib, it works. – TrissN Mar 01 '22 at 20:40
  • `xcb` seems to be important. on Windows, it all works okay. someone with a suitable linux needs to reproduce this. if you could add the specific versions of the packages (matplotlib, opencv, ...) and their origins (PyPI? a specific OS package source?) to your question, that might help someone to pin this down. – Christoph Rackwitz Mar 01 '22 at 22:34
  • 1
    What backend do you have installed: PyQt5 or PySide2? If you don't have any install the first one, then: add `from PyQt5.QtCore import QLibraryInfo` before `import cv2` and add `os.environ["QT_QPA_PLATFORM_PLUGIN_PATH"] = QLibraryInfo.location( QLibraryInfo.PluginsPath )` after `import matplotlib.pyplot as plt` – eyllanesc Mar 02 '22 at 00:18

0 Answers0