close
First, set up OpenCV building environments
INCLUDEPATH += C:\OpenCV\OpenCV4.2.0DNN\include
LIBS += -LC:\OpenCV\OpenCV4.2.0DNN\lib \
-lopencv_world420
Since Qt doesn’t recognise Mat data type that we have to register it
before we start using signal and slot mechanics.
Syntax: qRegisterMetaType<T>("typeName");
qRegisterMetaType helps us to register a new typeName called “cv::Mat&”
and its Type is corresponding to <T>, ie. <cv::Mat>
Besides, followed by a while loop, we notify ui to receive two inputs,
including frame and m_counter. The observer(ui) is notified by a singalFrameGrabbed
whenever there are new incoming frame and counter, both of which are emitted by m_capImg.
mainwindow.h
#ifndef MAINWINDOW_H#define MAINWINDOW_H#include <QMainWindow>#include <captureimage.h>#include <QtConcurrent/QtConcurrent>#include <QCloseEvent>#include <QMessageBox>QT_BEGIN_NAMESPACE
namespace Ui { class MainWindow; }
QT_END_NAMESPACE
class MainWindow : public QMainWindow
{Q_OBJECT
public:MainWindow(QWidget *parent = nullptr);
~MainWindow();
private:Ui::MainWindow *ui;
CaptureImage *m_capImg;
void StartCamera();public slots:void slotFrameGrabbed(cv::Mat& frame, int counter);
private slots: void on_pushButton_start_clicked(); void on_pushButton_stop_clicked(); void closeEvent(QCloseEvent *event);};
#endif // MAINWINDOW_H
mainwindow.cpp
The above shows connection between signalFrameGrabbed and slotFrameGrabbed is established.
Besides we want to run StartCamera in a sperate thread by using QtConcurrent::run().
#include "mainwindow.h"
#include "mainwindow.h"
#include "ui_mainwindow.h"
//Q_DECLARE_METATYPE(cv::Mat)MainWindow::MainWindow(QWidget *parent)
: QMainWindow(parent)
, ui(new Ui::MainWindow){ ui->setupUi(this);}
MainWindow::~MainWindow()
{ delete ui;}
void MainWindow::slotFrameGrabbed(cv::Mat& frame, int counter)
{ auto w = ui->label_image->width(); auto h = ui->label_image->height();ui->label_image->setPixmap(
QPixmap::fromImage(
QImage(frame.data, frame.cols, frame.rows, frame.step, QImage::Format_BGR888)
).scaled(w, h, Qt::KeepAspectRatio)
);
ui->label_counter->setText(QString::number(counter));
}
void MainWindow::on_pushButton_start_clicked(){ //m_capImg->Start(); m_capImg = new CaptureImage();connect(m_capImg, SIGNAL(signalFrameGrabbed(cv::Mat&, int)), this, SLOT(slotFrameGrabbed(cv::Mat&, int)));
QtConcurrent::run(this, &MainWindow::StartCamera);}
void MainWindow::StartCamera(){m_capImg->Start();
}
void MainWindow::on_pushButton_stop_clicked(){m_capImg->Stop();
}
void MainWindow::closeEvent (QCloseEvent *event){QMessageBox::StandardButton resBtn =
QMessageBox::question( this, "CaptureApp",
tr("Are you sure?\n"),QMessageBox::Cancel | QMessageBox::No | QMessageBox::Yes, QMessageBox::Yes);
if (resBtn != QMessageBox::Yes) {event->ignore();
} else {event->accept();
if(m_capImg!=nullptr) {m_capImg->Stop();
delete m_capImg;}
}
}
You can drag the windows form to any place and the picture keeps refreshing, because the frame acquistion of m_capImg is running in a separate thread.
References:
1. How to run a function in a separate thread in Qt Window App
2. How to load and display an image on Qt GUI with OpenCV 4.2.0
3. Qt: How do I handle the event of the user pressing the 'X' (close) button?
全站熱搜








留言列表
