如何解决使用 CAP_PROP_POS_FRAMES 寻找帧时,几次调用后 opencv VideoCapture.read() 失败
我有一个使用 raspivid 生成的 .h264 格式的 20 秒视频文件。 我正在使用 opencv 在 python 中处理这个视频。 我可以一一处理每一帧,但我希望能够向前或向后跳转到特定帧,而无需将每一帧都存储在 RAM 中。
打开视频并一一处理和/或显示帧没有问题:
import cv2
import os
data_path = "my_folder"
video_path = os.path.join(data_path,"test.h264")
cap = cv2.VideoCapture(video_path)
frame_count = 0
while (True):
res,frame = cap.read()
if res:
frame_count += 1
cv2.imshow("camCapture",frame)
cv2.waitKey(25)
else:
break
print(frame_count)
cap.release()
cv2.destroyAllWindows()
它播放了,我得到了预期的 600 帧。
读取总帧数、当前帧索引或时间戳不起作用:
cap.get(cv2.CAP_PROP_POS_MSEC)
cap.get(cv2.CAP_PROP_POS_FRAMES)
cap.get(cv2.CAP_PROP_FRAME_COUNT)
它总是返回 0。目前这对我来说没有问题,但我觉得这很奇怪。
另一件事是,如果我在 VLC 播放器中打开视频,进度条总是显示 00:00/00:00。 VLC 显示 1 个丢帧。
当我尝试使用 this answer 中的代码实现搜索器时:
cap = cv2.VideoCapture(video_path)
length = int(cap.get(cv2.CAP_PROP_FRAME_COUNT))
length = 600 #overwrite because it is -192153584101141
def onChange(trackbarValue):
print(trackbarValue)
res = cap.set(cv2.CAP_PROP_POS_FRAMES,trackbarValue)
# grabbed = cap.grab()
# print(grabbed)
grabbed,img = cap.read()
if grabbed:
# err,img = cap.retrieve()
cv2.imshow("mywindow",img)
cv2.waitKey(1)
cv2.namedWindow('mywindow')
cv2.createTrackbar( 'start','mywindow',length,onChange )
onChange(0)
cv2.waitKey()
cap.release()
cv2.destroyAllWindows()
在第 10 帧更改时停止读取并读取。如果我前进,它会在第 10 帧停止。当我前进和后退时,它会在发生 10 帧更改后工作。这可能是缓冲区问题吗? CAP_PROP_BUFFERSIZE 读取为零,设置它也不会改变任何东西。
首先在 RAM 中加载所有帧是一种解决方法,但这不是我的首选解决方案。我还可以实现一个混合程序,它缓冲有限数量的帧,并在进一步返回时从头开始重置和查找,但这会使读取帧过于复杂。使用 RAM 方法一段时间后,我收到 RecursionError 和分段错误。这是我的 RAM 解决方法:
import sys
sys.setrecursionlimit(10000) # this eliminates the recursion error
cap = cv2.VideoCapture(video_path)
frame_array = []
while (True):
res,frame = cap.read()
if res:
frame_array.append(frame)
else:
break
cap.release()
print(len(frame_array))
# for frame in frame_array:
# cv2.imshow("camCapture",frame)
# cv2.waitKey(20)
# cv2.destroyAllWindows()
import time
def onChange(trackbarValue):
time.sleep(0.010) # this delay reduces occurrence of Segmentation fault
cv2.imshow("mywindow",frame_array[trackbarValue])
cv2.waitKey(1)
# time.sleep(0.1)
cv2.namedWindow('mywindow')
cv2.createTrackbar( 'start',len(frame_array)-1,onChange )
onChange(0)
cv2.waitKey()
cv2.destroyAllWindows()
如何让 cap.read() 再次返回帧?
版权声明:本文内容由互联网用户自发贡献,该文观点与技术仅代表作者本人。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如发现本站有涉嫌侵权/违法违规的内容, 请发送邮件至 dio@foxmail.com 举报,一经查实,本站将立刻删除。