今天寫的QT+openCV實現攝像頭拍照功能。app
在網上收羅了不少資料,QT沒有專門操做攝像頭的類,這個得本身寫。網上也有不少關務openCV和V4l的一些介紹,因爲我項目要在window下開發,因此就選擇了openCV。因爲之前沒有用過openCV,因此就只看了關於openCVS攝像頭操做的這部分,其餘的還沒時間去看。函數
openCV : http://sourceforge.net/projects/opencvlibrary/files/opencv-win/2.1/ 學習
剛開始下載的是2.3.1的,安裝後發現沒有lib庫因此後面選擇了2.1的ui
openCV中文學習 pdf :this
如今,開始詳細的介紹如何在QT中實時的採集攝像頭數據。spa
打開QTcreator (我用的是QT 2.3的 中文版).net
新建一個widget工程指針
在界面上放兩個label 分別用來顯示攝像頭採集到的數據和照的照片。orm
編輯camaraget.h 文件視頻
#ifndef CAMARAGET_H #define CAMARAGET_H #include <QWidget> #include <QImage> #include <QTimer> // 設置採集數據的間隔時間 #include <highgui.h> //包含opencv庫頭文件 #include <cv.h> namespace Ui { class camaraGet; } class camaraGet : public QWidget { Q_OBJECT public: explicit camaraGet(QWidget *parent = 0); ~camaraGet(); private slots: void openCamara(); // 打開攝像頭 void readFarme(); // 讀取當前幀信息 void closeCamara(); // 關閉攝像頭。 void takingPictures(); // 拍照 private: Ui::camaraGet *ui; QTimer *timer; QImage *imag; CvCapture *cam;// 視頻獲取結構, 用來做爲視頻獲取函數的一個參數 IplImage *frame;//申請IplImage類型指針,就是申請內存空間來存放每一幀圖像 }; #endif // CAMARAGET_H
編輯camaraget.cpp
#include "camaraget.h" #include "ui_camaraget.h" camaraGet::camaraGet(QWidget *parent) : QWidget(parent), ui(new Ui::camaraGet) { ui->setupUi(this); cam = NULL; timer = new QTimer(this); imag = new QImage(); // 初始化 /*信號和槽*/ connect(timer, SIGNAL(timeout()), this, SLOT(readFarme())); // 時間到,讀取當前攝像頭信息 connect(ui->open, SIGNAL(clicked()), this, SLOT(openCamara())); connect(ui->pic, SIGNAL(clicked()), this, SLOT(takingPictures())); connect(ui->closeCam, SIGNAL(clicked()), this, SLOT(closeCamara())); } /****************************** ********* 打開攝像頭 *********** *******************************/ void camaraGet::openCamara() { cam = cvCreateCameraCapture(0);//打開攝像頭,從攝像頭中獲取視頻 timer->start(33); // 開始計時,超時則發出timeout()信號 } /********************************* ********* 讀取攝像頭信息 *********** **********************************/ void camaraGet::readFarme() { frame = cvQueryFrame(cam);// 從攝像頭中抓取並返回每一幀 // 將抓取到的幀,轉換爲QImage格式。QImage::Format_RGB888不一樣的攝像頭用不一樣的格式。 QImage image((const uchar*)frame->imageData, frame->width, frame->height, QImage::Format_RGB888); ui->label->setPixmap(QPixmap::fromImage(image)); // 將圖片顯示到label上 } /************************* ********* 拍照 *********** **************************/ void camaraGet::takingPictures() { frame = cvQueryFrame(cam);// 從攝像頭中抓取並返回每一幀 // 將抓取到的幀,轉換爲QImage格式。QImage::Format_RGB888不一樣的攝像頭用不一樣的格式。 QImage image((const uchar*)frame->imageData, frame->width, frame->height, QImage::Format_RGB888); ui->label_2->setPixmap(QPixmap::fromImage(image)); // 將圖片顯示到label上 } /******************************* ***關閉攝像頭,釋放資源,必須釋放*** ********************************/ void camaraGet::closeCamara() { timer->stop(); // 中止讀取數據。 cvReleaseCapture(&cam);//釋放內存; } camaraGet::~camaraGet() { delete ui; }
好了,所有代碼都OK了(固然,建立工程時,會生成main.cpp,沒必要去改動它),但如今你點運行,依然會產生錯誤,爲何呢?由於尚未把openCV的庫包含進去。
在*.pro 文件中 加入:
INCLUDEPATH+=C:\OpenCV2.1\include\opencv
LIBS += C:\OpenCV2.1\lib\highgui210.lib \
C:\OpenCV2.1\lib\cxcore210.lib \
C:\OpenCV2.1\lib\cv210.lib
OK,大功告成,運行後,在widget中點擊打開攝像頭,就能夠看到本身了。運行後的效果:
後來我發現這個效果不怎麼好,就改了一下:改了之後的運行效果也貼出來:
就改了一句:
QImage image((const uchar*)frame->imageData, frame->width, frame->height, QImage::Format_RGB888);
改成了 QImage image = QImage((const uchar*)frame->imageData, frame->width, frame->height, QImage::Format_RGB888).rgbSwapped();