关键词不能为空

当前您在: 首页 > 育儿 >

先天性心脏病的原因OpenCV入门教程

作者:陕西保健网
来源:http://www.xapfxb.com/yuer
更新日期:2021-02-24 02:50

-卵巢癌晚期症状

2021年2月24日发(作者:苋实)























































OpenCV
入门教程

作者:于仕琪

@


2012

8


版权所有
?

于仕琪

本作品采用知识共享署名
-
相同方式共享
4.0
国际许可协议进行许可。

1









OpenCV
是一个广受欢迎的开源计算机视觉库,它提供了很多函数,实现了


很多计 算机视觉算法,算法从最基本的滤波到高级的物体检测皆有涵盖。很多
初学者希望快速掌握

OpenCV
的使用方法,但往往会遇到各种各样的困难。其
实仔细分析,造成这些 困难的原因有两类:第一类是

C/C++
编程基础不过关;
第二类是不了解 算法原理。解决这些困难无非提升编程能力,以及提升理论基
础知识。提升编程能力需要多练习编程,提 升理论知识需要系统学习《数字图
像处理》、《计算机视觉》和《模式识别》等课程,所有这些都不能一 蹴而就,
需要耐下心来认真修炼。


同时我们也需要认识到
OpenCV
只是一个算法库,能为我们搭建计算机视觉
应用提供“砖头”。我们并不需要完 全精通了算法原理之后才去使用
OpenCV

只要了解了“砖头”的功能,就可以 动手了。在实践中学习才是最高效的学习
方式。本小册子希望为初学者提供引导,使初学者快速了解 OpenCV
的基本数
据结构以及用法。


此外,如您发现有错误之处,欢迎来信指正。




于仕琪


深圳大学




插播广告
:欢迎有能力、有激情以及对计算机视觉有兴趣的同学报考我的


研究生。欲了解详情可以访问深圳大学招生网

/

或者


给我发
email














2


目录



1


1.1
1.2
1.3
1.4
1.5
预备知识
..................................... .................................................. ........
5
编程的流程
...................... .................................................. ................
5
什么叫编辑
.............. .................................................. ........................
6
什么叫编译
...... .................................................. ................................
6
什么叫连接................................................ ........................................
7
什么叫运行
........................................ ................................................
7
1.6
Visual C++
是什么
.......... .................................................. ......................
8
1.7
1.8
头 文件
............................................ .................................................. ..
9
库文件
.............................. .................................................. ..............
10
1.9
OpenCV
是什么
...................................... .............................................
1
1
1.10
1.11


1.12
1.13

2


什么是命令行参数
... .................................................. .....................
12
常见编译错误
....... .................................................. .........................
13
1.11.1
找不到头文件
................................... ......................................
1
3
1.11.2
拼写错误
.......................... .................................................. .....
1
4
常见链接错误
................... .................................................. .............
15
运行时错误
................ .................................................. ....................
17
OpenCV
介绍
.................................................. .................................
1
9
2.1
OpenCV
的来源
................... .................................................. ..............
1
9
2.2
OpenCV
的协议
...................................... .............................................
1
9

3


3.1
图像的基本操作
.................................. ...............................................
2
1
图像的表示
.......................... .................................................. ..........
21
3.2
Mat

...... .................................................. .........................................
2
3
3.3




创建
Mat
对象
................................... ..............................................
2
4
3.3.1
构造函数方法
.............. .................................................. ...........
2
4
3.3.2 create()
函数创建对象
........................... ....................................
2
5
3.3.3 Matlab
风格的创建对象方法
............... ....................................
2
6

3



3.4
3.5



3.6




矩阵的基本元素表达
.................................................. ....................
2
6
像素值的读写
.... .................................................. ............................
2
7
3.5.1
at()
函数
............................... .................................................. .....
2
8
3.5.2
使用迭代器
......... .................................................. ....................
2
9
3.5.3
通过数据指针
................................... ........................................
3
0
选取图像局部区域
....................... .................................................. .
3
2
3.6.1
单行或单列选择
........... .................................................. ..........
3
2
3.6.2

Range
选择多行或多列
.................................. .....................
3
3
3.6.3
感兴趣区域
.................................... ...........................................
3
3
3.6.4
取对角线元素
.............. .................................................. ...........
3
4
3.7
Mat
表达式
.................................................. .......................................
34
3.8
Mat_

