摘要:
由于最近AR(增强现实)这个概念非常火爆,各种基于AR的应用及游戏逐渐面向大众,而在AR中最重要的两个技术就是跟踪识别和增强渲染,其中跟踪识别是通过OpenCV这个开源的计算机视觉库来实现的,所以我就想着研究一下这个库,这里是个人的学习笔记,不是什么权威的教程,如果你们有错误也麻烦帮我指出哈。
=============================================分割线==================================================
前言:
用OpenCV来完成我们的功能之前,我们需要先了解几个关键的点:
1.OpenCV的命名空间
2.图片的载入、显示及输出
案例源码:
=====================================================================================================
#include
#include
#include
using namespace cv;
int main(){
// 读入一张图片(游戏原画)
Mat img = imread("pic.jpg");
// 创建一个名为 "游戏原画"窗口
namedWindow("游戏原画");
// 在窗口中显示游戏原画
imshow("游戏原画", img);
// 等待6000 ms后窗口自动关闭
waitKey(6000);
}
====================================================================================================
一、OpenCV的命名空间:
在第一篇中我们引入了一个显示图片的案例,在头文件引入之后和main函数之前,我们可以看到这样一句声明:
using namespace cv;
这就是命名空间的声明,在OpenCV中,C++类和函数都是定义在
cv命名空间内的,所以假如我们需要在代码中引用OpenCV的时,需要声明其命名空间,方法有两个:
1.在main函数之后用“using namespace cv;”来声明命名空间
2.在要调用的类或者函数前面加上“cv::”来声明命名空间
显然,使用第一种方法的声明更加简洁方便。
二、图片载入、显示及输出:
1.图片载入:
我们要在窗口显示一张图片,首先我们需要将图片载入并转换成指定数据结构的数据存储,然后在需要显示的时候再将存储数据传递给显示接口,在案例中,我们载入图片的代码如下:
// 读入一张图片(游戏原画)
Mat img = imread("pic.jpg");
从以上代码我们发现,我们用imread函数载入pic.jpg这张图片之后,OpenCV中使用Mat类型来存储载入的图片数据,那么Mat类型有什么特点呢?
cv::Mat:是OpenCV用来保存图像以及其他矩阵数据的数据结构,其默认的尺寸为0,当然在定义是也可以指定其尺寸,例如我们在定义一个Mat对象时:cv::Matpic(640,1024,cv::Scalar(50));
imread函数:
官方原型:Mat imread(const string& filename, int flags=1 );
包含了两个参数:
参数一:const string&类型,用于填写图片存放的路径
参数二:int类型,载入标志,用于指定载入图片的颜色类型。显然这是一个枚举类型的,而且其缺省值为1,具体的枚举表可以在higui_c.h中找到。当然除了枚举也可以根据flag的赋值范围来判断颜色类型:
flags >0:返回一个3通道的彩色图像
2.图片显示:
显示图片,我们需要两个步骤:创建窗口和显示图片
namedWindow函数:
参数一:用于标识作用的,窗口的名称,不作为显示名称
参数二:int类型的窗口标识(跟窗口的大小有关)
imshow函数:
参数一:窗口的名称,作为显示名称
参数二:图片矩阵类型数据
3.图片输出:
在OpenCV中,我们通常用imwrite函数来输出图像到文件中,即
imwrite函数:
官方原型:bool imwrite(const string& filename,InputArray img, const vector
参数一:输出之后的文件名,需要加上后缀
参数二:输出的一个图片Mat数据
参数三:特定格式保存的参数编码,具有默认值,一般不填
三、实例:
在这里,我们读取两张图片,然后合并图片信息,并输出合并后的图像到文件:
#include
#include
#include
using namespace cv;
int main(){
//载入图片
Mat pic = imread("pic.jpg");
//包含透明度
Mat logo = imread("logo.jpg",-1);
//分别显示两张图片
namedWindow("原画【1】");
imshow("原画【1】", pic);
namedWindow("原画【2】");
imshow("原画【2】", logo);
Mat imageROI = pic(Rect(800, 350, logo.cols, logo.rows));
//将logo加到原图上
addWeighted(imageROI, 0.5, logo, 0.3, 0., imageROI);
//显示合并后的图片
namedWindow("原画【3】");
imshow("原画【3】", pic);
//将混合之后的结果输出为新的图片
imwrite("mix_pic.jpg",pic);
//等待键盘任意按钮事件
waitKey();
return 0;
}
这里我们还用到了一个
waitKey()函数,起作用就是让当前程序处于等待状态,保证绘制出来的窗口不会一闪而过,直到有键盘输入程序才继续运行。出现的结果是:
上面是混合之后的结果,我们还在程序中把混合之后的图像Mat数据通过imwrite方法输出为一张新的图片,查看工程目录,可以看到目录中多出了一张图片: