概述
【OpenCV学习笔记】数据结构
- 像素值的存储方法
- 显示创建Mat对象
- Mat对象组成结构
- OpenCV的格式化输出
- 一些类的关键字
- 其他常用知识点
本笔记来源于《OpenCV3编程入门》 毛星云等著
像素值的存储方法
RGB是最常见的颜色系统,它与人眼采用相似的工作机制,被显示设备所采用。
OpenCV中RGB和BGR有所区别。其中后者是OpenCV默认通道储存顺序。
HSV和HLS把颜色分解成色调、饱和度和亮度/名都。这是描述颜色更自然的方式。可以通过抛弃最后一个元素,使算法对输入图像的光照条件不敏感。
YCrCb在JPEG图像格式中被广泛使用
显示创建Mat对象
最常用的方法就是直接使用Mat()构造函数
如:
Mat M(2,2, CV_8UC3 ,Scalar(0,0,255));
CV_8UC3 和 Scalar(0,0,255)各代表什么?
对于二维多通道图像,首先要定义其尺寸,即行数和列数,然后,需要制定存储元素的数据类型以机每个矩阵点的通道数。为此,依据下面的规则有多种定义:
CV_[位数][带符号与否][类型前缀]C[通道数]
由此可以知道
CV_8UC3代表的是: 使用8位的unsigned char型,每个像素由三个元素组成三通道(预先定义的通道数可达4个)。
Scalar是个short型的向量,能够使用制定的定制化值来初始化矩阵,还可以用来表示颜色
如何创建三维矩阵?
/*-------------朱砂青瓦 创建三维矩阵--------------*/
int sz[3]={2,2,2};
Mat L(3,sz,CV_8UC,scalar::all(0));
第一个参数指定维数,然后传递一个指向一个数组的指针,包含每个维度的尺寸。
另外可以使用Mat类自带的Create()函数来初始化Mat类
/*-------------朱砂青瓦 Creat()初始化Mat--------------*/
mat.create(4,4,CV_8UC(2));
cout << "M = " << endl << " " << M << endl << endl;
但是这种方法并不能够位矩阵设定初始值,只能够开辟内存
Matlab式方法初始化
/*-------------朱砂青瓦 Matlab式初始化Mat--------------*/
//对角矩阵
Mat E = Mat::eye(4,4,CV_64F);
//1矩阵
Mat O = Mat::ones(2,2,CV_32F);
//0矩阵
Mat Z = Mat::zeros(3,3,cv_8UC1);
Mat对象组成结构
Mat是OpenCV储存图像的类,由两个数据部分组成:
- 矩阵头(包含矩阵尺寸、存储方法、存储地址等信息)类似段表
- 一个指向存储所有像素值的矩阵
矩阵头的尺寸是常数值,但矩阵本身的尺寸会依图像的不同而不同,通常比矩阵头的尺寸大数个数量级。
但是为了解决问题通常要使用库中的多个函数,因此在函数中传递图像是常有的事。
为了解决这个问题,OpenCV使用了计数机制。思路是让每个Mat对象由自己的信息头,但共享同一个矩阵。
也就是说,每个Mat对象的实例只是信息头有所区别,但是他们使用的矩阵都是一个。
因此,通过赋值运算符"="和拷贝构造函数(构造函数)只复制信息头。比如Mat B = A、Mat C(A)
A、B、C使用的是同一个矩阵。三者中只要有一个对象做出改变,其他两个也会被影响
当Mat对象被复制一次,计数就会+1.当一个头被释放,计数就会-1.当计数值为0,矩阵就会被清理。(感觉类似操作系统中的信号量)
那么如何复制矩阵本身?
答:使用clone()和copyTo()函数
例:
/*-------------朱砂青瓦 复制矩阵--------------*/
Mat D = A.clone();
Mat F;
A.copyTo(F);
这样,改变D或F就不会影响到A了。
OpenCV的格式化输出
randu()函数产生随机值来填充矩阵
/*-------------朱砂青瓦 复制矩阵--------------*/
Mat r = Mat(10, 3, CV_8UC3);
randu(r, Scalar::all(0), Scalar::all(255));
其中第一个参数是Mat类,后面两个参数指定了生成的随机数的上限和下限
/*-------------朱砂青瓦 格式化输出Mat--------------*/
Mat r = Mat(10, 3, CV_8UC3);
randu(r, Scalar::all(0), Scalar::all(255));
//默认风格
cout << "r (默认)=" << r << ";" << endl << endl;
//Python风格
cout << "r (Python)" << format(r, Formatter::FMT_PYTHON) << ";" << endl << endl;
//逗号分隔风格
cout << "r (逗号分隔风格)" << format(r, Formatter::FMT_CSV) << ";" << endl << endl;
//Numpy风格
cout << "r (Numpy)" << format(r, Formatter::FMT_NUMPY) << ";" << endl << endl;
//C语言风格
cout << "r (C)" << format(r, Formatter::FMT_C) << ";" << endl << endl;
结果显示如下:
一些类的关键字
Point类
Point_<int> 、Point2i、Point互相等价(Point类默认为int)
Point_<float>、Point2f互相等价
Scalar类
Scalar表示具有4个元素的数组。如果用不到第四个参数,就不用写出来。
Scalar(a,b,c)
那么定义的RGB颜色值:红色为c,绿色为b,蓝色为1
注意:默认通道储存顺序:BGR
Size类
Size_<int> 、Size2i、Size互相等价(Size类默认为int)
一般为2维。Size(2,3)表示宽度为2,高度为3.
Rect类
Rect类成员变量有x、y、width、height
常用成员函数有:
- Size()返回Size
- area()返回面积
- contains(Point)判断点是否在矩形内
- inside(Rect)判断矩形是否在该矩形内
- tl()返回左上角点坐标(topleft),br()返回右下角点坐标(bottomright)
求交集和并集:
Rect rect = rect1 & rect2;
Rect rect = rect1 | rect2;
平移和缩放操作:
Rect rectShift = rect + point;
Rect rectScale = rect + size;
小结
OpenCV中变量一般是[变量名]_<变量类型> 、 [变量名][维数][变量类型]
其他常用知识点
- Matx是个轻量级的mat,必须在使用前规定好大小。比如2*3的float型的Matx,可以声明为Matx23f
- Vec是Matx的一个派生类,是一个一维的Matx,和vector相似。
- Rnage类其实就是为了使OpenCV的使用更像Matlab而产生的。Range(a,b)其实就是Matlab中的a:b,a和b都应为整型。
- OpenCV中防止内存溢出的函数有:alignPtr、alignSize、allocate、deallocate、fastMalloc、fastFree
- <math.h>中一些函数使用起来很方便如:计算向量角度的函数fastAtan2、计算立方根函数cubeRoot、向上取整函数cvCeil、向下取整函数cvFloor、四舍五入函数cvRound等。另外比如判断变量是否无穷大cvIsInf、判断自变量是否不是一个数cvIsNaN
- 显示文字相关:getTextSize、cvInitFont、putText
- 作图相关:circle、clipLine、ellipse、ellipse2Poly、line、rectangle、polylines、类LineIterator
- 填充相关函数:fillConvexPoly、fillPoly
- OpenCV中RNG()函数的作用为初始化随机数状态的生成器。
最后
以上就是冷傲过客为你收集整理的【OpenCV学习笔记】1-Mat数据结构的全部内容,希望文章能够帮你解决【OpenCV学习笔记】1-Mat数据结构所遇到的程序开发问题。
如果觉得靠谱客网站的内容还不错,欢迎将靠谱客网站推荐给程序员好友。
发表评论 取消回复