........................ .................................................. ......................
36
3.9
Mat
类的内存管理
................................... ..........................................
38
3.10
输出
............................... .................................................. .................
4
0
3.11 Mat

IplImage

CvMat
的转换
.................................................
4
2


3.11.1 Mat
转为
IplImage

CvMat
格式
..........................................
42
3.11.2 IplImage

CvMat
格式转为
Mat ...........................................
42

4


数据获取与存储
..... .................................................. ..........................
4
4
4.1


4.2











4

读写图像文件
...... .................................................. ..........................
4
4
4.1.1
读图像文件
.................................... ...........................................
4
4
4.1.2
写图像文件
............... .................................................. ..............
4
5
读写视频
............ .................................................. ............................
4
7
4.2.1
读视频
...................................... .................................................
4
7
4.2.2
写视频
................. .................................................. ....................
4
9



1


预备知识


OpenCV < br>是一个功能强大的计算机视觉库,要用好它,除了要具有相关的计
算机视觉理论知识外,还需要具 有一定的编程能力。本书作者通过对

OpenCV
中文论坛中的大量问题观察,发现有很大比例的问题是因为用户对

C/C++
语言
不熟练,导致出错,或出错后不知如何解决。如果对

C/C++
语言不熟悉,那使

OpenCV
时会满头雾水瞎摸索,费心费力。


在这一章中,将介绍一些编程的基本概 念,让读者对编程的流程有一个基
本了解。这样在出现错误时,可以快速确定错误的类型,并知道该如何 解决。


1.1

编程的流程





















一个编程的基本流程包括编辑、编译和连接三大步骤。其流程图如图
1.1


示。

编辑

编辑





编译

编译













opencv_




















连接




5




1.1
编程的基本流程

1.2

什么叫编辑









































编辑(
edit
)代码即编写代码,是编程的第一步 。你可以任意一个编辑器
进行代码的编写。你可以使用

Windows
自 带的“记事本”来编写代码,也可以
使用
Notepad++
,或者
Visual Studio
提供的编辑器。


1.2
使用
Windows
自带的记事本编辑代码

虽然可以使用记事 本软件编辑代码,但是记事本软件的功能非常有限。缺少常
用的语法高亮,自动缩进等功能。所以可以使 用其他功能更丰富的编辑器,如

Notepad++
(图
1.3
)等。



1.3
使用
Notepad++
软件编辑代码


1.3

什么叫编译


编译(
compile
)是将用某种编程语言(如
C++
语言)写 成的源代码,转换成目
标文件。目标文件包含着机器代码(可直接被计算机中央处理器执行)以及代码在
运行时使用的数据。编译器(
compiler
)是实现这一目的的软件。编译器有很 多,
如在
Windows
下有微软公司的

,在
Linux
下有
gcc

g++
。在命令行


6























下使用



源代码进行编译,如图
1.4
所示。编译后,将得到目
标文件

,如图
1.5
所示。



1.4
在命令行下使用



进行编译



1.5
编译后,将新生成

目标文件

1.4

什么叫连接




连接(
link
)是 将多个目标文件,以及库文件生成可执行的文件(或静态库、
或动态库)的过程。连接器(
li nker
)是实现这一目的的软件。常用的连接器有

Windows
下的


Linux
下的
ld
等。



Windows
下可以使用

将前面生成的

连接为可执行文件。在
命令行下效果如所图
1.6
示。连接后,将生成可执行文件,如图
1.7
所示。























1.6
在命令行下使用



进行连接


1.7
连接后,将新生成

可执行文件

1.5

什么叫运行



运行(
run
)较容易理解,我们在
Windows
资源管理器里用鼠标双击
exe

执行程序,可以使程序被载入
CPU
运行。我们也可以在命令行窗口中输入可执

7

















行程序的文件名运行,如图
1.8
所示。


1.8
在命令行窗口中运行

,可以看到程序打印到标准输出的结果。

1.6

Visual C++
是什么



通过前面的介绍,可以看到一个编程的流程:编 辑
->
编译
->
连接
->
运行。更
具体来说,完成 这个流程需要你:

1.

打开记事本软件,编辑代码,并保存;

2.

在命令行下运行编译器,对代码进行编译,生成目标文件;

3.

在命令行下运行连接器,将目标文件连接起来,生成可执行程序;

4.

在命令行下,或
Windows
资源管理器中运行程序,验证程序的正确性。




