对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是可以的。

  • 1
    点赞
  • 4
    收藏
    觉得还不错? 一键收藏
  • 2
    评论
评论 2
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值