如何更新Qt ui以便从相机上显示opencv mat;

时间:2018-11-01 08:53:35

标签: qt opencv

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

1 个答案:

答案 0 :(得分:0)

只需将视频捕获周期移到另一个线程中,然后使用信号/插槽系统将帧发送到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();