2.1 OpenCV 核心模块之Mat矩阵

  • Mat

OpenCV最开始是使用C语言中的结构体IplImage来存储图像的,但是它的缺点在于需要程序编写者来管理内存的分配与释放。它在小项目中问题不大,一旦有代码变多,处理起来就会变得十分棘手。幸运的是,C++引入了类,能够自动管理内存;并且,这个改变在C++和C之间并没有任何兼容性问题。因此,OpenCV2.0版本使用新的C++接口,来自动管理内存,让代码更为简洁。由于大部分嵌入式系统只支持C语言,因此除嵌入式系统之外,都没必要继续使用旧的方式了。

Mat类有两个数据部分:矩阵头文件(包含信息有矩阵的大小,存储格式,存储地址等)和指向存储像素值矩阵的指针。矩阵头文件的大小是确定的,但是矩阵的大小根据图像的变化而变化。

OpenCV是一个图像处理库,包含大量的图像处理函数。为了进行一次计算,大多数情况你需要用到库里的多个函数。因此,将图像传递到函数是基本操作。我们不应该忘记的是这些图像处理算法的计算量十分大。最后,由于大图像不必要的复制操作,会导致程序速度降低。

为处理上述情况,OpenCV使用参考计数系统,即每个Mat矩阵有自己的头文件,但是通过将矩阵指针指向同一地址,让两个实例共享同一基础矩阵。并且,复制操作只会复制头文件和让指针指向基础矩阵,而不会复制整个矩阵数据。

Mat A,C;    //只创建头文件
A= imread(argv[1], CV_LOAD_IMAGE_COLOR);    //分配矩阵空间
Mat B(A);    //进行复制操作
C = A;    //赋值操作

上述所有变量,都指向同一数据矩阵。虽然它们的头文件不同,但是对它们其中一个进行修改操作其他的都会改变。实际操作中,尽管它们的头文件不同,然而不同变量只是提供了对同一数据的不同访问路径而已。最有趣的是,你可以创建一个只指向一部分数据的头文件。例如,创建一副图像的感兴趣区域(ROI),用一个新的带有以下边界的头文件指向它:

Mat D (A, Rect(10, 10, 100, 100));    //使用矩形边界
Mat E = A(Range::all(), Range(1.3));    //使用行、列边界

现在,你可能会问由于矩阵属于多个Mat变量,当不需要它时,由谁负责清理它呢?简单来说是最后一个使用它的变量。这是由参考计数机制处理的:当有人复制Mat变量的头文件时,计数会自动为这个矩阵加1;当头文件每被清理一个时,计数会自动减1;当计数归零时,矩阵就会被清理。有时,可能会想要复制整个矩阵,所以OpenCV提供了clone()和copyTo()函数。

Mat F= A.clone();
Mat G;
A.copyTo(G);

现在,修改F和G不会影响其他指向A矩阵的变量。你需要记住以下几点:

1. OpenCV函数的输出图像是自动分配的(除特殊情况)

2. OpenCV的C++接口不需要考虑内存分配问题

3. 赋值操作和复制操作只复制头文件

4. 图像的基础矩阵的复制只能使用clone()函数和copyT0()函数

  • 1
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

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

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值