使用 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 慢动作视频