OpenCV(C++版)入门

了解Opencv

喜欢的可以点赞收藏转发关注

Opencv是一个开源的计算机视觉编程程序库,可在windows,Linux,Mac,Android,iOS上面运行。目前Opencv已经到了第3版,增加了许多功能,API也全部迁移到了C++,当然也有Python版本。并且第三版还增加一个独立的最新算法库(contrib库),其中包含一些最新的算法,可能需要收费,但这些算法仍然在开发中,经常会被修改,没有特殊需求一般不需要使用。

OpenCV(C++版)入门

Opencv包含多个模块,core模块包含核心功能,imgproc模块包含图像处理,highgui模块包含读写图像和视频的一些函数,在使用这些模块之前,需要包含头文件。

#include
 
<opencv2/core.hpp>
#include
 
<opencv2/highgui.hpp>
#include
<opencv2/imgproc.hpp>

图像对象

在Opencv中,图像对象的数据是由Mat来表示的。对计算机来说,图像就是一个矩阵,因此Mat最主要的部分就是一个矩阵数据。除此之外,Mat还包括一些图像的属性,比如图像的长度、宽度、通道数等,我们可以用rows,cols,channels()来获取这些属性。

Mat
 image1
(
240
,
 
320
,
 CV_8U
,
 
100
);
cout 
<<
 image1
.
cols 
<<
 image1
.
rows 
<<
 image1
.
channels
();

除了图像的属性外,图像的像素也有它自己的格式。像素就是矩阵中的一个数据,这个数据的大小就表示了颜色的深浅。由于图像的通道包括单通道的和多通道的,所以像素也分为两种,单通道的就是一个数据就可以,多通道的需要多个数字组成一个像素。最常见的像素格式就是CV8U,这表示这是单通道的像素格式,或者说为一个灰度图像,它的像素值为8个字节,用C++中unsigned char数据类型表示。另一个彩色图像的像素可以用CV8UC3来表示,8U含义与单通道的一样,C3表示三个通道(channels),表示彩色像素类型,由三个数据RGB表示。若是灰度图像,则这三个RGB数据都相等。

OpenCV(C++版)入门

opencv还能够进行图像的读取、展示、保存,读取图像使用imread()函数,保存图像使用imwrite(),展示图像使用imshow()。在读取时,还能够自行选择图像的读取格式,常用的有IMREADGRAYSCALE和IMREADCOLOR,前一个表示灰度图像,后一个表示RGB图像。

Mat
 image 
=
 imread
(
"demo.jpg"
,
IMREAD_COLOR
);
imshow
(
"Image"
,
 image
);
 
// show the image
imwrite
(
"test.jpg"
,
 image
);
waitKey
(
0
);
 
// wait for a key pressed

waitKey(0)则表示在展示图像的时候,在等待规定时间内接受一个按键再进行下一步的操作,如果等待时间设为0,则表示一直等待下去。

Mat是Opencv经过高度优化的数据结构,它自带了内存管理,可以通过检测引用数来释放不需要的内存。同时它的赋值操作也分为浅赋值和深复制,浅赋值能够不必复制大量的数据,从而提高程序的性能,最好只在需要深复制时在进行深复制。

在赋值或者初始化时,使用的是浅赋值,这样变量的指针指向的是同一个数据。

cv
::
Mat
 image2
(
image1
);
image3 
=
 image2
;

如上所示,image1,image2,image3指向的都是内存中同一块数据,所以只要修改其中一个任意一个变量,其他的都会改变。

而在进行深赋值时,需要使用函数copyTo(),或者clone(),这样复制出来的就是两个不同的内存数据块,这样就可以随意修改数据也不会影响其他的了。

其他对象

Point表示点类型,常用来表示坐标。Size表示尺寸,常用来表示图像的大小。Scalar表示色彩,用来表示图像的颜色。还有InputArray表示一个输入数组的代理,由于使用Mat可能会造成参数不兼容,所以Opencv中的函数使用的都是InputArray,同时还有OutputArray对象,表示输出数组的代理。

有时候还会遇到需要小矩阵的情况,这时候可以使用模板类Matx和它的子类。例如定义一个3*3的双精度型的浮点数矩阵可以使用Matx33d,定义一个3元素的向量可以使用Matx31d。这些矩阵还支持矩阵之间的操作,比如相乘相加等。

cv
::
Matx33d
 matrix
(
3.0
,
 
2.0
,
 
1.0
,
 
2.0
,
 
1.0
,
 
3.0
,
 
1.0
,
 
2.0
,
 
3.0
);
cv
::
Matx31d
 vector
(
5.0
,
 
1.0
,
 
3.0
);
cv
::
Matx31d
 result 
=
 matrix
*
vector
;

获取ROI

ROI就是Region of Interest,表示感兴趣的区域。有时候我们只想获取一部分区域,那就需要用到ROI了。ROI实际上就是一个Mat对象,同时他和他的父图像指向的是同一个数据缓冲区,所以改变ROI也就能改变它的父图像了。

imageROI
=
 image
(
cv
::
Rect
(
image
.
cols
-
logo
.
cols
,
image
.
rows
-
logo
.
rows
,
 logo
.
cols
,
logo
.
rows
));

如上代码所演示,ROI可以直接使用Rect来定义,我们可以使用图像的大小和logo的大小来确定ROI的大小,接下来改变imageROI就会改变原始图像image。

另一种定义ROI的方式是使用Range结构,即从开始索引到结束索引的一片连续区域,但是行和列需要分别来定义。

imageROI 
=
 image
(
cv
::
Range
(
image
.
rows
-
logo
.
rows
,
image
.
rows
),
 cv
::
Range
(
image
.
cols
-
logo
.
cols
,
image
.
cols
));

还能直接定义行和列组成的ROI,这样只能选择由特定区域的行或者列,但不是特别灵活。

imageROI 
=
 image
.
rowRange
(
start
,
end
);
imageROI 
=
 image
.
colRange
(
start
,
end
);

上面主要介绍了opencv的一些基础知识,不过想熟练使用,还得多加练习才是。

如果你想了解或者学习C++,欢迎大家加入C++组织,评论+私信扣6,有关必回。记得点赞哦!

相关推荐