【问题标题】:How to grab video frames in Qt?如何在 Qt 中抓取视频帧?
【发布时间】:2015-08-28 07:52:25
【问题描述】:

我是 Qt 新手,我只知道基础知识:创建接口和连接插槽。总之,我的知识一点也不深。

我需要打开一个视频文件并捕获其所有帧以获取 R、G、B 通道,然后逐帧处理光流(这已经完成)以最终将其呈现在窗口上。

是否可以使用 Qt 获取视频帧?我研究了很多,但没有发现任何结论。

【问题讨论】:

标签: c++ image qt4 video-processing opticalflow


【解决方案1】:

您可以使用QMediaPlayer 来实现此目的。

  1. 实例化QMediaPlayer
  2. 子类化QAbstractVideoSurface
  3. 通过QMediaPlayer::setVideoOutput 将您的实现设置为媒体播放器的输出。
  4. 为媒体播放器提供所需的文件,如果视频加载成功,它最终会开始调用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();

它非常适合我的目的,所以我没有继续研究。

还是谢谢。

【讨论】:

    猜你喜欢
    • 1970-01-01
    • 2013-03-18
    • 1970-01-01
    • 2019-11-17
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多