集合OpenCV的視頻功能和QCamera的攝像頭接口,開發出易於理解的、結構簡單的攝像頭控制和采集框架。
MainWindow
:
:MainWindow(QWidget
*parent)
: QMainWindow(parent),
ui( new Ui : :MainWindow)
{
ui - >setupUi( this);
timer = new QTimer( this);
imag = new QImage(); // 初始化
connect(timer, SIGNAL(timeout()), this, SLOT(readFarme())); // 時間到,讀取當前攝像頭信息
bMethod = false; //是否使用算法
//填充界面控件
const QList <QCameraInfo > availableCameras = QCameraInfo : :availableCameras();
for ( const QCameraInfo &cameraInfo : availableCameras)
{
ui - >comboCamera - >addItem(cameraInfo.description());
}
ui - >comboCamera - >setCurrentIndex( 0);
bCameraOpen = false;
ui( new Ui : :MainWindow)
{
ui - >setupUi( this);
timer = new QTimer( this);
imag = new QImage(); // 初始化
connect(timer, SIGNAL(timeout()), this, SLOT(readFarme())); // 時間到,讀取當前攝像頭信息
bMethod = false; //是否使用算法
//填充界面控件
const QList <QCameraInfo > availableCameras = QCameraInfo : :availableCameras();
for ( const QCameraInfo &cameraInfo : availableCameras)
{
ui - >comboCamera - >addItem(cameraInfo.description());
}
ui - >comboCamera - >setCurrentIndex( 0);
bCameraOpen = false;
//顯示的圖像自動縮放
ui->label->setScaledContents(true);
ui->label_2->setScaledContents(true);
}
在界面初始化的時候,就直接填充界面。注意這里
setScaledContents的設置使得圖像能夠填充滿整個窗體。
另一個非常關鍵的一句就是
connect(timer, SIGNAL(timeout()), this, SLOT(readFarme())); // 時間到,讀取當前攝像頭信息
相當於ontimer,非常直觀吧。
// 從攝像頭中抓取並返回每一幀
void MainWindow : :readFarme()
{
videocapture - >read(matFrame);
//是否圖像處理
Mat tmp;
if(bMethod) //這里只是簡單地實現一個Canny算法
{
cvtColor(matFrame,tmp,COLOR_BGR2GRAY);
cv : :Canny(tmp,tmp, 100, 255, 3);
cvtColor(tmp,matDst,COLOR_GRAY2BGR);
}
else
{
matDst = matFrame.clone();
}
// 格式轉換
QPixmap qpixmap = Mat2QImage(matDst);
// 將圖片顯示到label上
ui - >label - >setPixmap(qpixmap);
}
void MainWindow : :readFarme()
{
videocapture - >read(matFrame);
//是否圖像處理
Mat tmp;
if(bMethod) //這里只是簡單地實現一個Canny算法
{
cvtColor(matFrame,tmp,COLOR_BGR2GRAY);
cv : :Canny(tmp,tmp, 100, 255, 3);
cvtColor(tmp,matDst,COLOR_GRAY2BGR);
}
else
{
matDst = matFrame.clone();
}
// 格式轉換
QPixmap qpixmap = Mat2QImage(matDst);
// 將圖片顯示到label上
ui - >label - >setPixmap(qpixmap);
}
這里使用了
Mat2QImage函數,將圖像轉換為
qpixmap,並且顯示在
label上
//打開磁盤上的圖片
void MainWindow : :on_pushButton_clicked()
{
//第3個參數表示查找文件時從哪個目錄開始,如果為"."的話,表示從該工程目錄開始查找,最后那個參數的過濾器的名字之間
//要用空格,否則識別不出來
QString img_name = QFileDialog : :getOpenFileName( this, tr( "Open Image"), ".",tr( "Image Files(*.png *.jpg *.jpeg *.bmp)"));
if(img_name == "")
return;
//toAscii()返回8位描述的string,為QByteArray,data()表示返回QByteArray的指針,QByteArray為字節指針
//現在已改為toLatinl函數
Mat src = imread(img_name.toLatin1().data());
cvtColor( src, src, CV_BGR2RGB );
QImage img = QImage( ( const unsigned char *)(src.data), src.cols, src.rows, QImage : :Format_RGB888 );
ui - >label - >setPixmap( QPixmap : :fromImage(img) );
img_name.clear();
}
void MainWindow : :on_pushButton_clicked()
{
//第3個參數表示查找文件時從哪個目錄開始,如果為"."的話,表示從該工程目錄開始查找,最后那個參數的過濾器的名字之間
//要用空格,否則識別不出來
QString img_name = QFileDialog : :getOpenFileName( this, tr( "Open Image"), ".",tr( "Image Files(*.png *.jpg *.jpeg *.bmp)"));
if(img_name == "")
return;
//toAscii()返回8位描述的string,為QByteArray,data()表示返回QByteArray的指針,QByteArray為字節指針
//現在已改為toLatinl函數
Mat src = imread(img_name.toLatin1().data());
cvtColor( src, src, CV_BGR2RGB );
QImage img = QImage( ( const unsigned char *)(src.data), src.cols, src.rows, QImage : :Format_RGB888 );
ui - >label - >setPixmap( QPixmap : :fromImage(img) );
img_name.clear();
}
可以直接使用函數,打開磁盤上的圖片。
//打開攝像頭
void MainWindow : :on_pushButton_OpenCam_clicked()
{
int i = ui - >comboCamera - >currentIndex();
//打開攝像頭,從攝像頭中獲取視頻
if(bCameraOpen)
{
videocapture - >release(); //kill camera first
}
videocapture = new VideoCapture(i);
bCameraOpen = true;
//這里給出了一個非常大的分辨率,如果攝像頭沒有這么大的分辨率,則會默認打開其支持的最大分辨率
videocapture - >set(CV_CAP_PROP_FRAME_WIDTH, 2592);
videocapture - >set(CV_CAP_PROP_FRAME_HEIGHT, 1944);
// 開始計時,超時則發出timeout()信號
timer - >start( 0);
}
void MainWindow : :on_pushButton_OpenCam_clicked()
{
int i = ui - >comboCamera - >currentIndex();
//打開攝像頭,從攝像頭中獲取視頻
if(bCameraOpen)
{
videocapture - >release(); //kill camera first
}
videocapture = new VideoCapture(i);
bCameraOpen = true;
//這里給出了一個非常大的分辨率,如果攝像頭沒有這么大的分辨率,則會默認打開其支持的最大分辨率
videocapture - >set(CV_CAP_PROP_FRAME_WIDTH, 2592);
videocapture - >set(CV_CAP_PROP_FRAME_HEIGHT, 1944);
// 開始計時,超時則發出timeout()信號
timer - >start( 0);
}
攝像頭的打開也非常直接。

添加了一些修改,使用QT來做,真的是非常方便:
項目地址:
https://github.com/jsxyhelu/GOQTTemplate3
歡迎提出寶貴意見。