今天寫的QT+openCV實現攝像頭拍照功能。
在網上收羅了很多資料,QT沒有專門操作攝像頭的類,這個得自己寫。網上也有很多關務openCV和V4l的一些介紹,由於我項目要在window下開發,所以就選擇了openCV。由於以前沒有用過openCV,所以就只看了關於openCVS攝像頭操作的這部分,其他的還沒時間去看。
openCV : http://sourceforge.net/projects/opencvlibrary/files/opencv-win/2.1/
剛開始下載的是2.3.1的,安裝后發現沒有lib庫所以后面選擇了2.1的
openCV中文學習 pdf :
現在,開始詳細的介紹如何在QT中實時的采集攝像頭數據。
打開QTcreator (我用的是QT 2.3的 中文版)
新建一個widget工程

在界面上放兩個label 分別用來顯示攝像頭采集到的數據和照的照片。

編輯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();

