Я хотел бы построить некоторые 3D-значения в режиме реального времени по маркерам ArUco, но я не могу показать график из Matplotlib 3.1.1 параллельно с OpenCV imshow()
, потому что они блокируют друг друга. Я также попытался запустить два отдельных потока, но появляется только пустой Pyplot. Я читал, что plt.show()
, plt.pause()
и некоторые другие блокируют программу, но я также пытался обновить фигуру с помощью метода canvas.flush_events()
, но все же не повезло.
Моя идея состояла в том, чтобы запуститьцикл while для Pyplot в его собственном потоке и помещает новые значения позиции в очередь, потому что я знаю, что это потокобезопасно. К сожалению, это полный беспорядок.
# Thread for camera
CamLoop = threading.Thread(name = 'CamLoop', target = CamMain(), daemon = True)
CamLoop.start()
plotter = Plotting()
# Thread for plotting (only with animating array from file)
PlotLoop = threading.Thread(name = 'PlotLoop', target = plotter.plotout('results/file.npz'), daemon = True)
PlotLoop.start()
И ниже необходимых функций из класса Plotting. Это работает само по себе, оно анимирует позиции из файла, но оно начинает строить только после уничтожения захвата видео с cv2.imshow()
. Я хотел бы иметь график Axes3D, где я могу обновить его новыми значениями в фоновом режиме, не блокируя видеопоток. (Я также читал об анимации в Matplotlib, но это скорее для целых наборов данных, а не для обновления новыми значениями.)
def __init__(self):
plt.ion()
fig = plt.figure()
self.ax = fig.add_subplot(111, projection='3d')
plt.show()
def plotout(self, file):
with np.load(file) as X:
tvec = X['tvecs']
xp=tvec[:,0]
yp=tvec[:,1]
zp=tvec[:,2]
maxval=max((max(xp),max(yp),max(zp)))
minval=min((min(xp),min(yp),min(zp)))
self.ax.set_xlim([minval,maxval])
self.ax.set_ylim([minval,maxval])
self.ax.set_zlim([minval,maxval])
bx_prev, by_prev, bz_prev = self.plotCoordSys(np.array([[0, 0, 0]]), np.array([[0.,0.,0.]]))
i = 0
while(True):
# Queue for future real-time run
# if not self.pos_queue.empty():
# q=self.pos_queue.get()
bx_prev.remove()
by_prev.remove()
bz_prev.remove()
if i < len(xp):
# Moving a coordinate system on the camera positions (origin, rotation) given
bx, by, bz = self.plotCoordSys(np.array([[xp[i],yp[i],zp[i]]]), np.array([[0.,0.,0.]]))
self.ax.add_artist(bx)
self.ax.add_artist(by)
self.ax.add_artist(bz)
bx_prev = bx
by_prev = by
bz_prev = bz
else:
break
i += 1
plt.pause(0.04)
Любой, кто имеет опыт отображения Matplotlib, не блокирует основную программу отвыполнение? Или какие-то другие идеи, где изобразить положение камеры, полученное от OpenCV?
Спасибо!