【opencv】内存自动管理的解释说明

server/2024/9/25 5:26:30/

原文

Automatic Memory Management OpenCV handles all the memory automatically.

First of all, std::vector, cv::Mat, and other data structures used by the functions and methods have destructors that deallocate the underlying memory buffers when needed. This means that the destructors do not always deallocate the buffers as in case of Mat. They take into account possible data sharing. A destructor decrements the reference counter associated with the matrix data buffer. The buffer is deallocated if and only if the reference counter reaches zero, that is, when no other structures refer to the same buffer. Similarly, when a Mat instance is copied, no actual data is really copied. Instead, the reference counter is incremented to memorize that there is another owner of the same data. There is also the cv::Mat::clone method that creates a full copy of the matrix data. See the example below:

// create a big 8Mb matrix
Mat A(1000, 1000, CV_64F);
// create another header for the same matrix;
// this is an instant operation, regardless of the matrix size.
Mat B = A;
// create another header for the 3-rd row of A; no data is copied either
Mat C = B.row(3);
// now create a separate copy of the matrix
Mat D = B.clone();
// copy the 5-th row of B to C, that is, copy the 5-th row of A
// to the 3-rd row of A.
B.row(5).copyTo(C);
// now let A and D share the data; after that the modified version
// of A is still referenced by B and C.
A = D;
// now make B an empty matrix (which references no memory buffers),
// but the modified version of A will still be referenced by C,
// despite that C is just a single row of the original A
B.release();
// finally, make a full copy of C. As a result, the big modified
// matrix will be deallocated, since it is not referenced by anyone
C = C.clone();

你看到使用Mat和其他基本数据结构是很简单的。但是对于高层次的类或者是那些在设计时没有考虑到自动内存管理的用户自定义数据类型呢?对于这些情况,OpenCV 提供了 cv::Ptr 模板类,它类似于 C++11 中的 std::shared_ptr。因此,你可以不用普通的指针,而是使用 cv::Ptr

T* ptr = new T(...);

你会看见:

Ptr<T> ptr(new T(...));

或者:

Ptr<T> ptr = makePtr<T>(...);

Ptr<T> 封装了一个指向类型 T 实例的指针以及一个与该指针关联的引用计数。有关详细信息,请参阅 cv::Ptr 的描述。

说明

自动内存管理

在OpenCV中,像std::vectorcv::Mat这样的数据结构,其内部实现会自动管理内存。这意味着当这些对象不再被使用时,它们会自动释放所占用的内存。具体来说,这些数据结构实现了智能引用计数机制。

引用计数机制
  • 共享内存:当一个cv::Mat对象被创建时,它会拥有一个内存缓冲区。如果另一个cv::Mat对象指向同一块内存,那么这块内存的引用计数就会增加。这意味着没有实际的数据复制发生,只有引用计数的增加。

  • 释放内存:当一个cv::Mat对象被销毁时,其内部的析构函数会减少这块内存的引用计数。只有当引用计数降到零时,这块内存才会被释放。

示例代码解释

让我们来看一下给定的代码示例:

  1. Mat A(1000, 1000, CV_64F);

    • 创建了一个大小为1000x1000的双精度浮点数矩阵A
  2. Mat B = A;

    • 创建一个新的Mat对象B,它指向与A相同的内存缓冲区。此时引用计数增加到2。
  3. Mat C = B.row(3);

    • C是一个指向B第三行的新Mat对象。这里C并不是一个完整的矩阵,而是一个视图(view)。
  4. Mat D = B.clone();

    • D是一个B的完整副本。这意味着D拥有自己的内存缓冲区,与AB不共享内存。
  5. B.row(5).copyTo(C);

    • B的第五行复制到C中,即修改了A的第三行。
  6. A = D;

    • 此时A指向了D的内存缓冲区,AD现在共享同一个内存。
  7. B.release();

    • B释放其对内存的引用,引用计数减1。但由于C仍然指向A的一部分,所以内存不会被释放。
  8. C = C.clone();

    • C创建了自己的内存副本,因此原来的内存不再被任何对象引用,最终会被释放。

