首页 > 解决方案 > 如何更新 Qt ui 以从相机显示 opencv mat;

问题描述

我想使用 QLabel 类显示来自相机的每一帧(一个 OpenCV Mat),但 update()不能连续显示图像,所以我使用repain();但这里有一个问题,我的 ui 无法移动,其他按钮无法单击,所以如果我想显示一个视频,我该怎么做;使用opencv和qt和vs;提前致谢!

标签: qtopencv

解决方案


只需将您的视频捕获周期移动到另一个线程中,然后使用信号/插槽系统将帧发送到 gui 线程。

线

class VideoThread : public QThread
{
    Q_OBJECT
public:
    VideoThread(QObject *parent = nullptr);

protected:
    void run();

signals:
    void frameCaptured(cv::Mat frame);
};

void VideoThread::run()
{
    VideoCapture cap(0);

    if(!cap.isOpened()){
        qDebug() << "Cant capture video";
        return ;
      }

      while(1){

        Mat frame;
        cap >> frame;

        if (frame.empty()) {
            qDebug() << "Empty frame";
            break;
        }

        emit frameCaptured(frame);
      }
}

使用

MainWindow::MainWindow(QWidget *parent) :
    QMainWindow(parent),
    ui(new Ui::MainWindow)
{
    ui->setupUi(this);

    connect(&m_videoThread, &VideoThread::frameCaptured,
            this, &MainWindow::OnFrameCaptured);
}

void MainWindow::OnFrameCaptured(const cv::Mat &frame)
{
    QImage imgIn= QImage((uchar*) frame.data, frame.cols, frame.rows, frame.step, QImage::Format_RGB888);
    ui->lblVideo->setPixmap(QPixmap::fromImage(imgIn));
}

不要忘记注册元类型

qRegisterMetaType<cv::Mat>("cv::Mat");

并运行线程

m_videoThread.start();

推荐阅读