0

我的总体目标是使用 Raspberry Pi HQ 相机拍摄视频。当使用终端和标准 raspivid 命令(如raspivid -w 640 -h 480 -fps 90 -t 10000 -o video.h264生成的视频)时,未存储有关 fps(和 frame_count)的正确信息。我使用以下代码使用openCV和python对其进行了检查:

import cv2

cap = cv2.VideoCapture('video.h264')

if cap.isOpened():

    fps = cap.get(cv2.CAP_PROP_FPS)

    print('fps:', fps)  # float `fps`

    frame_count = cap.get(cv2.CAP_PROP_FRAME_COUNT)

    print('frames count:', frame_count)  # float `frame_count`

我希望它是 fps:90.0 和 frame_count:900.0,但它是 fps:25.0 和 frame_count:-192153584101141.0。

经过一些研究,我得出结论,.h264 不存储正确的 fps 值,而是存储默认值(在我的情况下为 25.0 fps)。

现在我的下一个尝试是使用 openCV 和 python 用 HQ 摄像头捕捉视频。我尝试使用以下代码来执行此操作(尝试使用 openCV 捕获视频时这几乎是标准的):

import numpy as np
import cv2

#had to use (-1,cv2.CAP_V4L) instead of (0) for it to find my HQ Camera
cap = cv2.VideoCapture(-1,cv2.CAP_V4L)

fourcc = cv2.VideoWriter_fourcc(*'XVID')
out = cv2.VideoWriter('video_out.avi', fourcc, 30.0, (640, 480))

while(cap.isOpened()):
    ret, frame = cap.read()
    if ret==True:
        out.write(frame)
        cv2.imshow('frame', frame)
        if cv2.waitKey(1) & 0xFF == ord('q'):
            break
    else:
        break
cap.release()
out.release()
cv2.destroyAllWindows()

现在录制大约 10 秒时。长视频,然后使用与以前相同的方法对其进行分析,结果符合预期 fps:30.0 和 frame_count:(大约)300.0。

现在,将第 8 行中的 fps 从 30 更改为 60out = cv2.VideoWriter('video_out.avi', fourcc, 30.0, (640, 480))out = cv2.VideoWriter('video_out.avi', fourcc, 60.0, (640, 480))分析大约 10 秒。之后的长视频结果与预期的不同。结果不是 fps:60.0 和 frame_count:(大约)600.0,而是 fps:60.0 和 frame_count:(大约)300.0。此外,视频现在只有 5 秒。长而不是 10 秒。

我得出的结论是,视频仍然以 30 fps 和 10 秒的速度录制。记录总数300帧是正确的。但是在 video_out.avi 文件中,fps 设置为 60 fps,这导致(60 fps)视频只有一半的时间,因为总共仍然只有 300 帧可用。

现在剩下的问题是:

我以哪种方式更改上面的代码,以便能够捕获 10 秒。60 fps 的长视频,总共获得 600 帧?

编辑#1

@Tiphel 在他的评论中表示,添加 cap.set(cv2.CAP_PROP_FPS, 10) 可以解决问题;它似乎奏效了。我现在尝试以某种方式编辑代码,它记录之前定义的时间(例如 5 秒)然后停止。通过这样做,我可以验证是否有 5 秒的 60 fps 视频。的记录确实有 300 帧。此尝试导致以下代码:

import numpy as np
import cv2
import time

f=open("fps_and_time_passed.txt", "w")

cap = cv2.VideoCapture(-1,cv2.CAP_V4L)
cap.set(cv2.CAP_PROP_FPS, 30)

fourcc = cv2.VideoWriter_fourcc(*'XVID')
out = cv2.VideoWriter('vid_out.avi', fourcc, 30.0, (640, 480))

capture_time=5.0
start_time=time.time()

while(time.time() - start_time < capture_time):
    
    #print time passed in console
    #print('time passed: ' + str(time.time()-start_time))
    
    #write time passed in .txt file
    f.write('time passed: ' + str(time.time()-start_time) + ' ')
    
    fps=cap.get(cv2.CAP_PROP_FPS)
    
    #print fps in console
    #print('fps: ',fps)
    
    #write fps in .txt file
    f.write('fps: ' + str(fps) + '\n')
    ret, frame = cap.read()
    if ret==True:
        out.write(frame)
        cv2.imshow('frame', frame)       
        #if cv2.waitKey(1) & 0xFF == ord('q'):
        #    break
    else:
        break
f.close()
cap.release()
out.release()
cv2.destroyAllWindows()

在分析了现在生成的“vid_out.avi”文件后,我预计它是 fps:30.0 和 frame_count 150.0,但它是 fps:30.0 和 frame_count:115.0。然后我查看了“fps_and_time_passed.txt”文件,令我惊讶的是,大约有 1.4 秒。一开始的延迟:

time passed: 1.1682510375976562e-05 fps: 30.0
time passed: 1.4038400650024414 fps: 30.0
time passed: 1.4290287494659424 fps: 30.0
time passed: 1.4499273300170898 fps: 30.0
...
time passed: 4.89248514175415 fps: 30.0
time passed: 4.925801515579224 fps: 30.0
time passed: 4.9621946811676025 fps: 30.0
time passed: 4.995436191558838 fps: 30.0

如您所见,延迟介于第一个和第二个输出之间。

所以我的新问题是:

我怎样才能摆脱这种延迟?

4

1 回答 1

0

我认为这是因为您在捕获第一帧之前启动计时器,因此您最终没有达到所需的持续时间。

我相信,如果您根据所需的视频持续时间计算帧数,您将获得所需的输出。

尝试类似:

fps = 30
capture_time = 5.0
n_frames = capture_time * fps
curr_frame = 0

while (curr_frame < n_frames):
    ret, frame = cap.read()
    if ret==True:
        out.write(frame)
        cv2.imshow('frame', frame)       
    else:
        break

    fps=cap.get(cv2.CAP_PROP_FPS)  
    #write fps in .txt file
    f.write('fps: ' + str(fps) + '\n')

    curr_frame+=1

我没有测试过这个,它可能不起作用,但就是这样。

于 2021-06-02T13:55:00.283 回答