是否可以在OpenCV中向后播放视频? 通过API调用或缓冲视频帧并将顺序反转为 一个新的视频文件。
由于
答案 0 :(得分:19)
唯一可行的方法是手动提取帧,缓冲它们(在内存或文件上),然后以相反的顺序重新加载它们。
问题在于视频压缩器都在利用时间冗余 - 两个连续帧在大多数情况下非常相似的事实。因此,他们不时编码一个完整的帧(通常每几百帧),然后只发送前一个和当前的差异。
现在,为了解码工作,它必须以相同的顺序完成 - 解码一个关键帧(一个完整的),然后为每个新帧添加差异以获得当前图像。
这种策略很难在视频中反向播放。有几种技术,但都涉及缓冲。
现在,您可能已经看到了Astor描述的CV_CAP_PROP_POS_FRAMES参数。看起来没问题,但由于上述问题,OpenCV无法正确跳转到特定的框架(在这些问题上存在多个错误)。他们(OpenCV开发者)正在研究一些解决方案,但即使这些解决方案也会很慢(它们涉及回到之前的关键帧,然后解码回选定的关键帧)。如果使用这种技术,每帧必须平均解码数百次,这使得它非常慢。然而,它不起作用。
修改强> 如果你采用缓冲方式来反转它,请记住,解码后的视频会迅速吞噬普通计算机的内存资源。解压缩时,通常720p视频一分钟需要 4.7GB 的内存!将帧作为单个文件存储在磁盘上是解决此问题的实用方法。
答案 1 :(得分:2)
另一种类似于ArtemStorozhuk's answer的解决方案是使用FPS从帧域移动到时域,然后使用CV_CAP_PROP_POS_MSEC
向后搜索(这不会像{{1}那样锤击CPU }} 能够)。这是我的示例代码,它完全适用于.mpg,只使用大约50%的CPU。
CV_CAP_PROP_POS_FRAMES
答案 2 :(得分:1)
是的,这是可能的。请参阅带注释的代码:
//create videocapture
VideoCapture cap("video.avi");
//seek to the end of file
cap.set(CV_CAP_PROP_POS_AVI_RATIO, 1);
//count frames
int number_of_frames = cap.get(CV_CAP_PROP_POS_FRAMES);
//create Mat frame and window to display
Mat frame;
namedWindow("window");
//main loop
while (number_of_frames > 0)
{
//decrease frames and move to needed frame in file
number_of_frames--;
cap.set(CV_CAP_PROP_POS_FRAMES, number_of_frames);
//grab frame and display it
cap >> frame;
imshow("window", frame);
//wait for displaying
if (waitKey(30) >= 0)
{
break;
}
}
另请阅读this文章。