使用OpenCV寻找视频文件中的随机点似乎比Windows Media Player或VLC等媒体播放器慢得多。我试图使用VideoCapture
在H264(或MPEG-4 AVC(part10))中编码的视频文件上寻找不同的位置,并且寻找该位置所花费的时间似乎与查询的帧编号成比例。这是我尝试做的一个小代码示例:
import cv2
cap = cv2.VideoCapture('example_file')
frame_positions = [200, 400, 8000, 200000]
for frame_position in frame_positions:
cap.set(cv2.cv.CV_CAP_PROP_FRAMES, frame_position)
img = cap.read()
cv2.imshow('window', img)
cv2.waitKey(0)
从上方显示图像的感知时间与帧数成比例。也就是说,帧数200和400,几乎没有任何延迟,8000有一些明显的滞后,但200000将花费将近半分钟。
为什么OpenCV无法快速寻找""如Windows Media Player?可能是OpenCV在搜索时没有正确使用FFMPEG编解码器吗?是否可以从具有替代配置的编解码器的源构建OpenCV?如果是这样,有人可以告诉我配置是什么吗?
我只在Windows 7和10台PC上测试了这个,OpenCV二进制文件,系统路径中有相关的FFMPEG DLL。
另一个观察结果:OpenCV(二进制文件)版本大于2.4.9(例2.4.11,3.3.0),第一次搜索工作,但不是后续工作。也就是说,它可以从上面的例子中寻求框架200,但不是400和其余的框架;视频只是跳回到第0帧。但是因为它适用于2.4.9,我现在很高兴。
答案 0 :(得分:1)
这可能是因为这是一个非常基本的代码示例,并且所提到的应用程序正在做一些更聪明的事情。
几点:
如果搜索速度很重要,那么在进行视频操作时,you almost definitly want to work会使用GPU:
https://github.com/opencv/opencv/blob/master/samples/gpu/video_reader.cpp
答案 1 :(得分:0)
GPU加速与搜寻无关紧要,因为您不是在解码帧。另外,即使您正在解码帧,在GPU上执行此操作的速度也要比在CPU上慢,因为当今的CPU将视频编解码器“焊接”到芯片中,这使得视频解码非常快,并且必须进行一些簿记,才能将数据从主内存铲入GPU。
听起来OpenCV实现了一种“安全”的搜索方式:视频文件可以包含流偏移量。例如,您的音频流可能会与视频流发生冲突。再举一个例子,您可能已经切除了视频的开头并保存了结果。如果剪切并非恰好发生在关键帧上,则ffmpeg之类的视频编辑软件会在剪切前 在输出文件中包含少量帧,以允许剪切发生的帧正确解码(可能需要先前的帧)。在这种情况下,也会出现流偏移。
为了确保以正确的方式解释此类偏移,即相对于“时间0”真正准确地击中所需的帧,唯一的“简便”但昂贵的方法是真正地吃饱并解码所有内容视频帧。显然,这就是openCV在这里所做的。您的视频播放器不必为此烦恼,因为日常用户不会注意到,而且GUI中的控件反而是不精确的。
我可能对此有误。但是对other questions的回答以及我进行的一些评估实验表明,只有对视频中的帧进行计数的“缓慢”方式才能得出准确的结果。
答案 2 :(得分:0)
以下是一些相关的github问题:
https://github.com/opencv/opencv/issues/4890
https://github.com/opencv/opencv/issues/9053
使用ffmpeg重新编码视频。它对我有用。