【发布时间】:2019-12-03 10:02:28
【问题描述】:
我想要的是从长视频(约 50 分钟和 30fps)中获取随机索引帧,以预处理图像以训练神经网络。 使用 opencv 加载存储的 png 图像大约需要 10 毫秒的时间。这确实很快,但是在考虑加载它们进行训练之前,您总是必须通过从中提取图像来预处理视频。 所以我的想法是只在我的 multiprocessing-keras-dataloader 中使用视频作为输入。 我已经能够在 cv.VideoCapture() 中设置帧索引并获取帧。问题是设置索引的速度很慢。抓取一帧大约需要 2-3 毫秒,这比加载存储的图像要快得多。问题是设置帧索引花费的时间太长,我不知道如何加速这个过程。
分割长视频不会带来任何性能。所需时间始终相同。
frame_set_timings = []
frame_read_timings = []
frames = []
batch_size = 10
video = '/mnt/sda/test_video.mp4'
cap = cv2.VideoCapture(video)
total_frames = int(cap.get(7)) # total number of frames
for i in range(batch_size):
random_frame = random.randrange(start=0, stop=total_frames) # get random frame number
start_frame_set = time.time()
cap.set(1, random_frame) # Set which frame to grab from the video
start_frame_read = time.time()
ret, frame = cap.read() # Read (grab) the image
end_frame_read = time.time()
frame_set_timings.append(float("{0:.4f}".format(start_frame_read - start_frame_set)))
frame_read_timings.append(float("{0:.4f}".format(end_frame_read - start_frame_read)))
frames.append(frame)
cap.release()
mean_frame_set = float("{0:.4f}".format(sum(frame_set_timings) / len(frame_set_timings)))
mean_frame_read = float("{0:.4f}".format(sum(frame_read_timings) / len(frame_read_timings)))
print('Frame set timings: {list}\nwith a mean time of: {mean}'.format(list=frame_set_timings,
mean=mean_frame_set))
print('Frame read timings: {list}\nwith a mean time of: {mean}'.format(list=frame_read_timings,
mean=mean_frame_read))
设置所需帧索引的平均持续时间约为 56 毫秒。帧抓取大约是 3 毫秒,这对我的目的来说真的很快。 我希望帧索引更快。也许我应该使用另一个编解码器,或者将视频转换为另一种格式(如 avi)会更快吗?
【问题讨论】:
-
现在我使用 avi 视频进行了测试,它将帧索引从 56 毫秒加速到 28 毫秒。读取时间现在是 4ms 而不是 2-3ms
-
我从未尝试过,也没有任何理由相信它一定会更快,但您可能会发现只寻找 forwards 会更快 在您的视频中。因此,您可以在循环之外生成您想要的一批帧号,并将它们按升序排序,看看是否有帮助......奇怪的事情发生了!
-
在压缩视频中查找通常涉及从最近的keyframe 线性遍历每一帧。您可以使用其他存储原始数据的编解码器(即库可以跳过
n_frames*bytes_per_frame字节并读取下一个图像,例如 ProRes)。但正如马克建议的那样,你能订购你的随机帧索引吗?这对于您的项目似乎是可行的。然后你可以线性地浏览视频,没有回溯,这应该会加快速度。 -
你有什么更新吗?我面临同样的问题,使用 opencv 从 mp4 视频中抓取帧非常慢。而如果我们直接在命令行中使用ffmpeg或从.mov文件中抓取帧,它会快得多。
标签: python opencv deep-learning video-processing