使用OpenCV的VideoCapture和Python从视频中获取慢速图像(帧)

时间:2019-07-25 07:37:09

标签: python opencv deep-learning video-processing image-reader

我想要的是从长视频(〜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))

设置所需帧索引的平均持续时间为〜56ms。抓帧时间约为3毫秒,这对于我来说确实非常快。 我希望帧索引会更快。也许我应该使用其他编解码器,还是将视频转换为avi等其他格式会更快?

1 个答案:

答案 0 :(得分:0)

好吧,我发现了一个昂贵的解决方法...

我正在使用rawvideo编解码器和以下命令通过FFMPEG将mp4视频转换为原始视频:

ffmpeg -i input.mp4 -an -vf scale=768:512 -c:v rawvideo output.3gp

但是现在我的视频大小从18MB增加到750MB。有点奇怪,目前我不知道如何减小输出的大小。

但是: 6个随机帧的加载时间也从〜500ms减少到〜20ms。那真是太棒了,而且我没有想到很好的结果。

问题:我有271个mp4视频,总大小为200GB。如果我计算所有视频的faktor为42,则我的输出将总共有大约8400GB的数据量。

有什么想法如何在不购买12GB硬盘的情况下减小此大小?