使用OpenCV';从视频中抓取慢速图像(帧);s视频捕获和Python

使用OpenCV';从视频中抓取慢速图像(帧);s视频捕获和Python,python,opencv,deep-learning,video-processing,Python,Opencv,Deep Learning,Video Processing,我想要的是从一个长视频(约50分钟30帧)中绘制随机索引帧,目的是对图像进行预处理以训练神经网络。 使用opencv加载存储的png图像大约需要10毫秒的时间。这真的很快,但在考虑加载视频进行训练之前,您必须始终通过从视频中提取图像的方式对视频进行预处理。 所以我的想法是在我的多处理keras数据加载器中只使用视频作为输入。 我已经能够在cv.VideoCapture()中设置帧索引并获取帧。问题是设置索引的速度太慢。抓取一帧大约需要2-3毫秒,这比加载存储的图像快得多。问题是设置帧索引花费的时

我想要的是从一个长视频(约50分钟30帧)中绘制随机索引帧,目的是对图像进行预处理以训练神经网络。 使用opencv加载存储的png图像大约需要10毫秒的时间。这真的很快,但在考虑加载视频进行训练之前,您必须始终通过从视频中提取图像的方式对视频进行预处理。 所以我的想法是在我的多处理keras数据加载器中只使用视频作为输入。 我已经能够在cv.VideoCapture()中设置帧索引并获取帧。问题是设置索引的速度太慢。抓取一帧大约需要2-3毫秒,这比加载存储的图像快得多。问题是设置帧索引花费的时间太长,我不知道如何加快这个过程

分割长视频不会带来性能。所需的时间总是相同的

frame\u set\u计时=[]
帧读取时间=[]
帧=[]
批量大小=10
视频='/mnt/sda/test_video.mp4'
cap=cv2.视频捕获(视频)
总帧数=整数(上限get(7))#总帧数
对于范围内的i(批次大小):
随机帧=随机。随机范围(开始=0,停止=总帧)#获取随机帧编号
start\u frame\u set=time.time()
cap.set(1,随机帧)#设置要从视频中抓取的帧
start\u frame\u read=time.time()
ret,frame=cap.read()#读取(抓取)图像
end\u frame\u read=time.time()
frame\u set\u timings.append(float({0:.4f}).format(start\u frame\u read-start\u frame\u set)))
frame\u read\u timings.append(float({0:.4f}).format(end\u frame\u read-start\u frame\u read)))
frames.append(frame)
第1章释放()
mean_frame_set=float(“{0:.4f}”。格式(和(帧集定时)/len(帧集定时)))
mean_frame_read=float(“{0:.4f}”。格式(总和(frame_read_计时)/len(frame_read_计时)))
打印('Frame set timings:{list}\n平均时间:{mean}'。格式(list=Frame\u set\u timings,
平均值=平均值(帧集)
打印('Frame read timings:{list}\n平均时间:{mean}'。格式(list=Frame\u read\u timings,
平均值=平均值(帧(读取))
设置所需帧索引的平均持续时间约为56ms。抓拍画面的速度大约是3毫秒,这对我来说真的很快。
我希望帧索引速度更快。也许我应该使用另一种编解码器,或者将视频转换成另一种格式(如avi)会更快吗?

好的,我找到了一种昂贵的解决方法

我使用rawvideo编解码器和以下命令将mp4视频转换为带有FFMPEG的原始视频:

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硬盘的情况下缩小尺寸?

现在我使用avi视频进行了测试,它将帧索引从56ms加速到28ms。读取时间现在是4ms,而不是2-3ms。我从未尝试过这种方法,也没有理由相信它一定会更快,但你可能会发现,只在视频中寻找转发会更快。所以你可以在循环外生成你想要的一批帧号,并将它们按递增顺序排序,看看这是否有帮助。。。奇怪的事情发生了!在压缩视频中搜索通常涉及从最近的视频中线性遍历每一帧。您可以使用存储原始数据的其他编解码器(即,库可以跳过
n帧*字节/u帧
字节,然后读取下一个图像,例如ProRes)。但正如马克所建议的,你能为你的随机帧索引排序吗?这对你的项目来说似乎是可行的。然后你可以线性地浏览视频,而不需要回溯,这应该会加快速度。也许你可以用更频繁的关键帧重新编码视频,这不会造成空间浪费,但可能会加快搜索速度。@MarkSetchell是的,这可能是一个选项。但我真的不熟悉高性能的编解码器和文件格式。我将尝试使用此处描述的一些编解码器和格式: