opencv学习笔记(2) :Mat对象

一、概念:

Mat类是opencv中用来存储图像的类。

Mat类由矩阵头(包含矩阵尺寸、存储方法、存储地址等信息)一个指向存储所有像素值矩阵(根据所选存储方法的不同,矩阵可以是不同的维数)的指针。矩阵头的尺寸是常数值,但矩阵本身的尺寸会因图像的不同而不同,通常比矩阵头的尺寸大好几个数量级。因此,当在程序中传递图像并创建副本时,大的开销是由矩阵造成的,而不是矩阵头。OpenCV是一个图像处理库,其中包含大量的图像处理函数。为了解决问题,通常要使用库中的多个函数,因此经常需要在函数中传递图像。同时,对于那些计算量很大的图像处理算法,除非万不得已,否则不应该复制“大”图像,因为这会降低程序运行速度。

为了解决这个问题,OpenCV使用引用计数机制,其思路是让每个Mat对象有自己的矩阵头,但共享同一个矩阵(通过让矩阵指针指向同一地址来实现)。当使用复制构造函数(又称拷贝构造函数)时,只需复制矩阵头和矩阵指针即可,而不用复制矩阵本身。

如果矩阵属于多个Mat对象,那么当不再需要它时谁来负责清理?简单的回答是最后一个使用它的对象。清理工作可以通过引用计数机制来实现。无论用户什么时候复制一个Mat对象的矩阵头,都会增加矩阵的引用次数;反之,当一个矩阵头被释放之后,这个计数被减1;当计数值为0,矩阵就会被清理。但在某些时候确实需要完全复制矩阵本身(不只是矩阵头和矩阵指针),这时可以使用函数clone()或者copyTo()实现深复制。

总结:

①OpenCV函数中输出图像的内存分配是自动完成的(如果不特别指定的话)。

②使用OpenCV的Mat类时不需要考虑内存释放问题。

③赋值运算符和复制构造函数只复制矩阵头。

④函数clone()或者copyTo()可用来复制表示图像的矩阵。

Mat类的构造函数:

  1. Mat(int rows,int cols,int type)(常用)
  2. Mat(Size size,int type)(常用)
  3. Mat(int rows,int cols,int type,const Scalar &s)
  4. Mat(Size size,int type,const Scalar &s)
  5. Mat(int ndims,const int* sizes,int type)
  6. Mat(int ndims,const int* sizes,int type,const Scalar &s)

二、示例代码:

#include <iostream>

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

using namespace cv;
using namespace std;


void test01()
{
    // 1.使用Mat()创建Mat对象
    //   创建一个类型为8位uchar,颜色为三通道黄色的2*2的Mat对象
    Mat image(2,2,CV_8UC3,Scalar(0,255,255));
    cout<<"矩阵元素"<<endl<<image<<endl;
    //   将图像保存
    if(imwrite("D:/test.jpg",image))
    {
        cout<<"图片保存成功!"<<endl;
    }
    else
    {
        cout<<"图片保存失败!"<<endl;
    }

    // 2.创建一个超二维的矩阵
    int sz[3]={2,2,2};
    Mat image2(3,sz,CV_8UC1,Scalar(0));

    // 3.使用create()函数创建Mat对象
    Mat img;
    img.create(4,4,CV_8UC(2));
    cout<<"img = "<<endl<<img<<endl;
}

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值