对cv::Mat进行容器push_back的理解

2024-05-25 23:58
文章标签 进行 cv 理解 push 容器 back mat

本文主要是介绍对cv::Mat进行容器push_back的理解,希望对大家解决编程问题提供一定的参考价值,需要的开发者们随着小编来一起学习吧!

总所周知,cv::Mat 有两种拷贝方式,深拷贝和浅拷贝。直接a=b是浅拷贝,靠.clone()和copyTo()实现深拷贝。

容器的push_back是拷贝。

那么当我们push_back(cv::Mat)时,是深拷贝还是浅拷贝呢?

可以做一个实验,定义一个全局变量cv::Mat a , 全局变量vector<cv::Mat> buf;

不停更新a的值,发现buf里面都是最新的a的值。说明什么呢?说明**在push_bac Mat时是浅拷贝**

但是如果a是一个局部变量,则buf就是对的。这是由于cv::Mat的释放机制。

cv::Mat类似于智能指针的原理,有一个引用机制,有一个成员变量refcount,会自己根据被引用和释放的次数,自动管理内存。

push_back(cv::Mat) 浅拷贝,分配信息头,共享数据区,refcount++, 这时候局部变量a释放,只是清除本身的信息头和置零数据区指针,refcount--,由于refcount还不为零,共享数据区还不会被清空。

我认为如果生成cv::Mat容器,用局部变量来push_back是非常好的一种方式,即可以完成任务,又不耗时(clone耗时耗资源)。关键是能理解这种引用机制,只有一个引用没释放,这片内存就不会被释放!

需要注意的地方!!!

通过驱动(一般c语言编写)读取图片,一般是通过定义一个cv::Mat,其地址指向内存

cv::Mat gray(400, 640, CV_8UC1, buf->planes[0].start);
camera_put_image(handle, buf); //buf被释放了,即gray对应的内存被释放了

然后我们把gray可以浅拷贝给其他变量,push给buff之类的。按照cv::mat的内存管理机制,这里应该是没有什么问题的,前提啊,前提是buf->planes[0]不能释放,如果释放了,也就是所有cv::mat指向的那边内存被释放,一旦这片内存被使用,就会报错。

如果内存被释放,就不得不通过clone的方式给cv::mat重新申请一片内存。

因此我们一定要溯源,第一个mat的内存是什么样子的。可以用

cout << "img ptr" << gray.ptr<float>() << endl;

把mat对应的地址打出来看,我不知道为什么使用ptr<float>()才可以把地址打印出来。用uchar uint8都是乱码的。uint32_t是可以的。

这篇关于对cv::Mat进行容器push_back的理解的文章就介绍到这儿,希望我们推荐的文章对编程师们有所帮助!



http://www.chinasem.cn/article/1002981

相关文章

详解C++ 存储二进制数据容器的几种方法

《详解C++存储二进制数据容器的几种方法》本文主要介绍了详解C++存储二进制数据容器,包括std::vector、std::array、std::string、std::bitset和std::ve... 目录1.std::vector<uint8_t>(最常用)特点:适用场景:示例:2.std::arra

python项目打包成docker容器镜像的两种方法实现

《python项目打包成docker容器镜像的两种方法实现》本文介绍两种将Python项目打包为Docker镜像的方法,文中通过示例代码介绍的非常详细,对大家的学习或者工作具有一定的参考学习价值,需要... 目录简单版:(一次成功,后续下载对应的软件依赖)第一步:肯定是构建dockerfile,如下:第二步

JAVA SpringBoot集成Jasypt进行加密、解密的详细过程

《JAVASpringBoot集成Jasypt进行加密、解密的详细过程》文章详细介绍了如何在SpringBoot项目中集成Jasypt进行加密和解密,包括Jasypt简介、如何添加依赖、配置加密密钥... 目录Java (SpringBoot) 集成 Jasypt 进行加密、解密 - 详细教程一、Jasyp

linux实现对.jar文件的配置文件进行修改

《linux实现对.jar文件的配置文件进行修改》文章讲述了如何使用Linux系统修改.jar文件的配置文件,包括进入文件夹、编辑文件、保存并退出编辑器,以及重新启动项目... 目录linux对.jar文件的配置文件进行修改第一步第二步 第三步第四步总结linux对.jar文件的配置文件进行修改第一步进

GO语言zap日志库理解和使用方法示例

《GO语言zap日志库理解和使用方法示例》Zap是一个高性能、结构化日志库,专为Go语言设计,它由Uber开源,并且在Go社区中非常受欢迎,:本文主要介绍GO语言zap日志库理解和使用方法的相关资... 目录1. zap日志库介绍2.安装zap库3.配置日志记录器3.1 Logger3.2 Sugared

Go语言中如何进行数据库查询操作

《Go语言中如何进行数据库查询操作》在Go语言中,与数据库交互通常通过使用数据库驱动来实现,Go语言支持多种数据库,如MySQL、PostgreSQL、SQLite等,每种数据库都有其对应的官方或第三... 查询函数QueryRow和Query详细对比特性QueryRowQuery返回值数量1个:*sql

深入理解Redis线程模型的原理及使用

《深入理解Redis线程模型的原理及使用》Redis的线程模型整体还是多线程的,只是后台执行指令的核心线程是单线程的,整个线程模型可以理解为还是以单线程为主,基于这种单线程为主的线程模型,不同客户端的... 目录1 Redis是单线程www.chinasem.cn还是多线程2 Redis如何保证指令原子性2.

深入理解MySQL流模式

《深入理解MySQL流模式》MySQL的Binlog流模式是一种实时读取二进制日志的技术,允许下游系统几乎无延迟地获取数据库变更事件,适用于需要极低延迟复制的场景,感兴趣的可以了解一下... 目录核心概念一句话总结1. 背景知识:什么是 Binlog?2. 传统方式 vs. 流模式传统文件方式 (非流式)流

深入理解Go之==的使用

《深入理解Go之==的使用》本文主要介绍了深入理解Go之==的使用,文中通过示例代码介绍的非常详细,对大家的学习或者工作具有一定的参考学习价值,需要的朋友们下面随着小编来一起学习学习吧... 目录概述类型基本类型复合类型引用类型接口类型使用type定义的类型不可比较性谈谈map总结概述相信==判等操作,大

深入理解Mysql OnlineDDL的算法

《深入理解MysqlOnlineDDL的算法》本文主要介绍了讲解MysqlOnlineDDL的算法,文中通过示例代码介绍的非常详细,对大家的学习或者工作具有一定的参考学习价值,需要的朋友们下面随着小... 目录一、Online DDL 是什么?二、Online DDL 的三种主要算法2.1COPY(复制法)