OpenCV Python и Matplotlib параллельное обновление с потоками? - PullRequest
0 голосов
/ 19 октября 2019

Я хотел бы построить некоторые 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?

Спасибо!

Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...