QT與opencv(二)——開啟攝像頭
阿新 • • 發佈:2018-12-15
OpenCV中的VideoCapture不僅可以開啟視訊、usb攝像頭,還可以做很多事,例如讀取流媒體檔案,網路攝像頭,影象序列等。
下面我簡單介紹一個在Qt中用VideoCapture類開啟膝上型電腦自帶攝像頭。
(我用的是VS2015+QT5.8+Opencv3.2)
主要用到下面兩個函式
//獲取預設攝像頭 videocapture = new VideoCapture(0); //把攝像頭獲取到的某一幀影象傳給 Mat matFrame videocapture->read(matFrame);
然後 我們用Qt裡面的Qtimer類定時獲取影象,實現連續的每一幀影象的獲取,再把Mat顯示在介面裡面就好啦。
MainWindow.cpp
#pragma execution_character_set("utf-8") #include "MainWindow.h" //#include <QCameraViewfinder> //QCamera:系統攝像裝置(攝像頭) //QCameraViewfinder :攝像取景器部件 //QCameraImageCapture:截圖部件 using namespace cv; QtGuiApplication1::QtGuiApplication1(QWidget *parent) : QMainWindow(parent) { ui.setupUi(this); this->setFixedSize(300, 400); //setWindowState(Qt::WindowMaximized);//max timer = new QTimer(this); timer->stop(); connect(timer, SIGNAL(timeout()), this, SLOT(readFarme())); // 時間到,讀取當前攝像頭資訊 ok = true; pushButton = new QPushButton(tr("開始/暫停"),this); pushButton->setGeometry(QRect(0, 0, 300, 100)); pushButton->setFont(QFont("Times", 32, QFont::Bold)); connect(pushButton, SIGNAL(clicked()),this, SLOT(on_pushButton_clicked())); clickLabel = new QLabel(this); clickLabel->setGeometry(0, 100, 300, 300); //開啟攝像頭,從攝像頭中獲取視訊 videocapture = new VideoCapture(0); //videocapture = new VideoCapture(0); //timer->start(33); } QImage QtGuiApplication1::cvMat2QImage(const Mat& mat) // Mat 改成 QImage { if (mat.type() == CV_8UC1) // 單通道 { QImage image(mat.cols, mat.rows, QImage::Format_Indexed8); image.setColorCount(256); // 灰度級數256 for (int i = 0; i < 256; i++) { image.setColor(i, qRgb(i, i, i)); } uchar *pSrc = mat.data; // 複製mat資料 for (int row = 0; row < mat.rows; row++) { uchar *pDest = image.scanLine(row); memcpy(pDest, pSrc, mat.cols); pSrc += mat.step; } return image; } else if (mat.type() == CV_8UC3) // 3通道 { const uchar *pSrc = (const uchar*)mat.data; // 複製畫素 QImage image(pSrc, mat.cols, mat.rows, mat.step, QImage::Format_RGB888); // R, G, B 對應 0,1,2 return image.rgbSwapped(); // rgbSwapped是為了顯示效果色彩好一些。 } else if (mat.type() == CV_8UC4) { const uchar *pSrc = (const uchar*)mat.data; // 複製畫素 // Create QImage with same dimensions as input Mat QImage image(pSrc, mat.cols, mat.rows, mat.step, QImage::Format_ARGB32); // B,G,R,A 對應 0,1,2,3 return image.copy(); } else { return QImage(); } } Mat QtGuiApplication1::QImage2cvMat(QImage image) // QImage改成Mat { Mat mat; switch (image.format()) { case QImage::Format_ARGB32: case QImage::Format_RGB32: case QImage::Format_ARGB32_Premultiplied: mat = Mat(image.height(), image.width(), CV_8UC4, (void*)image.constBits(), image.bytesPerLine()); break; case QImage::Format_RGB888: mat = Mat(image.height(), image.width(), CV_8UC3, (void*)image.constBits(), image.bytesPerLine()); cv::cvtColor(mat, mat, CV_BGR2RGB); break; case QImage::Format_Indexed8: mat = Mat(image.height(), image.width(), CV_8UC1, (void*)image.constBits(), image.bytesPerLine()); break; } return mat; } ////////////////////////////////////事件驅動/////////////////////////////////////////////////////// //開啟攝像頭 void QtGuiApplication1::on_pushButton_clicked() { // 開始計時,超時則發出timeout()訊號 if(ok)timer->start(33); else timer->stop(); ok = !ok; } //讀取Frame影象 when timeout() void QtGuiApplication1::readFarme() { videocapture->read(matFrame); QImage imgg = cvMat2QImage(matFrame); QPixmap qpixmap = QPixmap::fromImage(imgg); // 將圖片顯示到label上 clickLabel->setPixmap(qpixmap); } //exit void QtGuiApplication1::bnClose() { timer->stop(); // 停止讀取資料。 videocapture->release(); //exit QApplication* app; app->exit(0); }
MainWindow.h
#pragma once #include <QtWidgets/QMainWindow> #include "ui_QtGuiApplication1.h" #include <opencv2/opencv.hpp> #include <opencv2/core/core.hpp> #include <opencv2/highgui/highgui.hpp> #include <opencv2/imgproc/imgproc.hpp> #include "qimage.h" #include <QFileDialog> #include <QLabel> #include <QTimer> #include <QPushButton> #include <QCamera> #include <QCameraImageCapture> using namespace cv; //OpenCV名稱空間 class QtGuiApplication1 : public QMainWindow { Q_OBJECT public: QtGuiApplication1(QWidget *parent = Q_NULLPTR); private: Ui::QtGuiApplication1Class ui; QImage cvMat2QImage(const Mat & mat); Mat QImage2cvMat(QImage image); QTimer *timer; bool ok; VideoCapture *videocapture; Mat matFrame; QLabel *clickLabel; QPushButton *pushButton; private slots: void on_pushButton_clicked(); void readFarme(); void bnClose(); };