最近使用Qt+openCV获取摄像头的图像
但是仅仅只是使用openCV自带的方法显示图像时,发现计算机CPU使用率比较高,最主要的一点是摄像头驱动自带的设置图像参数的无法直接调用出来
网上查找了很多资料发现 openCV内部是使用了videoInput类的方法实现的.但是没有引用它自身的方法.
经过几天的研究,成功使用videoinput显示摄像头图像,并且可以弹出摄像头驱动自带的图像设置窗口,
不过好像那种USB免驱动的摄像头无法打开,因为用不到就没深入探究.
openCV2.48
Qt5.2.1 用的是VS2010的编译器
videoInput 0.1995
源码及程序点击这里
做界面什么的,这个不是重点,不详述了
videoinput解压出来有源码和已经编译好的库
我用的是vs2008编译好的库
然后再Qt,pro文件中添加openCV以及video的路径
INCLUDEPATH += D:\opencv\build\include CONFIG(release,debug|release){ LIBS += D:\opencv\build\x86\vc10\lib\opencv_calib3d248.lib \ D:\opencv\build\x86\vc10\lib\opencv_contrib248.lib \ D:\opencv\build\x86\vc10\lib\opencv_core248.lib \ D:\opencv\build\x86\vc10\lib\opencv_features2d248.lib \ D:\opencv\build\x86\vc10\lib\opencv_flann248.lib \ D:\opencv\build\x86\vc10\lib\opencv_gpu248.lib \ D:\opencv\build\x86\vc10\lib\opencv_highgui248.lib \ D:\opencv\build\x86\vc10\lib\opencv_imgproc248.lib \ D:\opencv\build\x86\vc10\lib\opencv_legacy248.lib \ D:\opencv\build\x86\vc10\lib\opencv_ml248.lib \ D:\opencv\build\x86\vc10\lib\opencv_nonfree248.lib \ D:\opencv\build\x86\vc10\lib\opencv_objdetect248.lib \ D:\opencv\build\x86\vc10\lib\opencv_ocl248.lib \ D:\opencv\build\x86\vc10\lib\opencv_photo248.lib \ D:\opencv\build\x86\vc10\lib\opencv_stitching248.lib \ D:\opencv\build\x86\vc10\lib\opencv_superres248.lib \ D:\opencv\build\x86\vc10\lib\opencv_ts248.lib \ D:\opencv\build\x86\vc10\lib\opencv_video248.lib \ D:\opencv\build\x86\vc10\lib\opencv_videostab248.lib \ D:\opencv\build\include\opencv2\videoInput\videoInput.lib\ } CONFIG(debug,debug|release){ LIBS += D:\opencv\build\x86\vc10\lib\opencv_calib3d248d.lib \ D:\opencv\build\x86\vc10\lib\opencv_contrib248d.lib \ D:\opencv\build\x86\vc10\lib\opencv_core248d.lib \ D:\opencv\build\x86\vc10\lib\opencv_features2d248d.lib \ D:\opencv\build\x86\vc10\lib\opencv_flann248d.lib \ D:\opencv\build\x86\vc10\lib\opencv_gpu248d.lib \ D:\opencv\build\x86\vc10\lib\opencv_highgui248d.lib \ D:\opencv\build\x86\vc10\lib\opencv_imgproc248d.lib \ D:\opencv\build\x86\vc10\lib\opencv_legacy248d.lib \ D:\opencv\build\x86\vc10\lib\opencv_ml248d.lib \ D:\opencv\build\x86\vc10\lib\opencv_nonfree248d.lib \ D:\opencv\build\x86\vc10\lib\opencv_objdetect248d.lib \ D:\opencv\build\x86\vc10\lib\opencv_ocl248d.lib \ D:\opencv\build\x86\vc10\lib\opencv_photo248d.lib \ D:\opencv\build\x86\vc10\lib\opencv_stitching248d.lib \ D:\opencv\build\x86\vc10\lib\opencv_ts248d.lib \ D:\opencv\build\x86\vc10\lib\opencv_superres248d.lib \ D:\opencv\build\x86\vc10\lib\opencv_ts248d.lib \ D:\opencv\build\x86\vc10\lib\opencv_video248d.lib \ D:\opencv\build\x86\vc10\lib\opencv_videostab248d.lib \ D:\opencv\build\include\opencv2\videoInput\videoInput.lib\ }然后将include中的videoInput.h文件添加到项目中,
我将video常用的类写道一个新的类中.引出了一些常用的方法,直接调用videoinput也是可以的
int getTotalCameraCount(); //获得总共可用摄像头数量 char * getDeviceName(int deviceID); //根据摄像头编号获取驱动名称 void showSettingsWindow(int deviceID);//显示属性设置窗口 bool setupDevice(int deviceID, int w, int h); //配置摄像设备 bool setupDevice(int deviceID); //配置摄像设备 bool isFrameNew(int deviceID); //是否有新的一帧 void stopDevice(int deviceID);//停止摄像头工作 unsigned char * getPixels(int deviceID, bool flipRedAndBlue = true, bool flipImage = false );//获取图像数据全部的方法可以看videoInput.h头文件中的源码
//turns off console messages - default is to print messages static void setVerbose(bool _verbose); //Functions in rough order they should be used. static int listDevices(bool silent = false); //needs to be called after listDevices - otherwise returns NULL static char * getDeviceName(int deviceID); //choose to use callback based capture - or single threaded void setUseCallback(bool useCallback); //call before setupDevice //directshow will try and get the closest possible framerate to what is requested void setIdealFramerate(int deviceID, int idealFramerate); //some devices will stop delivering frames after a while - this method gives you the option to try and reconnect //to a device if videoInput detects that a device has stopped delivering frames. //you MUST CALL isFrameNew every app loop for this to have any effect void setAutoReconnectOnFreeze(int deviceNumber, bool doReconnect, int numMissedFramesBeforeReconnect); //Choose one of these four to setup your device bool setupDevice(int deviceID); bool setupDevice(int deviceID, int w, int h); //These two are only for capture cards //USB and Firewire cameras souldn't specify connection bool setupDevice(int deviceID, int connection); bool setupDevice(int deviceID, int w, int h, int connection); //If you need to you can set your NTSC/PAL/SECAM //preference here. if it is available it will be used. //see #defines above for available formats - eg VI_NTSC_M or VI_PAL_B //should be called after setupDevice //can be called multiple times bool setFormat(int deviceNumber, int format); //Tells you when a new frame has arrived - you should call this if you have specified setAutoReconnectOnFreeze to true bool isFrameNew(int deviceID); bool isDeviceSetup(int deviceID); //Returns the pixels - flipRedAndBlue toggles RGB/BGR flipping - and you can flip the image too unsigned char * getPixels(int deviceID, bool flipRedAndBlue = true, bool flipImage = false); //Or pass in a buffer for getPixels to fill returns true if successful. bool getPixels(int id, unsigned char * pixels, bool flipRedAndBlue = true, bool flipImage = false); //Launches a pop up settings window //For some reason in GLUT you have to call it twice each time. void showSettingsWindow(int deviceID); //Manual control over settings thanks..... //These are experimental for now. bool setVideoSettingFilter(int deviceID, long Property, long lValue, long Flags = NULL, bool useDefaultValue = false); bool setVideoSettingFilterPct(int deviceID, long Property, float pctValue, long Flags = NULL); bool getVideoSettingFilter(int deviceID, long Property, long &min, long &max, long &SteppingDelta, long ¤tValue, long &flags, long &defaultValue); bool setVideoSettingCamera(int deviceID, long Property, long lValue, long Flags = NULL, bool useDefaultValue = false); bool setVideoSettingCameraPct(int deviceID, long Property, float pctValue, long Flags = NULL); bool getVideoSettingCamera(int deviceID, long Property, long &min, long &max, long &SteppingDelta, long ¤tValue, long &flags, long &defaultValue); //bool setVideoSettingCam(int deviceID, long Property, long lValue, long Flags = NULL, bool useDefaultValue = false); //get width, height and number of pixels int getWidth(int deviceID); int getHeight(int deviceID); int getSize(int deviceID); //completely stops and frees a device void stopDevice(int deviceID); //as above but then sets it up with same settings bool restartDevice(int deviceID);
camera = new MyCamera(); //设置可用摄像头列表 int count = camera->getTotalCameraCount(); for(int i=0;i<count;i++){ QString name = camera->getDeviceName(i); ui->comboBoxCamreaList->addItem(name); }
//显示摄像头设置界面 camera->showSettingsWindow(ui->comboBoxCamreaList->currentIndex());
void MainWindow::display(cv::Mat &mat) { cv::Mat rgb = mat; QImage img; if(mat.channels()==3) { // cv::cvtColor(mat,rgb,CV_BGR2RGB); img = QImage((const uchar*)(rgb.data),rgb.cols,rgb.rows,rgb.cols*rgb.channels(),QImage::Format_RGB888); } else { img = QImage((const uchar*)(mat.data),mat.cols,mat.rows,mat.cols*mat.channels(),QImage::Format_Indexed8); } ui->labelImage->setPixmap(QPixmap::fromImage(img)); // ui->labelImage->resize(ui->labelImage->pixmap()->size()); ui->labelImage->show(); }
//打开摄像头 void MainWindow::on_actionCamreaOpen_triggered() { int width = 800; int height = 600; mat = cv::Mat(height,width,CV_32SC3); deviceID = ui->comboBoxCamreaList->currentIndex(); camera->setupDevice(deviceID,width,height);//配置摄像机 设置宽为800X600 timer = new QTimer(this); connect(timer,SIGNAL(timeout()),this,SLOT(startLoopSlot())); timer->start(30); }
//图像显示循环 void MainWindow::startLoopSlot() { if(camera->isFrameNew(deviceID)){ mat.data = camera->getPixels(deviceID,flipRedAndBlue,flipImage); display(mat); } }
//关闭摄像头 void MainWindow::on_actionCameraClose_triggered() { timer->stop(); delete timer; timer = NULL; camera->stopDevice(deviceID); qDebug()<<"close Camrea"; }