< br>如果你的项目只有一个源代码文件,完成上面四个步骤尚可接受。但是如
果你的项目包括几十个甚 至几百个源文件,如无其他软件辅助,只用上面四个
非常基本的步骤进行编程开发,会让人抓狂。




集成开发环境(
Integrated Development Environment
,简称
IDE
)可以帮助你
对项目进行管理。常用的
IDE
有微软公司的
Visual Studio
,里面包含
Visual C++


Visual C#
等,其他的还有
Eclipse

NetBeans

Delphi
等。因此我们平时所说的
VC

不是一种编程语言,也不是编译器,它只是一个
IDE


IDE
一般包含编辑器。
IDE
自带的编辑器一般都针对编程语言进行了定制,
实 现语法高亮、自动缩进、自动补全等方便的功能。
IDE
还提供丰富的菜单和按
钮工具,如图
1.9
、图
1.10
和图
1.11
所示。


如果你点击
IDE
中的“生成(
build
)”按钮(图
1.11
),或者点击菜单 “生成

build
)”中的菜单项“生成项目(
build
project
)”,那么

IDE
会去调用编译器


和连接器


来生成可执行程序。如果你在调试状态下,还会去调 用调
试器(
debugger
)。
IDE
会提升程序开发的效率,特别是调试程序的效率。









8




























1.9
微软
Visual Stdio
集成开发环境








1.10 Visual Stdio
中的编辑按钮










1.11 Visual Stdio
中的生成程序按钮

1.7

头文件



在编程过程中,程序代码往往被拆成很多部分,每部分放在一个独立的源文件中,而不是将所有的代码放在一个源文件中。考虑一个简单的小例子:程序中有两
个函数
main()

foo()

main()
函数位于


foo()
函数位于



main()
函数中调用

foo()
函数。在编译阶段,由于编译是对单个文件进行编译,所
以编译


时,编译器不知道是否存在

foo()
函数以及

foo()
调用是否正确,
因此需要头文件辅助。也就是说,在编译命令:


/c



运行时,编译器不知道
foo
的用法是否正确(因为
foo
在另一个文件

中),只有借助头文件中的函数声明来判断。对

进行编译时,不会涉及


文件,只会涉及


foo.h
(因为
foo.h

include
)文件。头文
件的作用如图
1.1
所示。





9











1.

foo()
函数

















2.







int
foo(int
i,
int
j)
,你的

调用看上去是对的。





foo.h



int foo(int i, int j);






#include

int main()

{

int i=foo(3,4);

return i;

}



#include

int foo(int i, int j)


{


……


}







1.12


进行编译时,需要利用头文件中的
foo()
函数声明来确认





foo()
的调用是正确的

1.8

库文件


库文件中包含一系列的子程序。例如在上一节的例子中,

源文件中
实现了
foo()
函数,我们假设
foo()
函数是包含重要算法的函数,我们需要将
foo()
函数提供给客户使 用,但是不希望客户看到算法源代码。为了达到这一目的,
我们可以将

编译程库文件(图
1.13
),库文件是二进制的,在库文件中
是看不到原 始的源代码的。库和可执行文件的区别是,库不是独立程序,他们
是向其他程序提供服务的代码。


当然使用库文件的好处不仅仅是对源代码进行保密,使用库文件还可以减少
重复 编译的时间,增强程序的模块化。将库文件连接到程序中,有两种方式,一
种是静态连接库,另一种是动 态连接库。如果希望了解更多关于库文件的知识,
请查阅相关资料,再次不详细分析它们之间的异同。< br>















10






用户

开发者

编辑





编辑












编译





编译





















连接





