【问题标题】:Change FPS on video capture from file with opencv使用 opencv 从文件中更改视频捕获的 FPS
【发布时间】: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)?

标签: c++ opencv video frame-rate


【解决方案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 读取包含许多帧的数据块,而不是逐帧读取和处理帧)。

【讨论】:

    猜你喜欢
    • 2010-11-13
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2021-03-02
    • 2022-11-02
    • 2020-01-07
    • 2018-07-30
    • 2013-04-01
    相关资源
    最近更新 更多