我想要的是从长视频(〜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等其他格式会更快?
答案 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硬盘的情况下减小此大小?