本程序是基于我的毕业设计进行的开发,这篇博客中的图像处理算法是直接调用opencv自带的函数,原理比较简单,转载请注明作者和出处http://blog.csdn.net/zyx1990412/article/details/51182646。
qt主要是用来做界面设计,opencv主要用来做算法处理。程序开发之前的配置工作在作者以前发表的博客中可以看到。
1.首先用QT进行界面设计,本文所设计的QT界面如图1。程序中部件的名称就不一一标明了,需要用到的时候自会说明。
图一
2.编写打开和关闭摄像头的代码,使摄像头的视频图像在“输入视频”label中显示。本文打开摄像头的部件名称为pushButton,关闭摄像头的部件为pushButton_5,“输入视频”为label。
(1)打开摄像头
右键点击pushButton,点击转到槽,建立槽函数,在函数中编写读取摄像头的代码:
voidMainWindow::on_pushButton_clicked()//打开摄像头,进行瞳孔精确检测及定位 { VideoCapturecap(0); //打开默认摄像头 if(!cap.isOpened()) { cout<<"nocap"<<endl; } Matframe;//保存当前帧的图像 Lstop=false;//控制是否循环检测 while(!Lstop) { cap>>frame;//将摄像头的当前帧输出到frame //图像处理函数。 imshow("camera",image); QImageimg=Mat2QImage(image);//将mat格式转换为Qimage格式 ui->label->setPixmap(QPixmap::fromImage(img));//将结果在label上显示 //ui->label->setScaledContents(true);//使图像尺寸与label大小匹配 intc=waitKey(30);//每一帧间隔30ms if(c>=0)//任意键暂停 { waitKey(0); } } cvDestroyWindow("camera"); }
函数的基本功能是,首先打开摄像头,将摄像头信息输出到mat格式的frame中保存,然后循环实现图像的输出。其中,由于opencv的图片数据格式与QT的数据格式不同,需要用Mat2QImage(image)函数进行数据的转换。
PS:本文使用imshow("camera",image),建立一个窗口对mat格式的图片进行输出,如果删除这条语句,程序将不能正常运行。如果有大神知道这是为什么,还请指教。
(2)Mat2QImage(image)函数的具体实现为:
QImageMat2QImage(constMat&mat) { //8-bitsunsigned,NO.OFCHANNELS=1 if(mat.type()==CV_8UC1) { //cout<<"1"<<endl; //Setthecolortable(usedtotranslatecolourindexestoqRgbvalues) QVector<QRgb>colorTable; for(inti=0;i<256;i++) colorTable.push_back(qRgb(i,i,i)); //CopyinputMat constuchar*qImageBuffer=(constuchar*)mat.data; //CreateQImagewithsamedimensionsasinputMat QImageimg(qImageBuffer,mat.cols,mat.rows,mat.step,QImage::Format_Indexed8); img.setColorTable(colorTable); returnimg; } //8-bitsunsigned,NO.OFCHANNELS=3 if(mat.type()==CV_8UC3) { //cout<<"3"<<endl; //CopyinputMat constuchar*qImageBuffer=(constuchar*)mat.data; //CreateQImagewithsamedimensionsasinputMat QImageimg(qImageBuffer,mat.cols,mat.rows,mat.step,QImage::Format_RGB888); returnimg.rgbSwapped(); } else { qDebug()<<"ERROR:MatcouldnotbeconvertedtoQImage."; returnQImage(); } }
(3)关闭摄像头:
voidMainWindow::on_pushButton_5_clicked()//关闭摄像头 { Lstop=true; }
3.打开本地图片
打开本地图片的按钮是pushButton_2,其槽函数的原理与打开摄像头一样,用imread函数读取图片,让后转换格式,最后进行输出。
voidMainWindow::on_pushButton_2_clicked()//打开本地图片 { Matimage; image=cv::imread("IF.jpg");//图片的路径 //图像处理函数 QImageimg=Mat2QImage(image); ui->label->setPixmap(QPixmap::fromImage(img)); //ui->label->setScaledContents(true); waitKey(1000); }
加入waitKey(1000)的作用是使程序等待1000ms,如果没有这条语句,当运行程序后,首先点击读取本地图片,程序将正常运行;如果先点击打开摄像头,然后点击读取本地图片,将发现程序没有显示本地图片。实际上,这种情况下程序同样运行了槽函数里的语句,只是因为运行完打开本地图片的函数后,程序马上会返回打开摄像头里的循环函数继续运行,本地图片会一闪而过,不容易看到,加入等待时间后,能够使本地图片显示的时间变长。
PS:在函数中的“图像处理函数”的位置,可以自行编写图像处理函数,我自己的研究是瞳孔的精确定位,其函数的实现将在以后的博客中进行更新。