转载请注明原文地址:http://blog.csdn.net/huang8579/article/details/8026158
OpenCV2.3.1已经编译完了,上一篇文章中只是简单地介绍一下完全用OpenCV自己图形库实现摄像头调用和图像显示,这篇文章则主要介绍Qt与OpenCV的使用
请注意:
OpenCV 2.x版本和1.x版本有着很大的差别,网上有很多文章讲的都是1.x版本,2.x版本中图像存储容器改为Mat,但是向下兼容以前的容器,库的使用上也有巨大差别
所以以后在使用开源库的时候,首先要去官方网站上查看文档,知道有哪些差别,如果只按照老的文档操作的话, 很容易造成时间上不必要的浪费!!
OpenCV 2.x 文档翻译网站:http://www.opencv.org.cn/opencvdoc/2.3.2/html/index.html
2.X版本的改变
1、新容器
在用新版本之前,你首先需要学习一些新的图像数据结构: Mat - 基本图像容器 ,它取代了旧的 CvMat 和 IplImage.
Mat的基本原理就是矩阵存储,所以在向QImage传递图像数据的大小时,Mat提供了矩阵的行数(Cols)和列数(Rows),用以取代IplImage的宽和高。
2、新的库调用方法
OpenCV 2 接受按需定制。所有函数不再装入一个单一的库中。我们会提供许多模块,每个模块都包含了与其功能相关的数据结构和函数。这样一来,如果你仅仅需要使用OpenCV的一部分功能,你就不需要把整个巨大的OpenCV库都装入你的程序中。使用时,你仅需要包含用到的头文件,比如:
#include
#include
#include
所有OpenCV用到的东西都被放入名字空间 cv 中以避免与其他库的数据结构和函数名称的命名冲突。因此,在使用OpenCV库中的任何定义和函数时,你必须在名称之前冠以 cv:: ,或者在包含头文件后,加上以下指令:
using namespace cv; // 新的C++接口API都在此名字空间中,需要导入。
因为所有库中函数都已在此名字空间中,所以无需加 cv 作为前缀。据此所有新的C++兼容函数都无此前缀,并且遵循驼峰命名准则。也就是第一个字母为小写(除非是单个单词作为函数名,如 Canny)并且后续单词首字母大写(如 copyMakeBorder ).
接下来,请记住你需要将所有用到的模块链接到你的程序中。如果你在Windows下开发且用到了 动态链接库(DLL) ,你还需要将OpenCV对应动态链接库的路径加入程序执行路径中。关于Windows下开发的更多信息请阅读 How to build applications with OpenCV inside the Microsoft Visual Studio;对于Linux用户,可参考 Using OpenCV with Eclipse (plugin CDT) 中的实例及说明。
Qt中使用OpenCV库新建QWidget工程,ui,main.cpp全都默认
头文件的实现,上面已经介绍,直接代码:
#ifndef WIDGET_H
#define WIDGET_H
#include
#include
#include
#include
#include
#include
#include
#include
#define FPS 33
using namespace cv;
namespace Ui {
class Widget;
}
class Widget : public QWidget
{
Q_OBJECT
public:
explicit Widget(QWidget *parent = 0);
void paintEvent(QPaintEvent *);
~Widget();
private:
Ui::Widget *ui;
VideoCapture V;
QTimer timer;
Mat im;
private slots:
void showImage();
};
#endif // WIDGET_H
//数字代表设备号,就是调用哪个摄像头
VideoCapture V(0);
//指针方式
V = new VideoCapture(0);
//判断是否成功打开摄像头
V.isOpened()
构造函数实现:
Widget::Widget(QWidget *parent) :
QWidget(parent),
ui(new Ui::Widget)
{
ui->setupUi(this);
V.open(0);
//设定摄像头采集图像的宽、高,可以不设置,采用原始图像
V.set(CV_CAP_PROP_FRAME_WIDTH,);
V.set(CV_CAP_PROP_FRAME_HEIGHT,450);
//开启定时器
timer.start(FPS);
//img = new QImage((unsigned char*)im.data,im.cols,im.rows,QImage::Format_RGB888);
connect(&timer,SIGNAL(timeout()),this,SLOT(showImage()));
}
OpenCV的图像格式是BGR,QImage的则是RGB,所以要进行图像格式转换,否则图像会的颜色会走样,2.x版本里面用cvtColor进行转换,详情见代码:
void Widget::showImage()
{
V >> im;
//图像格式转换
cvtColor(im,im,CV_BGR2RGB);
update();
}
注意QImage接收Mat图像数据时传递的参数类型
绘图部分代码:
void Widget::paintEvent(QPaintEvent *)
{
QImage img((unsigned char*)im.data,im.cols,im.rows,QImage::Format_RGB888);
QPainter painter(this);
painter.drawImage(-1,-1,img);
}
有什么不足的地方,还请提出来,大家一起进步!