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()