OpenCV/Python-获取特定的帧范围,CAP_PROP_POS_FRAMES不起作用



我需要从一个视频中获得一些连续帧组。这些组都是由相同数量的帧组成的,并且它们是连续的,所以类似于:

[10, 11, 12, 13, 14, 15],
[32, 33, 34, 35, 36, 37],
[123, 124, 125, 126, 127, 128]

这只是一个例子,在我的情况下,我事先不知道索引的范围,它们是在代码执行期间提供的

每次我必须提取给定范围中的帧时,我都尝试使用(例如,如这里所建议的(这个代码

video_capture = cv2.VideoCapture(video_path)
for frame_id in frames_range:
video_capture.set(cv2.CAP_PROP_POS_FRAMES, frame_ind)
success, image = video_capture.read()
if not success:
logging.warning(f"Error reading frame {frame_id}", frame_ind)
# do something with frames

但这不起作用,我通常总是得到视频的前N帧(N是范围的长度,在我的例子中是6(
我读到video_capture.set在某些情况下可能会由于视频压缩而失败,事实上,我在使用这种方法读取某些视频帧时遇到了一些错误。

另一种简单的方法是每次逐帧浏览视频,然后选择我需要的:

def get_required_frames(frames_range: list, video_cap) -> list:
frames = []
frame_counter = 0
while True:
ret, frame = video_cap.read()
if not ret:
return []
# collect frames in selected range
if frame_counter in frames_range:
frames.append(frame)
# after selected range, stop loop
if frame_counter > frames_range[-1]:
break
frame_counter += 1
return frames 
# every time I get the required range, I call this function
frames = get_required_frames(frames_range, cv2.VideoCapture(video_path))
# do something with frames

第二种方法还可以,但有点慢,因为我每次都必须从第0帧开始浏览整个视频,直到达到当前帧范围(有些视频可能很长(。考虑到帧范围总是连续的,有没有办法离开视频"悬挂";,以便至少我可以从先前帧范围中使用的最后一个位置重新开始?

我不确定这是否是在简化这篇文章的代码时创建的拼写错误,但这似乎是错误的:

for frame_id in frames_range:
video_capture.set(cv2.CAP_PROP_POS_FRAMES, frame_ind)

您正在从"frames_range"中获取"frame_id",但随后将video_capture的索引设置为"frame_ind"。

如果这不是问题所在,那么是的,您是对的——通过"CAP_PROP_POS_FRAMES"设置帧索引不一定可靠。在回答你的问题时,如果你能让视频拍摄"挂起",答案是肯定的。你应该能够做到以下几点:

cap = cv2.VideoCapture(video_path)
frames = get_required_frames(frames_range, cap)

当你再次阅读"cap"时,它应该在你离开的地方。

相关内容

  • 没有找到相关文章

最新更新