Я успешно создал анимированный график, используя данные цикла opencv while. Движение на камере вычитается из фона, создавая белые пиксели, эти пиксели усредняются average_int
, а затем наносятся на график по оси y с использованием функции matplotlib FuncAnimation()
.
Проблема в том, что я хотел бы использовать программу для исследований, и графики слишком сильно отстают от видео, поэтому его нужно оптимизировать. Предполагается, что техника блитинга ускоряет процесс в 10 раз, но всякий раз, когда я пытаюсь использовать его в FuncAnimation(blit=True)
, повышение производительности не происходит, а график мигает и выключается и никогда не отображается правильно. Я не могу найти проблему. Я подумал, что, возможно, окна Matplotlib как-то мешают окнам opencv.
import numpy as np
import cv2
import matplotlib.pyplot as plt
import matplotlib.animation as animation
from scipy import signal
cap = cv2.VideoCapture(0)
_, first_frame = cap.read()
count = 0
peaks_frames = 1
peaks_diff = [1]
result_array = np.array([])
x_len = 60
x_len2 = 200
y_range = [-2, 100]
y2_range = [3, 12]
fig = plt.figure()
ax = fig.add_subplot(2,1,1)
ax2 = fig.add_subplot(2,1,2)
xs = list(range(0,60))
xs2 = list(range(0,200))
ys = [0] * x_len
ys2 = [0] * x_len2
line, = ax.plot(xs, ys, 'k')
line2, = ax2.plot(xs2, ys2,'b')
ax.set_ylim(y_range)
ax2.set_ylim(y2_range)
def animate(i, ys, ys2):
ys.append(average_int)
ys = ys[-x_len:]
line.set_ydata(ys)
ys2.append(peaks_frames)
ys2 = ys2[-x_len2:]
line2.set_ydata(ys2)
return line, line2
ani = animation.FuncAnimation(fig, animate, fargs=(ys, ys2),interval=120, blit=True)
while True:
ret, frame = cap.read( )
difference = cv2.absdiff(first_frame, frame)
difference = cv2.GaussianBlur(difference, (3, 3), 0)
_, difference = cv2.threshold(difference, 18, 255, cv2.THRESH_BINARY)
cv2.imshow('first frame (1)', first_frame)
cv2.imshow('Original', frame)
cv2.imshow('difference', difference)
average = (np.average(difference))
average_int = int(average)
result_array = np.append(result_array, average_int)
peaks_pos = signal.find_peaks_cwt(result_array, range(1,2,10))
peaks_diff = peaks_pos[1:] - peaks_pos[:-1]
count = count + 1
if count >= 30:
peaks_frames = peaks_diff[-1]
plt.pause(0.000001)
key = cv2.waitKey(30) & 0xff
if key == 27:
break
cap.release()
cv2.destroyAllWindows()