使用 opencv 从文件中更改视频捕获的 FPS

Posted

技术标签:

【中文标题】使用 opencv 从文件中更改视频捕获的 FPS【英文标题】:Change FPS on video capture from file with opencv 【发布时间】:2016-12-07 19:18:09 【问题描述】:

我正在读取一个视频文件,即使我没有对图像进行任何处理,它也比文件的实际 FPS (59 FPS @1080p) 慢:

       using namespace cv;
       using namespace std;
       // Global variables
        UMat frame; //current frame
        int main(int argc, char** argv)
        

                VideoCapture capture("myFile.MP4");
                namedWindow("Frame");
                capture.set(CAP_PROP_FPS, 120); //not changing anything
                cout>>capture.get(CAP_PROP_FPS);
                while (charCheckForEscKey != 27) 

                       capture >>frame;
                if (frame.empty())
                    break;
                imshow("Frame", frame);

                

    

即使我尝试将 CAP_PROP_FPS 设置为 120,它也不会改变文件的 fps,当我得到 (CAP_PROP_FPS) 时,我仍然得到 59.9...

当我阅读视频时,实际结果或多或少是 54 FPS(即使使用 UMat)。

有没有办法以更高的 FPS 速率读取文件?

我也在opencv问答网站上问过他问题:http://answers.opencv.org/question/117482/change-fps-on-video-capture-from-file/

只是因为我的电脑太慢了吗?

【问题讨论】:

在互联网上搜索“双缓冲”,一个线程正在写入缓冲区而另一个线程正在读取缓冲区的概念。可以使用多个缓冲区来调整速度。 从文件中读取,FPS 只是您可以使用的元数据。 VideoCapture 尽可能快地解码帧。 @ThomasMatthews 谢谢我去检查 @DanMašek,谢谢,但是为什么使用普通的 videoReader 我可以得到更快的显示(例如 VLC)? 【参考方案1】:

TL;DR FPS 与问题无关,可能是性能问题

FPS 用于什么? 在显示单帧视频之前,您必须读取数据(从 HDD、DVD、网络、互联网或其他任何地方)并对其进行解码。这两种操作都需要时间,具体时间取决于系统的速度,取决于 HDD/Internet 的速度、处理器速度等。如果我们只是在准备好后立即显示每一帧,那么最终的电影速度将,因此,因系统而异。这通常不是我们想要的,所以除了视频帧的序列,我们得到“每秒帧数”值(a.k.a.FPS),它告诉我们应该多快显示每个连续帧(每 1/30 次30 FPS 为 1 秒,60 FPS 为每 1/60 秒一次,依此类推)如果帧已准备好显示但为时过早,我们可以等到时间到来。如果是时候显示一个帧但它还没有准备好(在一个功率不足/太忙的系统上),我们无能为力(在某些情况下可能会丢帧)。自己看看效果,尝试改变 x2 的 FPS 值,保存文件并用 VLC 显示:对于相同的数据量和相同的帧数,您会注意到您的视频速度增加了一倍,时间- 减半。尝试为您的 x2 FPS 写入每帧两次 - 您会看到播放速度恢复正常(帧数翻倍并且文件大小无意义地增加)。

FPS不用于什么?在处理(不显示)视频时,我们不受原始FPS的限制,处理速度尽可能快。如果您的 PC 可以每秒处理 1000 帧 - 很好,如果 1500 - 更好。不用说,更改文件中的 FPS 值不会提高您的 CPU/HDD 速度,因此如果您每秒只能处理 54 帧,那么您仍然只能每秒处理 54 帧。

但是 VLC 怎样才能显示得更快呢? 假设您没有忘记在测量时间之前从 Debug 切换到 Release 构建,仍然有很多可能性:VLC 可能更适合特定的视频播放任务(OpenCV 在某些任务中并不是那么快,而且它必须将每一帧转换为更通用的 Mat/UMat 结构),多线程(包括 cmets 中提到的“双缓冲”)是另一个可能的原因,也许也可以缓存(例如,一次从 HDD 读取包含许多帧的数据块,而不是逐帧读取和处理帧)。

【讨论】:

以上是关于使用 opencv 从文件中更改视频捕获的 FPS的主要内容,如果未能解决你的问题,请参考以下文章

使用 C++/OpenCV 从 100fps GoPro .mp4 视频创建 25fps 慢动作视频

用Python从屏幕捕获视频数据

在 OpenCV 上输入更高分辨率的视频文件时 fps 低

如何使用 opencv 和多线程 (logitech c920) 在 python 中捕获视频

OpenCV3学习笔记整理(二期)

OpenCV VideoCapture 有时会返回空白帧