частота кадров не верна в видео - PullRequest
0 голосов
/ 02 мая 2019

У меня 12-секундное видео с частотой 25 кадров в секунду.При воспроизведении видео со скоростью 25 кадров в секунду в opencv видео становится 16 сек.Я получаю fps с помощью fps = get (cv2.CAP_PROP_FPS), а затем устанавливаю waitKey (1000 / fps), но видео воспроизводится медленно ...

import numpy as np
import cv2
import time
start = time.time()

cap = cv2.VideoCapture("hackerman.mp4")
fps = cap.get(cv2.CAP_PROP_FPS)
print(fps)
while True:
    # Capture frame-by-frame
    ret, frame = cap.read()
    if ret == True:
        frame_new = frame
    else:
        end = time.time()
    # frame = cv2.cvtColor(frame, cv2.COLOR_BGR2GRAY) # turn video gray

    # Display the resulting frame
    cv2.namedWindow('frame', cv2.WINDOW_NORMAL)
    cv2.imshow('frame', frame_new)

    k = cv2.waitKey(int(round(1000/fps))) & 0xFF
    if k == 27:         # wait for ESC key to exit
        break
    elif cv2.getWindowProperty("frame", 0) == -1:
        break


print(end-start)
# When everything done, release the capture
cap.release()
cv2.destroyAllWindows()

1 Ответ

1 голос
/ 02 мая 2019

Похоже, что неоправданно cap.read () читает быстрее, чем частота кадров, что было бы очень желательно, если бы вы обрабатывали кадры, а не отображали их - поэтому в вашем приложении вам нужно добавить задержку, например, с помощью. time.sleep() или в вашем случае waitKey(), и это должно быть рассчитано для достижения частоты кадров 25 кадров в секунду.

Для наиболее точных 25 кадров в секунду основывайте время окончания следующего кадра на общем начальном времени, как показано ниже (не проверено):

frameref_ms = int(time.time()*1000)
frametime_ms = int(1000/fps)

while True:
    # update frameref to end frame period from now (regardless of how long reading and displaying the frame takes)
    frameref_ms += frametime_ms
    # Capture frame-by-frame
    ret, frame = cap.read()
    if ret == True:
        frame_new = frame
    else:
        end = time.time()
    # frame = cv2.cvtColor(frame, cv2.COLOR_BGR2GRAY) # turn video gray

    # Display the resulting frame
    cv2.namedWindow('frame', cv2.WINDOW_NORMAL)
    cv2.imshow('frame', frame_new)
    # wait for a keypress or the time needed to finish the frame duration
    k = cv2.waitKey(frameref_ms-int(time.time()*1000)) & 0xFF
    if k == 27:         # wait for ESC key to exit
        break
    elif cv2.getWindowProperty("frame", 0) == -1:
        break

Эта методика, состоящая в том, чтобы иметь абсолютное время для завершения отображения / чтения следующего кадра, означает, что частота кадров будет точной, автоматически компенсируя многозадачность других задач ОС, если эти другие задачи не занимают так много ЦП. что ваш код вряд ли работает, если вы столкнетесь с этой проблемой, я думаю, вам придется увеличить приоритет Python, что замедлит работу других программ. Я использовал этот метод при измерении времени для измерений температуры / вибрации, и он работает очень хорошо. См. Ту же технику в одном из моих ответов Неточное время цикла в Python

Если бы вы были действительно осторожны / пессимистичны, вы бы также проверили, что waitKey() не дается отрицательная задержка в случае, когда чтение кадра + отображение заняло больше времени, чем период кадра.

...