如何在 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 中抓取视频帧?的主要内容,如果未能解决你的问题,请参考以下文章

如何通过 Qt gui 应用程序显示视频的帧?

opencv中如何将从视频中抓取的帧释放掉

Qt 视频采集

如何访问 WPF 应用程序中的视频卡帧缓冲区?

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

altera公司FPGA的视频流帧抓取