使用 C++ 加载视频和抓取图像的最佳方式

Posted

技术标签:

【中文标题】使用 C++ 加载视频和抓取图像的最佳方式【英文标题】:Best way to load in a video and to grab images using c++ 【发布时间】:2011-09-16 17:38:10 【问题描述】:

我正在寻找一种快速加载视频文件并以特定时间间隔(每秒、每分钟、每小时等)从中创建图像的方法。

我尝试使用 DirectShow,但运行速度太慢,我无法启动视频文件并移动到某个位置以获取数据并将其保存到图像中。即使我禁用了参考时钟。尝试过 OpenCV,但除非我知道确切的编解码器信息,否则它无法打开 AVI 文件。因此,如果我知道一种从 OpenCV 中获取编解码器信息的方法,我可能会再试一次。我尝试使用 FFMPEG,但对它的控制并不如我所愿。

任何建议将不胜感激。这是在 Windows 机器上开发的,因为它必须托管在 Windows 机器上。

【问题讨论】:

什么文件格式和什么编解码器?如果是 WMV,可以使用 Windows Media Format SDK。 大部分视频都是使用 MPEG-4 格式的 AVI。虽然我们确实有一些 FLV 文件。 AVI 只是位图的集合。您可以在播放期间截屏和 bitblt,或者找到可以为您提取帧的库。 OpenCV 本身使用 DirectShow 或 FFMPEG 来读取视频,因此与它们相比它不会给您任何加速。 @AJG85 - 不完全正确。传统上,AVI 是没有压缩 (bmps) 的文件。但文件格式可扩展以托管来自流编解码器的视频。在 Seb 的例子中,他有 MPEG 视频的 AVI 文件。 【参考方案1】:

MPEG-4 格式不是帧内编码格式,因此您不能只跳到随机帧并自行解码,因为大多数帧只编码与一个或多个其他帧的差异。我怀疑您的解码速度很慢,因为当您降落在首先要解码其他几个依赖帧的帧上时。

提高性能的一种方法是确定哪些帧是关键帧(有时也称为“同步”点)并将解码限制在这些帧,因为这些帧可以自行解码。

我对 DirectShow 功能不是很熟悉,但我希望它有一些 API 来公开同步点。

另外,我应该提到 Windows 上的 QuickTime SDK 可能是您从电影中解码帧的另一个不错的选择。您应该首先测试您的 AVI 电影是否在 QuickTime Player 中正确播放。 QT SDK 确实公开了同步点,请参阅 QT SDK 文档中的 Finding Interesting Times 部分。

【讨论】:

我将如何使用它来获取所需的每个指定帧?就像我需要每帧每秒或每 30 秒的图像一样。 嗯,这很棘手。您需要找到最接近目标帧的关键帧。您可能必须决定您愿意走多远,如果最近的关键帧太远,您可能别无选择,只能以更高的成本解码目标帧。 我玩过 QT SDK,但没有得到我想要的结果。我主要是尝试创建一个在后台运行的控制台应用程序,而我可以在网上找到的唯一示例让我创建了一个 Windows 应用程序。有什么方法可以“伪造”渲染,以便只处理视频? 看看这个示例应用程序:developer.apple.com/library/mac/#samplecode/MovieGWorlds 感谢您的所有帮助。这似乎可以很好地满足我的需要。【参考方案2】:

ffmpeg 的 libavformat 可能对你有用...

【讨论】:

以上是关于使用 C++ 加载视频和抓取图像的最佳方式的主要内容,如果未能解决你的问题,请参考以下文章

opencv4opencv视频教程 C++(opencv教程)2加载,修改,保存图像

使用增强现实录制视频的最佳方式是什么?

如何在 Windows 8 现代应用程序上从视频流中抓取帧?

来自视频文件的简单图像采集卡[重复]

动态抓取vedio元素帧显示,点击帧图像跳转回放视频

将视频文件加载到 C++ 中的缓冲区中