OpenCV入门教程.docx
- 文档编号:119923
- 上传时间:2023-04-28
- 格式:DOCX
- 页数:52
- 大小:47.47KB
OpenCV入门教程.docx
《OpenCV入门教程.docx》由会员分享,可在线阅读,更多相关《OpenCV入门教程.docx(52页珍藏版)》请在冰点文库上搜索。
OpenCV入门教程
OpenCV入门教程
作者:
于仕琪
shiqi.yu@
2012年8月
版权所有©于仕琪
本作品采用知识共享署名-相同方式共享4.0国际许可协议进行许可。
1
前言
OpenCV是一个广受欢迎的开源计算机视觉库,它提供了很多函数,实现了
很多计算机视觉算法,算法从最基本的滤波到高级的物体检测皆有涵盖。
很多初学者希望快速掌握OpenCV的使用方法,但往往会遇到各种各样的困难。
其实仔细分析,造成这些困难的原因有两类:
第一类是C/C++编程基础不过关;第二类是不了解算法原理。
解决这些困难无非提升编程能力,以及提升理论基础知识。
提升编程能力需要多练习编程,提升理论知识需要系统学习《数字图像处理》、《计算机视觉》和《模式识别》等课程,所有这些都不能一蹴而就,需要耐下心来认真修炼。
同时我们也需要认识到OpenCV只是一个算法库,能为我们搭建计算机视觉应用提供“砖头”。
我们并不需要完全精通了算法原理之后才去使用OpenCV,只要了解了“砖头”的功能,就可以动手了。
在实践中学习才是最高效的学习方式。
本小册子希望为初学者提供引导,使初学者快速了解OpenCV的基本数据结构以及用法。
此外,如您发现有错误之处,欢迎来信指正。
于仕琪
深圳大学
插播广告:
欢迎有能力、有激情以及对计算机视觉有兴趣的同学报考我的
研究生。
欲了解详情可以访问深圳大学招生网或者
给我发email。
2
3
4
第1章预备知识
OpenCV是一个功能强大的计算机视觉库,要用好它,除了要具有相关的计算机视觉理论知识外,还需要具有一定的编程能力。
本书作者通过对OpenCV中文论坛中的大量问题观察,发现有很大比例的问题是因为用户对C/C++语言不熟练,导致出错,或出错后不知如何解决。
如果对C/C++语言不熟悉,那使用OpenCV时会满头雾水瞎摸索,费心费力。
在这一章中,将介绍一些编程的基本概念,让读者对编程的流程有一个基本了解。
这样在出现错误时,可以快速确定错误的类型,并知道该如何解决。
1.1编程的流程
一个编程的基本流程包括编辑、编译和连接三大步骤。
其流程图如图所
示。
编辑编辑
a.cppb.cpp
编译编译
opencv_core.lib
a.obj
b.obj
连接
main.exe
5
图1.1编程的基本流程
1.2什么叫编辑
编辑(edit)代码即编写代码,是编程的第一步。
你可以任意一个编辑器进行代码的编写。
你可以使用Windows自带的“记事本”来编写代码,也可以使用Notepad++,或者VisualStudio提供的编辑器。
图1.2使用Windows自带的记事本编辑代码
虽然可以使用记事本软件编辑代码,但是记事本软件的功能非常有限。
缺少常用的语法高亮,自动缩进等功能。
所以可以使用其他功能更丰富的编辑器,如
Notepad++)等。
图1.3使用Notepad++软件编辑代码
1.3什么叫编译
编译(compile)是将用某种编程语言(如C++语言)写成的源代码,转换成目标文件。
目标文件包含着机器代码(可直接被计算机中央处理器执行)以及代码在运行时使用的数据。
编译器(compiler)是实现这一目的的软件。
编译器有很多,如在Windows下有微软公司的cl.exe,在Linux下有gcc和g++。
在命令行
6
下使用cl.exe对hello.cpp源代码进行编译,如图所示。
编译后,将得到目标文件hello.obj,如图所示。
图1.4在命令行下使用cl.exe对hello.cpp进行编译
图1.5编译后,将新生成hello.obj目标文件
1.4什么叫连接
连接(link)是将多个目标文件,以及库文件生成可执行的文件(或静态库、或动态库)的过程。
连接器(linker)是实现这一目的的软件。
常用的连接器有
Windows下的link.exe,Linux下的ld等。
在Windows下可以使用link.exe将前面生成的hello.obj连接为可执行文件。
在命令行下效果如所图示。
连接后,将生成可执行文件,如图所示。
图1.6在命令行下使用link.exe对hello.obj进行连接
图1.7连接后,将新生成hello.exe可执行文件
1.5什么叫运行
运行(run)较容易理解,我们在Windows资源管理器里用鼠标双击exe可执行程序,可以使程序被载入CPU运行。
我们也可以在命令行窗口中输入可执
7
行程序的文件名运行,如图所示。
图1.8在命令行窗口中运行hello.exe,可以看到程序打印到标准输出的结果。
1.6VisualC++是什么
通过前面的介绍,可以看到一个编程的流程:
编辑->编译->连接->运行。
更具体来说,完成这个流程需要你:
1.打开记事本软件,编辑代码,并保存;
2.在命令行下运行编译器,对代码进行编译,生成目标文件;
3.在命令行下运行连接器,将目标文件连接起来,生成可执行程序;
4.在命令行下,或Windows资源管理器中运行程序,验证程序的正确性。
如果你的项目只有一个源代码文件,完成上面四个步骤尚可接受。
但是如果你的项目包括几十个甚至几百个源文件,如无其他软件辅助,只用上面四个非常基本的步骤进行编程开发,会让人抓狂。
集成开发环境(IntegratedDevelopmentEnvironment,简称IDE)可以帮助你对项目进行管理。
常用的IDE有微软公司的VisualStudio,里面包含VisualC++,VisualC#等,其他的还有Eclipse、NetBeans、Delphi等。
因此我们平时所说的VC
不是一种编程语言,也不是编译器,它只是一个IDE。
IDE一般包含编辑器。
IDE自带的编辑器一般都针对编程语言进行了定制,实现语法高亮、自动缩进、自动补全等方便的功能。
IDE还提供丰富的菜单和按钮工具,如图、图所示。
如果你点击IDE中的“生成(build)”按钮(图),或者点击菜单“生成(build)”中的菜单项“生成项目(buildproject)”,那么IDE会去调用编译器cl.exe和连接器link.exe来生成可执行程序。
如果你在调试状态下,还会去调用调试器(debugger)。
IDE会提升程序开发的效率,特别是调试程序的效率。
8
图1.9微软VisualStdio集成开发环境
图1.10VisualStdio中的编辑按钮
图1.11VisualStdio中的生成程序按钮
1.7头文件
在编程过程中,程序代码往往被拆成很多部分,每部分放在一个独立的源文件中,而不是将所有的代码放在一个源文件中。
考虑一个简单的小例子:
程序中有两个函数main()和foo()。
main()函数位于main.cpp,foo()函数位于foo.cpp,
main()函数中调用foo()函数。
在编译阶段,由于编译是对单个文件进行编译,所以编译main.cpp时,编译器不知道是否存在foo()函数以及foo()调用是否正确,因此需要头文件辅助。
也就是说,在编译命令:
cl.exe/cmain.cpp
运行时,编译器不知道foo的用法是否正确(因为foo在另一个文件foo.cpp中),只有借助头文件中的函数声明来判断。
对main.cpp进行编译时,不会涉及
foo.cpp文件,只会涉及main.cpp和foo.h(因为foo.h被include)文件。
头文件的作用如图所示。
9
1.foo()函数这样用对
main.cpp
#include"foo.h"
intmain()
{
inti=foo(3,4);
returni;
}
2.函数声明是intfoo(inti,intj),你的调用看上去是对的。
foo.h
intfoo(inti,intj);
foo.cpp
#include"foo.h"
intfoo(inti,intj)
{
……
}
图1.12对main.cpp进行编译时,需要利用头文件中的foo()函数声明来确认main.cpp中
对foo()的调用是正确的
1.8库文件
库文件中包含一系列的子程序。
例如在上一节的例子中,foo.cpp源文件中实现了foo()函数,我们假设foo()函数是包含重要算法的函数,我们需要将foo()函数提供给客户使用,但是不希望客户看到算法源代码。
为了达到这一目的,我们可以将foo.cpp编译程库文件(图),库文件是二进制的,在库文件中是看不到原始的源代码的。
库和可执行文件的区别是,库不是独立程序,他们是向其他程序提供服务的代码。
当然使用库文件的好处不仅仅是对源代码进行保密,使用库文件还可以减少重复编译的时间,增强程序的模块化。
将库文件连接到程序中,有两种方式,一种是静态连接库,另一种是动态连接库。
如果希望了解更多关于库文件的知识,请查阅相关资料,再次不详细分析它们之间的异同。
10
用户
开发者
编辑
编辑
main.cpp
foo.cpp
编译
编译
main.obj
foo.lib
foo.obj
连接
main.exe
图1.13库是二进制的文件,里面包含一系列子程序(图有问题)
1.9OpenCV是什么
OpenCV其实就是一堆C和C++语言的源代码文件,这些源代码文件中实现了许多常用的计算机视觉算法。
例如C接口函数cvCanny()实现了Canny边缘提取算法。
可以直接将这些源代码添加到我们自己的软件项目中,而不需要自己再去写代码实现Canny算法,也就是不需要重复“造轮子”。
由于OpenCV中源代码文件巨多,根据算法的功能,将这些源文件分到多个模块中:
core、imgproc、highgui等。
将每个模块中的源文件编译成一个库文件(如opencv_core.lib、opencv_imgproc.lib、opencv_highgui.lib等),用户在使用时,仅将所需的库文件添加到自己的项目中,与自己的源文件一起连接成可执行程序则可。
11
1.10什么是命令行参数
C/C++语言中的main函数,经常带有参数argc,argv,如下:
intmain(intargc,char**argv)
或者
intmain(intargc,char*argv[])
在上面代码中,argc表示命令行输入参数的个数(以空白符分隔),argv中存储了所有的命令行参数。
假如你的程序是hello.exe,如果在命令行运行该程序(如图。
首先应该在命令行下用cd命令进入到hello.exe文件所在目录),运行命令为:
hello.exeShiqiYu
那么,argc的值是3,argv[0]是"hello.exe",argv[1]是"Shiqi",argv[2]是"Yu"。
图1.14使用命令行参数运行程序
下面的程序演示argc和argv的使用:
#include
intmain(intargc,char**argv)
{
inti;
for(i=0;i printf("Argument%dis%s.\n",i,argv[i]);return0; } 假如上述代码编译为hello.exe,那么运行 hello.exeabcde 12 将得到 Argument0ishello.exe. Argument1isa. Argument2isb. Argument3isc. Argument4isd. Argument5ise. 运行 hello.exelena.jpg 将得到 Argument0ishello.exe. Argument1islena.jpg. 1.11常见编译错误 在编程中,经常会出现各种错误。 出现错误后,不要闭眼抱头作痛苦状。 出现错误后,需要做的第一件事情是阅读出错信息。 出错信息虽然看似凌乱,但是能够提供很多有价值的信息,帮你解决问题。 1.11.1找不到头文件 找不到头文件往往会提示如下错误: hello.cpp (2): fatalerrorC1083: Cannotopenincludefile: 'opencv2/opencv.hppp': Nosuchfileordirectory 找不到头文件一般有两个原因: 一个是头文件的文件名拼写错误;或者未将头文件所在路径添加到开发环境中。 上例中的错误是文件名拼写错误,opencv2/opencv.hpp被错误地拼写为opencv2/opencv.hppp。 如果文件名拼写正确,编译器还是找不到头文件,则需要将头文件所在路径添加到相应的变量中。 如在VisualStudio2010中,需要在项目属性(ProjectProperty)对话框中设置头文件路径。 具体位置在对话框“VC++Directories”里面的“IncludeDirectories” 中,如图所示。 13 图1.15头文件所在路径设置 1.11.2拼写错误 在编程中,拼写错误也是一类常见错误。 如图所示代码中,将imread函数错误地拼成imreadd,编译器会提示错误: hello.cpp(9): errorC3861: 'imreadd': identifiernotfound 这句错误提示的意思是说无法找到imreadd标识符,因此我们需要仔细检查imreadd找不到的原因。 假如你真的有一个函数是imreadd,但是找不到,可能的原因是声明imreadd的头文件未使用include语句包含到源文件中。 14 图1.16拼写错误,将imread拼成了imreadd,会造成编译时错误。 如果源代码不符合语法规则,则会造成编译错误。 编译错误往往是由于编写代码不仔细造成,比如拼写错误、漏了半个括号、漏了分号等。 因此一旦遇到便宜错误,你需要按照错误提示,定位到出错的位置,仔细检查语法是否符合规范。 1.12常见链接错误 如果你的代码符合语法规则,则会通过编译过程。 编译完所有源代码之后,下一步是连接目标文件,以形成可执行文件。 连接过程中最常见的错误如下(图 ): 1>hello.obj: errorLNK2019: unresolvedexternalsymbol"classcv: : Mat__cdeclcv: : imread(classstd: : basic_string : char_traits : allocator imread@cv@@YA? AVMat@1@ABV? $basic_string@DU? $char_traits@D@std@@V? $allocator@D@2@@std@@H@Z)referencedinfunction_main 这个错误信息里最关键的词是“unresolvedexternalsymbol”,更具体的意思是在main函数中使用了imread函数,但是无法从外部找到imread。 imread函数是OpenCV的函数,不是用户自己实现的函数。 opencv.hpp头文件告诉编译器有个imread函数可以用,编译通过;但是到了连接时,连接器却找不到imread的具体实现,故出错。 15 图1.17连接错误,无法找到imread等函数的实现 要解决这一问题,需要将依赖的库文件添加到项目设置中。 具体位置在对话框“Linker-Input”里面的“AdditionalDependencies”中,如图所示。 图1.18添加依赖的库文件 16 1.13运行时错误 经过编译和连接过程,生成了可执行的文件(如exe文件)之后,在运行这个可执行文件所产生的错误是运行时错误。 比较常见的运行时错误是内存错误。 比如下面这段代码: #include #include usingnamespacecv; intmain() { printf("Hello,OpenCV! \n"); Matimg=imread("lena.jpg"); Matgray; cv: : cvtColor(img,gray,CV_BGR2GRAY); return0; } 编译和连接过程无任何问题,但在运行时弹出如图所示对话框,并在命令行窗口输出错误信息(图)。 图1.19运行时错误对话框 图1.20运行时错误的出错信息 17 错误信息中提示color.cpp文件的第2834行有错,错误原因是条件(scn==3||scn==4)不成立。 很多OpenCV用户看到此错误信息一头雾水,不知如何下手解决。 根据程序源代码的意思,是将三通道的BGR图像img转为单通道的图像gray。 但是程序说img既不是3通道,也不是4通道。 而根据imread函数的文档,imread将图像作为彩色图像读入,条件(scn==3||scn==4)肯定成立。 这个程序的问题出现在当前目录下无lena.jpg文件,这样程序无法读到图像,造成cvtColor函数出错。 因此对于读入图像时,需要检查图像读入是否成功,以免造成运行时错误。 在程序编写中,对于数组和指针等,要特别地小心。 因为对于空指针以及数组越界等问题,编译器无法在编译时给出错误提示。 这类错误一旦在运行时发生,排除起来非常困难。 18 第2章OpenCV介绍 OpenCV的全称是OpenSourceComputerVisionLibrary,是一个开放源代码的计算机视觉库。 OpenCV是最初由英特尔公司发起并开发,以BSD许可证授权发行,可以在商业和研究领域中免费使用,现在美国WillowGarage为OpenCV提供主要的支持。 OpenCV可用于开发实时的图像处理、计算机视觉以及模式识别程序,目前在工业界以及科研领域广泛采用。 2.1OpenCV的来源 OpenCV诞生于Intel。 Intel最初希望提供一个计算机视觉库,使之能充分发 掘CPU的计算能力,当然更希望以此促进Intel的产品的销售。 OpenCV最初的开发工作是由Intel在俄罗斯的团队实现。 这里面有两个关键人物,一个是Intel性 能团队(Intel’sPerformanceLibraryTeam)的李信弘(ShinnLee)先生,他是团队的经理,负责IPP等库,给予OpenCV很大的支持。 另一个关键人物是VadimPisarevsky,Vadim在Intel负责OpenCV的项目管理、代码集成、代码优化等工作。 在后期Intel支持渐少的时候,是VadimPisarevsky一直在维护着OpenCV。 2007年6月,受本书作者之邀,李信弘和VadimPisarevsky作为嘉宾参加了在北 京举行的“开放源代码计算机视觉库(OpenCV)研讨会”1,并做了非常有价值的报告。 在2008年,一家美国公司,WillowGarage2,开始大力支持OpenCV,VadimPisarevsky和GaryBradski都加入了WillowGarage。 GaryBradski也是OpenCV开 发者中的元老级人物,他曾出版《LeaningOpenCV》一书,广受欢迎。 WillowGarage是一家机器人公司,致力于为个人机器人开发开放的硬件平台和软件。 现在已经开发了PR2机器人,并支持ROS、OpenCV、PCL等软件。 ROS(RobotOperatingSystem)是用于机器人的操作系统,是一个开放源代码的软件,OpenCV作为ROS的视觉模块嵌入。 自从获得WillowGarage支持后,OpenCV的更新速度明显加快。 大量的新特性被被加入OpenCV中,很多算法都是最近一两年的新的科研成果。 OpenCV正日益成为算法研究和产品开发不可缺少的工具。 2.2OpenCV的协议 OpenCV采用BSD协议,这是一个非常宽松的协议。 简而言之,用户可以修 1研讨会网址: 2WillowGarage公司网站: 19 改OpenCV的源代码,可以将OpenCV嵌入到自己的软件中,可以将包含OpenCV的软件销售,可以用于商业产品,也可以用于科研领域。 BSD协议并不具有“传染性”,如果你的软件中使用了OpenCV,你不需要公开代码。 你可以对OpenCV做任何操作,协议对用户的唯一约束是要在软件的文档或者说明中注明使用了 OpenCV,并附上OpenCV的协议。 在这个宽松协议下,企业可以在OpenCV基础之上进行产品开发,而不需要担心版权问题(当然你要注明使用了OpenCV,并附上OpenCV的协议)。 科研领域的研究者,可以使用OpenC
- 配套讲稿:
如PPT文件的首页显示word图标,表示该PPT已包含配套word讲稿。双击word图标可打开word文档。
- 特殊限制:
部分文档作品中含有的国旗、国徽等图片,仅作为作品整体效果示例展示,禁止商用。设计者仅对作品中独创性部分享有著作权。
- 关 键 词:
- OpenCV 入门教程
![提示](https://static.bingdoc.com/images/bang_tan.gif)