1.13
库是二进制的文件,里面包含一系列子程序(
图有问题


1.9
OpenCV
是什么


OpenCV
其实就是一堆
C

C++
语言的源代码文件,这些源代码文件中实现
了许多常用的计算机视觉算法。例如
C
接口函数
cvCanny()
实现了
Canny
边缘提< br>取算法。可以直接将这些源代码添加到我们自己的软件项目中,而不需要自己
再去写代码实现 Canny
算法,也就是不需要重复“造轮子”。


由于

OpenCV
中源代码文件巨多,根据算法的功能,将这些源文件分到多
个模块中:
core

imgproc

highgui
等。将每个模块中的源文件编译成一个库文
件(如

opencv_

opencv_

opencv_
等) ,用户在
使用时,仅将所需的库文件添加到自己的项目中,与自己的源文件一起连接成
可执行程 序则可。







11





1.10
什么是命令行参数

C/C++
语言中的
main
函数,经常带有参数
argc

argv
,如下:

int main(int argc, char** argv)

或者


int main(int argc, char* argv[])


在上面代码中,
argc
表示命令行输入参数的个数(以空白符分隔),
argv

存储了所有的命令行参数。假如你的程序是

,如果在命令行运行该程序
(如图
1.14
。首先应该在命令行下用
cd
命令进入到

文件所在目录),
运行命令为:


Shiqi Yu






















那么,
argc
的值是
3

argv[0]



argv[1]



argv[2]





1.14
使用命令行参数运行程序

下面的程序演示
argc

argv
的使用:









#include

int main(int argc, char ** argv)

{

int i;

for (i=0; i < argc; i++)

printf(
return 0;

}

假如上述代码编译为

,那么运行


a b c d e



12









将得到

Argument 0 is .

Argument 1 is a.

Argument 2 is b.

Argument 3 is c.

Argument 4 is d.

Argument 5 is e.

运行





将得到




Argument 0 is .

Argument 1 is .

1.11
常见编译错误


在编程中,经常会出现各种错误。出现 错误后,不要闭眼抱头作痛苦状。
出现错误后,需要做的第一件事情是阅读出错信息。出错信息虽然看似 凌乱,
但是能够提供很多有价值的信息,帮你解决问题。


1.11.1
找不到头文件


找不到头文件往往会提示如下错误:




(2):
fatal
error
C1083:
Cannot
open
include

file:

'opencv2/': No such file or directory















找不到头文件一般有两个原因:一个是头文件的文件名拼写错误;或者 未将
































opencv2/
被错误地拼写为

openc v2/
。如果文件名拼写正
确,编译器还是找不到头文件,则需要将头文件所在路径添加到相应 的变量中。

如在
Visual Studio 2010
中,需要在项目属性(
Project Property
)对话框中设置头
文件路径。具体位置在对话框“
VC++ Directories
”里面的“
Include Directories


中,如图
1.15
所示。

13





























1.15
头文件所在路径设置


1.11.2
拼写错误


在编程中,拼写错误也是一类常见错误。如图
1.16
所示代码中,将
imread
函数错误地拼成
imreadd
,编译器会提示错误:



(9): error C3861: 'imreadd': identifier not found

这句错误提示的意思是说无法找到

imreadd
标识符,因此我们需要仔细检

imreadd
找不到的原因。假如你真的有一个函数是
imreadd
,但是找不到,可
能的原因是声明
imreadd
的头文件未使用
include
语句包含到源文件中。
























14






























1.16
拼写错误,将
imread
拼成了
imreadd
,会造成编译时错误。


如果源 代码不符合语法规则,则会造成编译错误。编译错误往往是由于编写代
码不仔细造成,比如拼写错误、漏 了半个括号、漏了分号等。因此一旦遇到便宜错
误,你需要按照错误提示,定位到出错的位置,仔细检查 语法是否符合规范。


1.12
常见链接错误




如果你的代码符合语法规则,则会通过编译过程。编译完所有源代码之后,
下一步是连接目标文件,以形成可执行文件。连接过程中最常见的错误如下(图

1.17
):

1> : error LNK2019: unresolved external symbol
cv::Mat
__cdecl
cv::imread(class
std::basic_stringstd::char_traits,class
std::allocator
> const
&,int)
(?imread@cv@@YA?AVMat@1@ABV?$$basic_string@DU?$$cha r_traits@D@std@@
V?$$allocator@D@2@@std@@H@Z) referenced in function _main







这个错误信息里最关键的词是“
unresolved
external
symbol
”,更具体的意
思是在

main
函数中使用了

imread
函数,但是无法从外部找到

imread

imread
函数是

OpenCV
的函数,不是用户自己实现的函数。

头文件告诉编
译器有个

imread
函数可以用,编译通过;但是到了连接时,连接器却找不到

imread
的具体实现,故出错。

15





























1.17
连接错误,无法找到
imread
等函数的实现































1.18
添加依赖的库文件







16

要解决这一问题,需要将依赖的库文件添加到项目设置中。具体位置在对
话框“
Linker - Input
”里面的“
Additional Dependencies
”中,如图
1.18
所示。



1.13
运行时错误

经过编译和连接过程,生成了可执行的文件(如
exe
文件)之后,在运行这个可执行文件所产生的错误是运行时错误。比较常见的运行时错误是内存错误。
比如下面这段代码:
















#include


#include


using namespace cv;

int main()

{

printf(

);

Mat img = imread(

);

Mat gray;

cv::cvtColor(img, gray, CV_BGR2GRAY);

return 0;

}






























编译和连接过程无任何问题,但在运行时弹出如图
1.19
所示对话框,并在
命令行窗口输出错误信息(图
1.20
)。


1.19
运行时错误对话框


1.20
运行时错误的出错信息

17
















2834


错< br>,







(scn==3 ||scn==4)
不成立。很多
OpenCV
用户看到此错误信息一头雾水,不 知如何下
手解决。根据程序源代码的意思,是将三通道的

BGR
图像

img
转为单通道的图像

gray
。但是程序说
img
既不是
3
通道,也不是
4
通道。而根据
imread
函数的文档,
imread
将图像作为彩色图像读入,条件
(scn==3 ||scn==4)
肯定成立。


这个程序的问题出现在当前目录下无


文件,这样程序无法读到图像,
造成
cvtColor
函数出错。因此对于读入图像时,需要检查图像读入是否成功,以
免造成运行时错误。


在程序编写中,对于数组和指针等,要特别地小心。因为对于空指针以及数
组越界等 问题,编译器无法在编译时给出错误提示。这类错误一旦在运行时发生,
排除起来非常困难。


















































18



2

OpenCV
介绍


OpenCV
的全称是
Open Source Computer Vision Library
,是一个开放源代码
的计算机视觉库。
OpenCV
是最初由英特尔公司发起并开发,以
BSD
许可证授权
发行,可以在商业和研究领域中免费使用,现在美国

Willow
Garage


OpenCV
提供主要的支持。
OpenCV
可用于开发实时的图像处理、计算机视觉以及模式识
别程序,目前在工业界以及科研领域广泛采用。


2.1
OpenCV
的来源




OpenCV
诞生于
Intel

Intel
最初希望提供一个计算机视觉库,使之能充分发



CPU
的计算能力,当然更希望以此促进
Intel
的产品的销售。
OpenCV
最初的开发
工作是由
Intel
在俄罗斯的团队实现。这里面有两个关键人物,一个是
Intel


能团队(
Intel’s
Performance
Library
Team
)的李信弘(
Shinn
Lee
)先生,他是团队
的经理,负责

IPP
等库,给予

OpenCV
很大的支持。另一个关键人物是

Vadim
Pisarevsky

Vadim

Intel
负责
OpenCV
的项目管理、代码集成、代码优化等工作。
在后期
Intel
支持渐少的时候,是
Vadim Pisarevsky
一直在维护着
OpenCV

2007


6
月,受本书作者之邀,李信弘和
Vadim Pisarevsky
作为嘉宾参加了在北





京举行的“开放源 代码计算机视觉库
(OpenCV)
研讨会”
,并做了非常有价值的
报告。< br>


2008
年,一家美国公司,
Willow
Garage
,开始大力支持

OpenCV

Vadim
Pisarevsky

Gary Bradski
都加入了
Willow Garage

Gary Bradski
也是
OpenCV


发者中的元老级人物,他曾出版《
Leaning OpenCV
》一书,广受欢迎。

2
1
Willow
Garage
是一家机器人公司,致力于为个人机器人开发开放的硬件平
台和软件。现在已经开发了

PR2
机器人,并支持

ROS

OpenCV

PCL
等软件。
ROS

Robot
Operating
System
)是用于机器人的操作系统,是一个开放源代码的
软件,
OpenCV
作为
ROS
的视觉模块嵌入。


自从获得

Willow
Garage
支持后,
OpenCV
的更新速度明显加快。大量的新
特性被被加入

OpenCV
中,很多算法都是最近一两年的新的科研成果。
OpenCV
正日益成为算法研究和产品开发不可缺少的工具。


2.2
OpenCV
的协议








OpenCV
采用
BSD
协议,这是一个非常宽松的协议。简而言之,用户可以修

1
2

研讨会网址:
//OpenCV_Symposium


Willow Garage
公司网站:


19







OpenCV
的源代码,可以将

OpenCV
嵌入到自己的软件中,可以将包含

OpenCV
的软件销售,可以用于商业产品,也可以用于科研领域。
BSD
协议并不具有“传染
性”,如果你的软件中使用了

OpenCV
,你不需要公开代码。你可以对

OpenCV

任何操作,协议对用户的唯一约束是要在软件的文档或者说明中注明使用了

OpenCV
,并附上
OpenCV
的协议。

在这个宽松协议下,企业可以在
OpenCV
基础之上进行产品开发,而不需要担
心版权问题(当然你要注明使用了

OpenCV
,并附上

OpenCV
的协议)。科研领域
的研究者,可以使用

OpenCV
快速地实 现系统原型。因此可以这样说,
OpenCV

协议保证了计算机视觉技术快速的传播 ,让更多的人从
OpenCV
受益。






















































20



3


图像的基本操作


3.1

图像的表示





















































在正式介绍之前,先简单介绍一下数字图像的基本概念。如图
3.1
中所示
的图像,我们看到的是
Lena
的头像,但是计算机看来,这副图像只是一堆亮度
各异的点。一副尺寸为
M
×
N
的图像可以用一个
M
×
N
的矩阵 来表示,矩阵
元素的值表示这个位置上的像素的亮度,一般来说像素值越大表示该点越亮。
如图
3.1
中白色圆圈内的区域,进行放大并仔细查看,将会如图
3.2
所示。



3.1 Lena
的照片

21
























3.2

3.1
中圆圈处的放大效果



一般来说,灰度图用
2
维矩阵表示,彩色(多通道)图像用
3
维矩阵(
M

×

N
×
3
)表示。对于图像显示来说,目前大部分设备都是用无符号
8
位整
数(类型为
CV_8U
)表示像素亮度。

图像数据 在计算机内存中的存储顺序为以图像最左上点(也可能是最左下
点)开始,存储如表
3-1
所示。




3-1
灰度图像的存储示意图


I
0 0



I
0 1





I
0 N-1

I
1 N-1


I
1 0



I
1 1
















I
M-1 N-1


I
M-1 0

I
M-1 1










I
ij

表示第
i

j
列的像素值。如果是多通道图像,比如
RGB
图像,则每个
像素用三个字节表示。在
OpenCV
中,
RGB
图像的通道顺序为
BGR
,存储如



3-2
所示。



3-2
彩色
RGB
图像的存储示意图

B
00



G
00


R
00


B
01


G
01


R
01







B
10



G
10


R
10


B
11


G
11


R
11







22
























3.2
Mat




早期的
OpenCV
中,使用
IplImage

CvMat
数据结构来表示图像。
IplImage



CvMat
都是

C
语言的结构。使用这两个结构的问题是内存需要手动管理,开发者必须清楚的知道何时需要申请内存,何时需要释放内存。这个开发者带来
了一定的负担,开发者 应该将更多精力用于算法设计,因此在新版本的

OpenCV
中引入了
Mat
类。


新加入的
Mat
类能够自动管理内存。使用
Mat
类,你不再需要花费大量精
力在内存管 理上。而且你的代码会变得很简洁,代码行数会变少。但

C++
接口
唯一的不足是当前一些嵌入式开发系统可能只支持

C
语言,如果你的开发平台
支持
C++
,完全没有必要再用
IplImage

CvMat
。在新版本的
OpenCV
中,开发
者依然可以使用

IplImage


CvMat
,但是一些新增加的函数只提供了

Mat
接口。
本书中的例程也都将采用新的
Mat
类,不再介绍
IplImage

CvMat


























23

Mat
类的定义如下所示,关键的属性如下方代码所示:

class CV_EXPORTS Mat

{

public:

//
一系列函数

...

/* flag
参数中包含许多关于矩阵的信息,如:

-Mat
的标识

-
数据是否连续

-
深度

-
通道数目

*/

int flags;

//
矩阵的维数,取值应该大于或等于
2

int dims;

//
矩阵的行数和列数,如果矩阵超过
2
维,这两个变量的值都为
-1 int rows, cols;

//
指向数据的指针

uchar* data;

//
指向引用计数的指针

//
如果数据是由用户分配的,则为
NULL

int* refcount;





//
其他成员变量和成员函数

...

};

3.3

创建

Mat

对象


Mat
是一个非常优秀的图像类,它同时也是一个通用的矩阵类,可以用来
创建和操 作多维矩阵。有多种方法创建一个
Mat
对象。


3.3.1
构造函数方法


Mat
类提供了一系列构造函数,可以方便的根据需要创建

Mat
对象。下面
是一个使用构造函数创建对象的例子。




Mat M(3,2, CV_8UC3, Scalar(0,0,255));

cout <<

第一行代码创建一个行数(高度)为

3
,列数(宽度)为

2
的图像,图像
元素是

8
位无符号整数类型,且有三个通道。图像的所有像素值被初始化为
(0,
0, 255)
。由于
OpenCV
中默认的颜色顺序为
BGR
,因此这是一个全红色的图像。


第二行代码是输出
Mat
类的实例
M
的所有像素值。
Mat
重定义了
<<
操作符,
使用这个操作符,可以方便地输出所有像素值,而不需要使用

for
循环逐个像
素输出。













3.3
例程输出内容


该段代码的输出如图
3.3
所示。

常用的构造函数有:

?
?
?
?
?
?
?
?

Mat::Mat()
?

Mat::Mat(int rows, int cols, int type)
?

Mat::Mat(Size size, int type)
?
创建行数为
rows
,列数为
col
,类型为
type
的图像;
创建大小为
size
,类型为
type
的图像;
无参数构造方法;
?
?
?


Mat::Mat(int rows, int cols, int type, const Scalar& s)
?
24


?
?
?
?

Mat::Mat(Size size, int type, const Scalar& s)
?

Mat::Mat(const Mat& m)
?
创建行数为
rows
,列数为
col
,类型为
type
的图像,并将所有元素初始
化为值
s


创建大小为
size
,类型为
type
的图像,并将所有元素初始化为值
s

?
?
?

m
赋值给新创建的对象,此处不会对图像数据进行复制,
m
和新对
?
象共用图像数据;

Mat::Mat(int rows, int cols, int type, void* data, size_t step=AUTO_STEP)

Mat::Mat(Size size, int type, void* data, size_t step=AUTO_STEP)
?
?
?
?
创建行数为
rows
,列数为
col
,类型为
type
的图像,此构造函数不创建
图像数据所需内存,而是直接使用

data
所指内存,图像的行步长由

?
step
指定。
创建大小为
size
,类型为
type
的图像,此构造函数不创建图像数据所
?
需内存,而是直接使用
data
所指内存,图像的行步长由
step
指定。
?
?
?

?

Mat::Mat(const Mat& m, const Range& rowRange, const Range& colRange)
?

Mat::Mat(const Mat& m, const Rect& roi)
?
创建的新图像为

m
的一部分,具体的范围由

rowRange


colRange

定,此构造函数也不进行图像数据的复制操作,新图像与

m
共用图像
?
数据;
?
创建的新图像为
m
的一部分,具体的范围
roi
指定,此构造函数也不进
?
行图像数据的复制操作,新图像与
m
共用图像数据。
这些构造函数中,很多都涉及到类型
type

type
可以是
CV_8UC1

CV_16SC1



CV_64FC4
等。里面的
8U
表示
8
位无符号整数,
16S
表示
16
位有
符号整数,
64F
表示
64
位浮点数(即
double
类型);
C
后面的数表示通道数,例

C1
表示一个通道的图像,
C4
表示
4
个通道的图像,以此类推。


如果你需要更多的通道数,需要用宏
CV_8UC(n)
,例如:


Mat M(3,2, CV_8UC(5));//
创建行数为
3
,列数为
2
,通道数为
5
的图像


3.3.2 create()
函数创建对象


除了在构造函数中可以创建图像,也可以使用
Mat
类的
create()
函数创建图
像。如果

create()
函数指定 的参数与图像之前的参数相同,则不进行实质的内存
申请操作;如果参数不同,则减少原始数据内存的索 引,并重新申请内存。使
用方法如下面例程所示:


Mat M(2,2, CV_8UC3);//
构造函数创建图像

(3,2, CV_8UC2);//
释放内存重新创建图像



25

-卵巢癌晚期症状


-卵巢癌晚期症状


-卵巢癌晚期症状


-卵巢癌晚期症状


-卵巢癌晚期症状


-卵巢癌晚期症状


-卵巢癌晚期症状


-卵巢癌晚期症状



本文更新与2021-02-24 02:50,由作者提供,不代表本网站立场,转载请注明出处:http://www.xapfxb.com/yuer/456953.html

OpenCV入门教程的相关文章