Warning: file_get_contents(/data/phpspider/zhask/data//catemap/9/opencv/3.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
Opencv 视频中的帧速率不正确_Opencv_Frame Rate - Fatal编程技术网

Opencv 视频中的帧速率不正确

Opencv 视频中的帧速率不正确,opencv,frame-rate,Opencv,Frame Rate,我有一个25帧每秒12秒的视频。当我在opencv中以25 fps的速度播放视频时,视频变为16秒。我通过使用 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_FP

我有一个25帧每秒12秒的视频。当我在opencv中以25 fps的速度播放视频时,视频变为16秒。我通过使用 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()

似乎cap.read()的读取速度比帧速率快,如果您正在处理帧而不是显示帧,这将是非常理想的-因此在应用程序中,您需要使用例如
time.sleep()
或在您的情况下
waitKey()添加延迟
这必须计算为达到25fps的帧速率

对于最精确的25fps,将下一帧结束的时间基于总开始时间,如下所示(未测试):

这种有绝对时间来完成显示/读取下一帧的技术意味着帧速率将是精确的,自动补偿多任务其他操作系统任务,只要这些其他任务不占用太多CPU以至于代码难以运行,如果您遇到了这个问题,我想您将不得不提高Python的优先级,这将减慢其他程序的速度。我使用这种方法对温度/振动测量进行定时采样,效果非常好。在我的一个答案中看到同样的技巧


如果你真的很小心/悲观,你也应该检查一下
waitKey()
在帧读取+显示时间超过帧周期的情况下,不会被给予负延迟。

您正在按顺序读取和显示每一帧,然后暂停40ms-因此,在显示前一帧之前,不会捕获下一帧,即总速度将低于25fps。如果您不使用
waitKey(1000/fps)
,它的运行速度有多快?@barny您必须使用waitKey,否则视频将无法显示,脚本将在1.8秒内运行。如果我设置waitkey(1),使用waitkey(1000/25)需要3.8秒,需要13.8秒,所以基本上视频太长了1.8秒!这太棒了!多聪明的解决方案啊。正如您所说,如果考虑到执行这个
k=cv2.waitKey(frameref_ms-int(time.time()*1000))&0xFF(如果k==27:#等待ESC键退出break-elif-cv2.getWindowProperty(“frame”,0),我想可以得到更好的估计==-1:break
但是整个视频的差异似乎是2毫秒,所以没有那么大的差异waitkey调用延迟的变化只会影响单帧显示持续时间的抖动,您不会注意到。您可以通过在
waitKey()
调用中以微秒为单位工作并仅转换为毫秒来提高亚毫秒精度,但不要期望太高-您的Linux/Windows主机不是实时系统。我检查了执行上述代码所需的时间,大约为1毫秒,因此我使用了waitKey(frameref\u ms-int(time.time()*1000)-1). 现在我的视频是12.0004秒,没有从waitkey删除1毫秒,它大约是12.001秒:)在最后一次迭代中,执行waitkey的时间将增加到总时间,但例如,120秒的视频将是120.001秒,即不会因为执行waitkey而出现速率错误。对于Linux/Windows向人播放视频而言,1ms是完全可以忽略的。
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