OpenCV学习笔记基础篇(三):基本数据结构介绍

前言:

笔者目前在校本科大二,有志于进行计算机视觉、计算机图形学方向的研究,准备系统性地、扎实的学习一遍OpenCV的内容,故记录学习笔记,同时,由于笔者同时学习数据结构、机器学习等知识,会尽量根据自己的理解,指出OpenCV的应用,并在加上自己理解的前提下进行叙述。
若有不当之处,希望各位批评、指正。


本篇学习内容:

1.基本数据结构介绍


介绍

在第一篇、第二篇中,我介绍了在OpenCV中如何进行图像读写,以及创建窗口、创建滑动条。本篇则介绍OpenCV中的基础数据结构。
我本不想以这种形式介绍数据结构。因为在前期了解了这些之后,仍会云里雾里。我更擅长在运用中进行知识的掌握。但是为了加深印象,我还是单独介绍一下OpenCV中的数据结构。


1.基本数据结构介绍

1.1 Mat

Mat类,现作为基础图像容器。在我看来,Mat其实就是OpenCV提供的一个用于储存矩阵的数据结构。就像Python里的numpy那样。

Mat由两部分构成。矩阵头和一个指向存储所有值的矩阵指针。矩阵头的尺寸是常数值,但矩阵本身的尺寸会依图像的不同而不同。

关于Mat,我们不必手动为其开辟空间,也不必在不需要时立即将空间释放。

为了解决在进行大规模矩阵复制时的开销,OpenCV采用了引用计数机制。即让每个Mat对象有自己的信息头,但共享一个矩阵。在内存管理上,只有一个矩阵的引用次数计数值为0时,才会被清理。
官方文档:Use a copy constructor or assignment operator where there can be an array or expression on the right side (see below). As noted in the introduction, the array assignment is an O(1) operation because it only copies the header and increases the reference counter. The Mat::clone() method can be used to get a full (deep) copy of the array when you need it.
Once the array is created, it is automatically managed via a reference-counting mechanism. If the array header is built on top of user-allocated data, you should handle the data by yourself. The array data is deallocated when no one points to it. If you want to release the data pointed by a array header before the array destructor is called, use Mat::release().

注意:在用operator=进行复制的时候,两个矩阵头会指向同一个矩阵。当你需要复制出一个独立的矩阵,需要用clone()或者copyTo()。

如何创建Mat:

在这里插入图片描述
以上是Mat的全部构造函数。
下面举例说明如何创建Mat(并不全是利用构造函数)。

1.Mat (int rows, int cols, int type, const Scalar &s)

Mat M(2,3,CV_8UC3,Scalar(0,0,255));//8UC3即表示 8位无符号整数,且通道数为3

2.Mat (int ndims, const int *sizes, int type, const Scalar &s)

int sz[3] = {2,2,2};
Mat M(3,sz,CV_8U,Scalar::all(0))

3.create()
在查阅官方文档时发现了一个很有意思的例子。我将它与函数介绍一并放上来。
官方文档:
create()
Allocates new array data if needed.
This is one of the key Mat methods. Most new-style OpenCV functions and methods that produce arrays call this method for each output array. The method uses the following algorithm:
1.If the current array shape and the type match the new ones, return immediately. Otherwise, de-reference the previous data by calling Mat::release.
2.Initialize the new header.
3.Allocate the new data of total()*elemSize() bytes.
4.Allocate the new, associated with the data, reference counter and set it to 1.
Such a scheme makes the memory management robust and efficient at the same time and helps avoid extra typing for you. This means that usually there is no need to explicitly allocate output arrays. That is, instead of writing:

Mat color;
...
Mat gray(color.rows, color.cols, color.depth());
cvtColor(color, gray, COLOR_BGR2GRAY);

you can simply write:

Mat color;
...
Mat gray;
cvtColor(color, gray, COLOR_BGR2GRAY);

再借鉴https://blog.csdn.net/maweifei/article/details/72773274的文章(如介意联系删除)
cv::Mat::create()函数的作用为创建一个指定大小Size,指定类型type的图像矩阵的矩阵体
4.采用Matlab形式初始化方式

Mat A = Mat::eye(4, 4, CV_64F);
Mat B = Mat::ones(2, 2, CV_32F);
Mat C = Mat::zeros(3, 3, CV_8UC1);
Mat D = Mat::eye(4, 4, CV_8UC3);
Mat E = Mat::eye(3, 4, CV_8U);
cout << D << endl;
cout << E << endl;

在这里插入图片描述
5.为已存在的对象创建新信息头

Mat A = C.row(1).clone();

此外,在Mat输出时,可以指定多种风格输出。
如Numpy风格、Python风格等。
例如:

Mat E = Mat::eye(4, 4, CV_8U);
cout << format(E, Formatter::FMT_PYTHON);
1.2 点
//首先,Point_<int>,Point2i,Point等价,Point_<float>,Point2f等价。
Point p1;
p1.x = 10;
p1.y = 20;

Point p2 = Point(10,20);

Point2f p3(6,2);

Point3f p4(1,2,3);

vector<float> v1;
v1.push_back(1);
v1.push_back(2);
v1.push_back(3);

cout<<p1<<endl;
cout<<p2<<endl;
cout<<p3<<endl;
cout<<p4<<endl;
cout<<Mat(v)<<endl;

在这里插入图片描述

1.3 颜色:Scalar

Scalar()表示具有4个元素的数组。若不写第四个参数,OpenCV会认为我们只想表示3个参数。
注意OpenCV的RGB顺序为BGR,即:
Scalar(a,b,c)中c表示红色分量,b表示绿色分量,a表示蓝色分量。

1.4 尺寸:Size

直接举例最为直接:

Size(5,5);//构造出的Size宽度和高度都为5,第一个参数为宽,第二个为高
1.5 矩形:Rect

有四个成员变量:x,y,height,width,分别表示矩形的宽和高和左上角点的坐标。(构造时的顺序就是这个)
此外,&可以求交集,|可以求并集。
矩形的创建和交并实例如下:

	Rect r1(10, 20, 10, 20);
	Rect r2(15, 20, 10, 20);
	Rect r3(100, 200, 10, 20);
	Rect r4 = r1 & r2;
	Rect r5 = r1 | r2;
	Rect r6 = r1 & r3;
	Rect r7 = r1 | r3;
	cout << r1 << endl << r2 << endl << r3 << endl << r4 << endl << r5 << endl << r6 << endl << r7 << endl;

在这里插入图片描述

参考文献:

  1. OpenCV官方文档:https://docs.opencv.org/4.x/
  2. 《OpenCV3编程入门》毛星云、冷雪飞等编著
  3. 《OpenCV4快速入门》冯振、郭延宁、吕跃勇著
  • 0
    点赞
  • 2
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值