opencv3和opencv2读取摄像头的代码方法不能共用,所以这里总结一下;
变化是opencv2是用IplImage指针读取存储摄像头的帧,opencv3是用Mat;
opencv2摄像头读取代码(Qt工程)如下:
#include "mainwindow.h"
#include "ui_mainwindow.h"
#include "cv.h"
#include "highgui.h"
MainWindow::MainWindow(QWidget *parent) :
QMainWindow(parent),
ui(new Ui::MainWindow)
{
ui->setupUi(this);
}
MainWindow::~MainWindow()
{
delete ui;
}
void MainWindow::on_pushButton_clicked()
{
//下面的代码在mian函数里或用其他函数调用即可,我加了按钮调用;
IplImage* pFrame = NULL; //声明IplImage指针
CvCapture* pCapture = cvCreateCameraCapture(-1);
//获取摄像头
//-1为默认摄像头,其他则需要填写地址;
//函数cvCreateCameraCapture给从摄像头的视频流分配和初始化CvCapture结构。
//目前在Windows下可使用两种接口:Video for Windows(VFW)
//和Matrox Imaging Library(MIL);
//Linux下也有两种接口:V4L和FireWire(IEEE1394)。
//释放这个结构,使用函数cvReleaseCapture。
//返回值为一个
// CvCapture
cvNamedWindow("video", 1); //创建窗口
while(1)//显示视屏
{
pFrame=cvQueryFrame( pCapture );
// 函数cvQueryFrame从摄像头或者文件中抓取一帧,
//然后解压并返回这一帧。
//这个函数仅仅是函数cvGrabFrame和函数cvRetrieveFrame在一起调用的组合。
//返回的图像不可以被用户释放或者修改。抓取后,capture被指向下一帧,
//可用cvSetCaptureProperty调整capture到合适的帧。
if(!pFrame)break; //如果PFrame为空,则跳出循环;
cvShowImage("video",pFrame); //当前帧显示后
char c=cvWaitKey(33); //等待33ms
if(c==27)break;
//如果用户触发了按键,将按键的ASCII值给C
//如果C为ESC(ASCII 为27)循环退出
}
cvReleaseCapture(&pCapture); //释放Capture;
cvDestroyWindow("video"); //销毁窗口
}
opencv3摄像头读取代码,如下:
#include "mainwindow.h"
#include "ui_mainwindow.h"
#include <opencv2/core.hpp>
#include <opencv2/highgui.hpp>
#include <opencv2/videoio.hpp>
#include <QMessageBox>
#pragma execution_character_set("utf-8")//Qt5中文乱码问题解决
using namespace cv;
MainWindow::MainWindow(QWidget *parent) :
QMainWindow(parent),
ui(new Ui::MainWindow)
{
ui->setupUi(this);
}
MainWindow::~MainWindow()
{
delete ui;
}
void MainWindow::on_Btn_video_clicked()
{
//下面的代码在mian函数里或用其他函数调用即可,我是加了按钮调用;
/*VideoCapture结构体,保存图像信息,open()参数为int index(0为默认摄像头),读入摄像头视频,
open()参数为路径,读入视频文件*/
VideoCapture cap(0); // 打开摄像头0
if (!cap.isOpened()) // 异常处理
{
QMessageBox mesg;
mesg.about(NULL,"提示","摄像头打开失败");
waitKey(1000);
}
while (1)
{
Mat frame;
bool bSuccess = cap.read(frame); // 获取一帧
if (!bSuccess) //异常处理
{
QMessageBox mesg;
mesg.about(NULL,"提示","Cannot read a frame from video stream");
break;
}
imshow("MyVideo", frame); //显示获取到的视频帧
if (waitKey(30) == 27) //按键退出
{
QMessageBox mesg;
mesg.about(NULL,"信息","退出摄像");
break;
}
}
waitKey(10);
cap.release();
cv::destroyAllWindows ();
}
以下摘自博客:http://blog.csdn.net/qq_34917736/article/details/77427596;
区别:
1、保存图像信息的结构体:
opencv2:CvCapture,操作清一色指针。
opencv3:VideoCapture,操作清一色变量。
2、打开到函数:
opencv2:cvCreateCameraCapture(-1)读入摄像头视频,
cvCreateFileCapture("路径")读入视频文件。
opencv3:open一个函数搞定,文件和摄像头是不同的重载函数。
3、IplImage指针、Mat变量
4、读取视频流的形式:
opencv2:cvQueryFrame(capture)
opencv3:<<,经过重载到operate函数。
5、图像显示:
opencv2:在main一开头声明窗口:cvNamedWindow,后面用cvShowImage函数显示
opencv3:imshow全部搞定。当然,cvNamedWindow也有它到代替品:namedWindow();
6、控制帧率
opencv2:cvWaitKey
opencv3:waitKey
7、释放保存图像信息到结构体
opencv2:cvReleaseCapture()函数
opencv3:作为一个变量,显然是由系统释放到,完全不需要管。不过严谨起见,也可以加上一行capture.release();