OpenCV库包含500多个函数,2500多种算法,可以扩展应用到视觉行业中的很多领域,有广泛的用途,比如安保,医学成像,模式与人脸识别,机器人和工业产品检测,等等。《学习OpenCV 3(中文版)》实用性强,内容全面,讲解透彻,可以帮助读者掌握如何构建具有一定AI(人工智能)的应用程序,使计算机能够“看见”并根据所得到的数据来做出决策。《学习OpenCV 3(中文版)》全面介绍整个OpenCV库,所有示例代码都用C++实现,同时还介绍了可以用于计算机视觉的机器学习工具。《学习OpenCV 3(中文版)》每一章都精心设计有动手练习,旨在方便课堂教学和自学,进一步帮助读者学以致用。
通过学习《学习OpenCV 3(中文版)》,读者可以奠定扎实的基础,运用计算机视觉相关知识和OpenCV库来构建简单的或者精巧复杂的应用程序。
计算机视觉是在图像处理的基础上发展起来的新兴学科。OpenCV是一个开源的计算机视觉库,是英特尔公司资助的两大图像处理利器之一。它为图像处理、模式识别、三维重建、物体跟踪、机器学习和线性代数提供了各种各样的算法。
《学习OpenCV 3(中文版)》由OpenCV发起人所写,站在一线开发人员的角度用通俗易懂的语言解释了OpenCV的缘起和计算机视觉基础结构,演示了如何用OpenCV和现有的自由代码为各种各样的机器进行编程,这些都有助于读者迅速入门并渐入佳境,兴趣盎然地深入探索计算机视觉领域。
《学习OpenCV 3(中文版)》可作为信息处理、计算机、机器人、人工智能、遥感图像处理、认知神经科学等有关专业的高年级学生或研究生的教学用书,也可供相关领域的研究工作者参考。
第一个程序:显示图片
OpenCV提供了一些实用工具来读取从视频流到摄像机画面的各种各样的图像格式,这些工具都是HighGUI的一部分。我们将使用其中的一些工具来创建一个简单的程序,这个程序将打开一张图像并且将其显示在屏幕上(如示例2-1所示)。
示例2-1:一个简单的加载并显示图像的OpenCV程序
#include <opencv2/opencv.hpp> //Include file for every supported OpenCV function
int main( int argc, char** argv ) {
cv::Mat img = cv::imread(argv[1],-1);
if( img.empty() ) return -1;
cv::namedWindow( "Example1", cv::WINDOW_AUTOSIZE );
cv::imshow( "Example1", img );
cv::waitKey( 0 );
cv::destroyWindow( "Example1" );
return 0;
}
注意,OpenCV的函数都位于cv这一命名空间下,为了调用OpenCV的函数,你需要在每个函数前加上c v::,向编译器说明你所调用的函数处于c v命名空间。为了摆脱这种繁琐的工作,我们可以像示例2-2一样用using namespace cv;指令,告诉编译器假设所有函数都位于c v命名空间下。注1你还需要注意示例2-1和示例2-2在头文件上的不同,在前者中,我们使用了通用的opencv.hpp,而在后者中,我们只使用了必须的头文件来节约编译时间。
示例2-2:与示例2-1不同的是直接使用了using namespace
#include "opencv2/highgui/highgui.hpp"
using namespace cv;
int main( int argc, char** argv ) {
Mat img = imread( argv[1], -1 );
if( img.empty() ) return -1;
注1: 当然,如果这样做,需要冒着和其他潜在的命名空间冲突的风险。如果函数f o o()已经存在于c v和s t d的命名空间,你必须指定自己使用的是位于c v::f o o()的函数还是位于std::foo()的函数。在本书中,除了示例2-2,都会指明cv::命名空间,并以此保持一个良好的编程风格。
namedWindow( "Example1", cv::WINDOW_AUTOSIZE );
imshow( "Example1", img );
waitKey( 0 );
destroyWindow( "Example1" );
}
当使用命令行编译和运行时,注2示例2-1将加载一张图像到内存中并且显示到屏幕上。它会保持显示直到用户按下一个键,之后程序才会销毁窗口并退出。现在让我们来一行一行地解释代码,并花一些时间来理解每一行代码都在做什么工作。
cv::Mat img = cv::imread( argv[1], -1 );
这一行将会载入图像。注3函数cv::imread()是高级的;依据文件名来决定载入图像格式的处理。这也会自动地申请图像需要的内存,注意,cv::imread()可以读取很多种图像格式,包括BMP,DIP,JPEG,JPE,PNG,PBM,PGM,PPM,SR,RAS以及TIFF。
函数会返回一个c v::M a t结构,这个结构是Op e nCV中你将会接触最多的自带结构。OpenCV使用这个结构来处理所有类型的图像:单通道、多通道、整型、浮点数以及各种类型。紧接着的下面这一行:
if( img.empty() ) return -1;
检查这个图像是否真的被载入了。另一个高层级的函数cv::namedWindow()将会在屏幕打开一个窗口,其中可以包含需要显示的图片。
cv::namedWindow( "Example1", cv::WINDOW_AUTOSIZE );
该函数由HighGUI模块提供,会将一个名称赋予窗口(在这里窗口名为"Example1")。未来HighGUI的和这个窗口的交互函数将由这个名称来指定要与哪个窗口交互。
c v::n a m e d W i n d o w第二个参数说明了Windows的特性。这可以全部设置为0(默认情况下),也可以设置为cv::WINDOW_AUTOSIZE。在之前的例子中,窗口的大小将会和载入图像的大小一致,图像将会被缩放以适应窗口的大小。在之后的例子中,窗口将会在图像载入的时候被自动缩放以适应图像的真实大小,也可能由用户自行调整。
注2: 当然,如果这样做的话,你需要冒着和其他潜在的命名空间冲突的风险。如果函数f o o()已经存在于c v和s t d的命名空间,必须指定你使用的是位于c v::f o o()的函数还是位于std::foo()的函数。在本书中,除了示例2-2,都会指明cv::命名空间,并以此保持一个良好的编程风格。
注3: 好的程序会检查argv[1]是否存在并且给用户反馈一个错误信息,但是在这里没有。我们在本书中将会简略掉这些处理并且假设读者都有足够的的知识来理解处理错误代码的方式及其重要性。
cv::imshow( "Example1", img );
不论何时,只要在c v::M a t中拥有一个图像结构,我们都可以通过c v::i m s h o w()进行显示。c v::i m s h o w()将建一个窗口(如果这个窗口不存在,它会自动调用c v::n a m e d W i n d o w()新建一个窗口)。在调用c v::i m s h o w()的时候,窗口将被重绘上要求的图片,并且窗口会按照要求自动调整大小(如果使用c v::W I N D O W_A U T O S I Z E参数)。
cv::waitKey(0);
c v::w a i t K e y(0);函数告诉系统暂停并且等待键盘事件。如果其传入了一个大于零的参数,它将会等待等同于该参数的毫秒时间,然后继续执行程序。如果参数被设置为0或者一个负数,程序将会无限等待直到有键被按下。
因为有c v::M a t,图像将会在生命周期结束的时候自动释放,其行为类似于标准模板库(STL)中的容器类。这种自动的内存释放由内部的引用指针所控制,最重要的是,这表示我们用不着担心图像的内存申请和释放,这将程序员从OpenCV 1.0 IplImage结构繁琐的维护工作中解放了出来。
cv::destroyWindow( "Example1" );
最后,我们可以让窗口自行销毁。函数cv::destroyWindow()将会关闭窗口并且释放掉相关联的内存空间。为了更简洁的编码,我们将会在之后的例子中略过这一步。在更长、更复杂的代码中,程序员应该在窗口的生命周期自然结束之前自主销毁窗口以防止内存泄漏。
我们下一个任务是创建一个非常简单的、几乎和本例一样的程序来读取视频文件。在此之后,我们将会开始对实际图像进行更多的操作。
目录
译者序 xvii
前言 xxi
第1章 概述 1
什么是OpenCV 1
OpenCV怎么用 2
什么是计算机视觉 3
OpenCV的起源 6
OpenCV的结构 7
使用IPP来加速OpenCV 8
谁拥有OpenCV 9
下载和安装OpenCV 9
安装 9
从Git获取最新的OpenCV 12
更多的OpenCV文档 13
提供的文档 13
在线文档和维基资源 13
OpenCV贡献库 15
下载和编译Contributed模块 16
可移植性 16
小结 17
练习 17
第2章 OpenCV初探 19
头文件 19
资源 20
第一个程序:显示图片 21
第二个程序:视频 23
跳转 24
简单的变换 28
不那么简单的变换 30
从摄像头中读取 32
写入AVI文件 33
小结 34
练习 35
第3章 了解OpenCV的数据类型 37
基础知识 37
OpenCV的数据类型 37
基础类型概述 38
深入了解基础类型 39
辅助对象 46
工具函数 53
模板结构 60
小结 61
练习 61
第4章 图像和大型数组类型 63
动态可变的存储 63
cv::Mat类N维稠密数组 64
创建一个数组 65
独立获取数组元素 69
数组迭代器NAryMatIterator 72
通过块访问数组元素 74
矩阵表达式:代数和cv::Mat 75
饱和转换 77
数组还可以做很多事情 78
稀疏数据类cv::SparesMat 79
访问稀疏数组中的元素 79
稀疏数组中的特有函数 82
为大型数组准备的模板结构 83
小结 85
练习 86
第5章 矩阵操作 87
...
第6章 绘图和注释 139
绘图 139
艺术线条和填充多边形 140
字体和文字 146
小结 148
练习 148
第7章 OpenCV中的函数子 151
操作对象 151
主成分分析(cv::PCA) 151
奇异值分解cv::SVD 154
随机数发生器cv::RNG 157
小结 160
练习 160
第8章 图像、视频与数据文件 163
HighGUI模块:一个可移植的图形工具包 163
图像文件的处理 164
图像的载入与保存 165
关于codecs的一些注释 167
图片的编码与解码 168
视频的处理 169
使用cv::VideoCapture对象读取视频流 169
使用cv::VideoWriter对象写入视频 175
数据存储 176
cv::FileStorage的写入 177
使用cv::FileStorage读取文件 179
cv::FileNode 180
小结 183
练习 183
第9章 跨平台和Windows系统 187
基于Windows开发 187
HighGUI原生图形用户接口 188
通过Qt后端工作 199
综合OpenCV和全功能GUI工具包 209
小结 222
练习 222
第10章 滤波与卷积 225
...
第11章 常见的图像变换 267
...
第12章 图像分析 297
...
第13章 直方图和模板 329
...
第14章 轮廓 359
...
第15章 背景提取 391
...
第16章 关键点和描述子 433
...
第17章 跟踪 511
...
第18章 相机模型与标定 553
...
第19章 投影与三维视觉 599
...
第20章 机器学习基础 665
...
第21章 StatModel:OpenCV中的基准学习模型 689
...
第22章 目标检测 753
...