OpenCV入门教程(6)-Mat类之内存管理和输出

1 Mat 类的内存管理

使用 Mat 类,内存管理变得简单,不再像使用 IplImage 那样需要自己申请和释放内存。虽然不了解 Mat 的内存管理机制,也无碍于 Mat 类的使用,但是如果清楚了解 Mat 的内存管理,会更清楚一些函数到底操作了哪些数据。
Mat 是一个类,由两个数据部分组成:矩阵头(包含矩阵尺寸,存储方法,存储地址等信息)和一个指向存储所有像素值的矩阵的指针,如下图所示。矩阵头的尺寸是常数值,但矩阵本身的尺寸会依图像的不同而不同,通常比矩阵头的尺寸大数个数量级。复制矩阵数据往往花费较多时间,因此除非有必要,不要复制大的矩阵。
为了解决矩阵数据的传递,OpenCV 使用了引用计数机制。其思路是让每个Mat 对象有自己的矩阵头信息,但多个 Mat 对象可以共享同一个矩阵数据。让矩阵指针指向同一地址而实现这一目的。很多函数以及很多操作(如函数参数传值)只复制矩阵头信息,而不复制矩阵数据。
前面提到过,有很多中方法创建 Mat 类。如果 Mat 类自己申请数据空间,那么该类会多申请 4 个字节,多出的 4 个字节存储数据被引用的次数。引用次数存储于数据空间的后面,refcount 指向这个位置,如下图所示。当计数等于 0 时,则释放该空间。
这里写图片描述
关于多个矩阵对象共享同一矩阵数据,我们可以看这个例子:

Mat A(100,100, CV_8UC1);
Mat B = A;
Mat C = A(Rect(50,50,30,30));

上面代码中有三个 Mat 对象,分别是 A,B 和 C。这三者共有同一矩阵数据,其示意图如下图所示。
这里写图片描述
图 3个矩阵共用同一个矩阵数据
2 输出
从前面的文章中,可以看到 Mat 类重载了<<操作符,可以方便地使用流操作来输出矩阵的内容。默认情况下输出的格式是类似 Matlab 中矩阵的输出格式。除了默认格式,Mat 也支持其他的输出格式。代码如下:
首先创建一个矩阵,并用随机数填充。填充的范围由 randu()函数的第二个参数和第三个参数确定,下面代码是介于 0 到 255 之间。

Mat R = Mat(3, 2, CV_8UC3);
randu(R, Scalar::all(0), Scalar::all(255));

默认格式输出的代码如下:

cout << "R (default) = " << endl << R << endl << endl;

输出结果如图所示。
这里写图片描述
Python 格式输出的代码如下:

cout << "R (python) = " << endl << format(R,"python") << endl << endl;

这里写图片描述
以逗号分割的输出的代码如下:

cout << "R (csv) = " << endl << format(R,"csv") << endl << endl;

这里写图片描述
numpy 格式输出的代码如下:

cout << "R (numpy) = " << endl << format(R,"numpy" ) << endl << endl;

这里写图片描述
C 语言格式输出的代码如下:

cout << "R (c) = " <<endl << format(R,"C") << endl << endl;

这里写图片描述
除了 Mat 对象可以使用<<符号输出,其他的很多类型也支持<<输出。
二维点:

Point2f P(5, 1);
cout << "Point (2D) = " << P << endl << endl;

三维点:

Point3f P3f(2, 6, 7);
cout << "Point (3D) = " << P3f << endl << endl;
  • 3
    点赞
  • 4
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

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

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值