如何在 Qt 中抓取视频帧?
Posted
技术标签:
【中文标题】如何在 Qt 中抓取视频帧?【英文标题】:How to grab video frames in Qt? 【发布时间】:2015-08-28 07:52:25 【问题描述】:我是 Qt 新手,我只知道基础知识:创建接口和连接插槽。总之,我的知识一点也不深。
我需要打开一个视频文件并捕获其所有帧以获取 R、G、B 通道,然后逐帧处理光流(这已经完成)以最终将其呈现在窗口上。
是否可以使用 Qt 获取视频帧?我研究了很多,但没有发现任何结论。
【问题讨论】:
您查看文档了吗? doc.qt.io/qt-5/videooverview.html 这个link 可以帮助您从视频文件中捕捉帧。 【参考方案1】:您可以使用QMediaPlayer 来实现此目的。
-
实例化QMediaPlayer。
子类化QAbstractVideoSurface。
通过
QMediaPlayer::setVideoOutput
将您的实现设置为媒体播放器的输出。
为媒体播放器提供所需的文件,如果视频加载成功,它最终会开始调用QAbstractVideoSurface::present(const QVideoFrame & frame)
来执行QAbstractVideoSurface
。然后您可以从QVideoFrame 访问频道和所有内容,并在小部件上绘制框架。
【讨论】:
我在任何地方都找不到 QMediaPlayer。我已经通过 qt-unified-mac-x64-2.0.1-online.dmg 安装了 Qt,但我没有移动包 @Leo 它不应该出现在移动包中,只需将#include <QMediaPlayer>
添加到您的来源,并将QT += multimedia
添加到您的.pro
文件中,如doc.qt.io/qt-5/qmediaplayer.html 中所述。另外我不熟悉 osx 版本,但 2.0.1 似乎很奇怪 - 它是哪个 qt 版本?【参考方案2】:
我不知道为什么我不能包含必要的 Qt 标头来处理帧(它们似乎总是有未解决的依赖关系,有些不存在)所以我转向 OpenCV 3.0 并这样做:
cv::VideoCapture cap(videoFileName);
if(!cap.isOpened()) // check if we succeeded
return;
while (cap.isOpened())
cv::Mat frame;
cap >> frame;
cv::flip(frame, frame, -1);
cv::flip(frame, frame, 1);
// get RGB channels
w = frame.cols;
h = frame.rows;
int size = w * h * sizeof(unsigned char);
unsigned char * r = (unsigned char*) malloc(size);
unsigned char * g = (unsigned char*) malloc(size);
unsigned char * b = (unsigned char*) malloc(size);
for(int y = 0; y < h;y++)
for(int x = 0; x < w; x++)
// get pixel
cv::Vec3b color = frame.at<cv::Vec3b>(cv::Point(x,y));
r[y * w + x] = color[2];
g[y * w + x] = color[1];
b[y * w + x] = color[0];
cap.release();
它非常适合我的目的,所以我没有继续研究。
还是谢谢。
【讨论】:
以上是关于如何在 Qt 中抓取视频帧?的主要内容,如果未能解决你的问题,请参考以下文章