Acelerar el trazado en vivo de un material de archivo (cv2)

Estoy intentando usar el módulo cv2 para crear un diagtwig de dispersión en vivo para cada cuadro de un video. El código de abajo hace exactamente eso.

Sin embargo, con más de 8 minutos de imágenes que contienen más de 60000 fotogtwigs para procesar, el código no es eficiente y toma mucho más tiempo del necesario para obtener la salida deseada.

vidcap = cv2.VideoCapture(filepath) fig, ax = plt.subplots(1) plt.ion() x=df["time"][7:100] y=df["force"][7:100] for i in range(len(x)): vidcap.set(1,590) ret, image = vidcap.read() frameId = vidcap.get(1) plt.imshow(image,extent=[0,200,0,100], aspect='auto') plt.subplot(221) plt.plot(x[0+i:1+i],y[0+i:1+i],'or', lw=2) plt.subplot(222) fig.set_size_inches(20, 10) plt.pause(.000001) plt.draw() 

He considerado usar pyqtgraph para boost la velocidad del proceso. ¿Hay una mejor manera de procesar y trazar en un cuadro de un video?

La respuesta de esta pregunta muestra dos formas de obtener un video en matplotlib.

El punto principal es no recrear la ttwig completa en cada iteración. Si utiliza el segundo enfoque de esa respuesta, el uso de blit=True puede boost la velocidad aún más. Esto se muestra en el siguiente código.

 import cv2 import pandas as pd import numpy as np import matplotlib.pyplot as plt from matplotlib.animation import FuncAnimation df = pd.DataFrame({"time": np.linspace(0,20, num=100), "force" : np.cumsum(np.random.randn(100))}) def grab_frame(cap): ret,frame = cap.read() return frame # or cv2.cvtColor(frame,cv2.COLOR_BGR2RGB) #Initiate vidcap = cv2.VideoCapture(0) # vidcap.set(1,590) fig, (ax,ax2) = plt.subplots(ncols=2,figsize=(20, 10)) x=df["time"][7:100] y=df["force"][7:100] #create two image plots im1 = ax.imshow(grab_frame(vidcap),extent=[0,200,0,100], aspect='auto') line, = ax2.plot(x[0:1],y[0:1],'or') ax2.set_xlim(x.min(), x.max()) ax2.set_ylim(y.min(), y.max()) def update(i): im1.set_data(grab_frame(vidcap)) line.set_data(x[0+i:1+i],y[0+i:1+i]) return im1, line ani = FuncAnimation(fig, update, frames=len(x), interval=1, blit=True) plt.show()