В документах указано:
Примечание
За этой функцией должна следовать функция waitKey, которая отображает изображение в течение указанных миллисекунд. В противном случае он не будет отображать изображение. Например, waitKey (0) будет отображать окно бесконечно до любого нажатия клавиши (это подходит для отображения изображения). waitKey (25) будет отображать кадр в течение 25 мс, после чего дисплей будет автоматически закрыт. (Если вы поместите его в цикл для чтения видео, оно покажет видео за кадром)
В cv2.waitKey(X)
функция X
означает количество миллисекунд для изображения, которое будетотображается на экране. В вашем случае это значение равно 1, поэтому теоретически вы можете достичь 1000 кадров в секунду (кадров в секунду). Но декодирование кадров занимает время в VideoCapture
объекте и ограничивает вашу частоту кадров. Чтобы изменить скорость воспроизведения, вам нужно объявить переменную и использовать ее в качестве параметра в функции waitKey
.
import cv2
cap = cv2.VideoCapture('video.mp4')
frameTime = 10 # time of each frame in ms, you can add logic to change this value.
while(cap.isOpened()):
ret, frame = cap.read()
cv2.imshow('frame',frame)
if cv2.waitKey(frameTime) & 0xFF == ord('q'):
break
cap.release()
cv2.destroyAllWindows()
В качестве альтернативы, поскольку декодирование кадров является наиболее трудоемкой задачей, вы можете переместить ее во второй поток. и использовать очередь декодированных кадров. Смотрите эту ссылку для деталей.
Третий подход состоит в том, чтобы разделить процесс захвата и декодирования и просто декодировать каждый n-й кадр. Это приведет к отображению только поднабора кадров из исходного видео, но с точки зрения пользователя видео будет воспроизводиться быстрее.
import cv2
cap = cv2.VideoCapture('video.mp4')
i=0 #frame counter
frameTime = 1 # time of each frame in ms, you can add logic to change this value.
while(cap.isOpened()):
ret = cap.grab() #grab frame
i=i+1 #increment counter
if i % 3 == 0: # display only one third of the frames, you can change this parameter according to your needs
ret, frame = cap.retrieve() #decode frame
cv2.imshow('frame',frame)
if cv2.waitKey(frameTime) & 0xFF == ord('q'):
break
cap.release()
cv2.destroyAllWindows()