使用cv::Ptr管理内存

除了基本数据结构之外,对于用户定义的数据类型或高级类,OpenCV提供了cv::Ptr模板类来帮助管理内存。cv::Ptr类似于C++11中的std::shared_ptr,它封装了一个指针和一个引用计数。这样,当最后一个指向某个对象的cv::Ptr实例被销毁时,对象本身也会被自动删除。

例如,可以使用cv::Ptr来替代原始指针:

1Ptr<T> ptr(new T(...));

或者使用makePtr<T>工厂函数:

1Ptr<T> ptr = makePtr<T>(...);

这种方式使得内存管理更加安全且易于维护。


http://www.ppmy.cn/server/115283.html

相关文章

如何通过食堂采购小程序端降低成本,提升效率?

随着数字化管理工具的普及&#xff0c;越来越多的食堂正在引入小程序来优化采购流程&#xff0c;减少成本和提升效率。食堂采购小程序端通过技术手段实现了自动化、智能化的管理方式&#xff0c;为管理者提供了极大的便利。本文将探讨如何利用技术手段开发一个高效的食堂采购小…

MATLAB求解0-1线性规划问题的详细分析

引言 0-1线性规划是整数规划中的一种特殊形式&#xff0c;它广泛应用于资源分配、工厂选址、投资组合优化、物流运输等多个领域。0-1线性规划的特点是&#xff0c;决策变量只能取0或1的离散值&#xff0c;通常用于描述“是-否”决策问题。随着计算机技术的发展&#xff0c;数学…

【python计算机视觉编程——8.图像内容分类】

python计算机视觉编程——8.图像内容分类 8.图像内容分类8.1 K邻近分类法&#xff08;KNN&#xff09;8.1.1 一个简单的二维示例8.1.2 用稠密SIFT作为图像特征8.1.3 图像分类:手势识别 8.2贝叶斯分类器用PCA降维 8.3 支持向量机8.3.2 再论手势识别 8.4 光学字符识别8.4.2 选取特…

嵌入式系统------ARM

目录 一.c语言回顾 1.特殊符号 &#xff08;1&#xff09;const &#xff08;2&#xff09;static &#xff08;3&#xff09;extern 2.内存的结构 &#xff08;1&#xff09;kernel&#xff1a;内核 &#xff08;2&#xff09;栈区 &#xff08;3&#xff09;堆区 &#xff08…

【PPT学习笔记】使用PPT制作动画/手书/视频等作品的适配性和可能性?

【PPT学习笔记】使用PPT制作动画/手书等作品的可能性&#xff1f; 背景前摇&#xff1a;&#xff08;省流可不看&#xff09; 最近找到另外一份新的实习工作&#xff0c;有很多需要用到PPT动画的地方。 然而&#xff0c;我们之前制作的理工科PPT全是摒弃了形式主义的艰苦朴素…

给自己复盘用的随想录笔记-栈与队列

用栈实现队列 难在出去 232. 用栈实现队列 - 力扣&#xff08;LeetCode&#xff09; class MyQueue {private Stack<Integer> A;private Stack<Integer> B;public MyQueue() {Anew Stack<>();Bnew Stack<>();}public void push(int x) {A.push(x);}pu…

coding云原生构建实现自动化部署(前端代码v3+vite)

使用Coding CI/CD 在现代软件开发中&#xff0c;自动化部署是提高效率和降低出错率的关键步骤。本文将详细介绍如何使用 coding-ci.yml 文件配置 CI/CD 流程&#xff0c;实现一个自动化的部署过程。我们将以一个简单的项目为例&#xff0c;讲解如何利用 Coding CI/CD 工具自动…

solidity学习-15异常

异常 异常的作用&#xff1a;用于程序debug 主要有三种抛出异常的方法&#xff1a; error require assert本章的学习目的&#xff1a; 1了解三种异常的使用。 2区分三种异常的gas fee消耗 手写代码如下 // SPDX-License-Identifier: MIT pragma solidity ^0.8.21;// 定义一个…