今天在写代码的时候遇到这样一个问题

先来看个函数,这是一段更新subShape的函数:

void updateSubShape()
{double sub_shape_01_brow_left_data[10] = {mShape.part(17).x(),mShape.part(17).y(),mShape.part(18).x(),mShape.part(18).y(),mShape.part(19).x(),mShape.part(19).y(),mShape.part(20).x(),mShape.part(20).y(),mShape.part(21).x(),mShape.part(21).y()};sub_shape_01_brow_left = cv::Mat(5, 2, CV_64FC1, sub_shape_01_brow_left_data);double sub_shape_02_brow_right_data[10] = {mShape.part(22).x(),mShape.part(22).y(),mShape.part(23).x(),mShape.part(23).y(),mShape.part(24).x(),mShape.part(24).y(),mShape.part(25).x(),mShape.part(25).y(),mShape.part(26).x(),mShape.part(26).y()};sub_shape_02_brow_right = cv::Mat(5, 2, CV_64FC1, sub_shape_02_brow_right_data);double sub_shape_03_eye_left_data[12] = {mShape.part(36).x(),mShape.part(36).y(),mShape.part(37).x(),mShape.part(37).y(),mShape.part(38).x(),mShape.part(38).y(),mShape.part(39).x(),mShape.part(39).y(),mShape.part(40).x(),mShape.part(40).y(),mShape.part(41).x(),mShape.part(41).y()};sub_shape_03_eye_left = cv::Mat(6, 2, CV_64FC1, sub_shape_03_eye_left_data);double sub_shape_04_eye_right_data[12] = {mShape.part(42).x(),mShape.part(42).y(),mShape.part(43).x(),mShape.part(43).y(),mShape.part(44).x(),mShape.part(44).y(),mShape.part(45).x(),mShape.part(45).y(),mShape.part(46).x(),mShape.part(46).y(),mShape.part(47).x(),mShape.part(47).y()};......sub_shape_04_eye_right = cv::Mat(6, 2, CV_64FC1, sub_shape_04_eye_right_data);std::cout << "sub_shape_01_brow_left:" << sub_shape_01_brow_left << std::endl;std::cout << "sub_shape_02_brow_right:" << sub_shape_02_brow_right << std::endl;std::cout << "sub_shape_03_eye_left:" << sub_shape_03_eye_left << std::endl;std::cout << "sub_shape_04_eye_right:" << sub_shape_04_eye_right << std::endl;......
}

笔者在当前函数内打印出01,02,03,04四个Mat的信息如下:

sub_shape_01_brow_left:

[77, 83;
 83, 78;
 92, 77;
 100, 79;
 107, 84]
sub_shape_02_brow_right:

[122, 86;
 131, 84;
 141, 85;
 150, 90;
 156, 97]
sub_shape_03_eye_left:

[85, 96;
 90, 95;
 96, 96;
 101, 99;
 95, 100;
 90, 99]
sub_shape_04_eye_right:

[128, 103;
 134, 102;
 139, 103;
 145, 106;
 139, 106;
 133, 106]

然而神奇的一幕来啦,当笔者在另外一个函数中调用上述函数,打印出01,02,03,04四个Mat的信息如下:

sub_shape_01_brow_left:

[77, 83;
 83, 78;
 92, 77;
 100, 79;
 107, 84]
sub_shape_02_brow_right:

[122, 86;
 131, 84;
 141, 85;
 150, 90;
 156, 97]
sub_shape_03_eye_left:

[85, 96;
 1.197398590121304e-47, 95;
 6.952696120312864e-310, 6.952696120312864e-310;
 6.444060669718295e-316, 1.427990031124621e-316;
 6.952696120331045e-310, 4.940656458412465e-324;
 3.458459520888726e-323, 6.937713299605351e-310]
sub_shape_04_eye_right:

[128.0001200092957, 6.444533391728236e-316;
 6.444533391728236e-316, 6.444533391728236e-316;
 6.444533391728236e-316, 6.444533638761059e-316;
 6.444533737574188e-316, 6.444533391728236e-316;
 6.444533737574188e-316, 0;
 0, 0]

发现竟然01,02指向的Mat数据正确,03,04指向的数据就完全错了,这是神马情况。然而在cv::Mat(xxx)后添加.clone()后就可以解决上述问题。

原来Mat有浅拷贝和深拷贝的区分,cv::Mat C(xxx)只是一个浅拷贝的状况,浅拷贝后的变量指针都会与Mat指向同一个内存地址,在上述函数中笔者使用了大量的cv::Mat(xxx)进行浅拷贝,笔者猜测应当是opencv在函数操作中对Mat的内存分配是存在一定限制的,由于笔者使用的cv::Mat(xxx)过多,已经超出了opencv的限制,因此在函数结束后,部分内存被自动释放,所以导致了上述这个问题。而采用clone的深拷贝的方式,会完整的为变量字段开辟一个属于自己的内存空间,函数结束后,内存不能被自动释放,所以不会出现上述问题。

由此可见,使用opencv的Mat,一定要深入理解浅拷贝和深拷贝的含义啊,clone也对于Mat变得无比重要。

【Opencv-Ubuntu】论clone对Mat的重要性相关推荐

  1. OpenCV源码解读:Mat与GpuMat的内存拷贝(copyTo和clone)

    前言 OpenCV基础类型Mat以及GPU上的GpuMat是整个OpenCV工程体系中两种非常基础常用的类型.通常情况下Mat拥有的方法,GpuMat都会有对应的方法.对于内存拷贝,有两个常用的方法c ...

  2. 学习OpenCV(一)从Mat讲起

    本博客所用OpenCV版本为2.4.3,运行环境为Visual Studio2012. 学习OpenCV是一个比较漫长的过程,希望我能够坚持! (一)从Mat讲起 Mat是OpenCV中用于存放图像的 ...

  3. vs code linux opencv,ubuntu+vscode 测试运行opencv

    ubuntu+vscode 测试运行opencv ubuntu+vscode 测试运行opencv 之前再ubuntu配置好了opencv,今天测试运行一下. 1.创建一个文件夹opencv+test ...

  4. 【OpenCV】看看clone和copyTo的源码

    结论: clone代码: mat.inl.hpp 直接调用了copyTo函数,新建了一个临时变量m,返回赋值(地址的头+尺寸)给开发者定义的变量 inline Mat Mat::clone() con ...

  5. 【OpenCv】c++ 入门认识 Mat 类,单通道 Mat 的基本操作

    文章目录 前言 Mat 类 Mat 类的构造方式 Mat 基本操作 单通道 Mat 的基本操作 使用成员变量 rows 和 cols 获取矩阵的行数和列数 使用成员函数 size() 来获取矩阵的尺寸 ...

  6. 【opencv4】opencv教程 C++ 4、Mat对象(深拷贝:clone()、copyTo(),create()创建图片,zeros()、eye()初始化空白图像,Scalar()创建向量)

    上一讲:[opencv4]opencv视频教程 C++(opencv教程)3.矩阵的掩膜操作(filter2D) 下一讲:[opencv4]opencv视频教程 C++ 5.读写图像imread.im ...

  7. OpenCV 笔记(06)— Mat 结构、像素值存储方法、创建 Mat 对象各种方法、Mat 对象的运算

    数字图像中的每个点都称为像素(对于图像元素),并且每个像素可以存储一个或多个值,这取决于它是否是仅存储一个值的黑白图像(也称为二进制图像,比如只存储0或1),还是存储两个值的灰度图像,或者是存储三个值 ...

  8. OpenCV【零】—————cv::Mat——Mat对象创建方法

    OpenCV (一)--Mat对象创建方法 目录 OpenCV (一)--Mat对象创建方法 1. cv::Mat优点及原理(本质类) 2. Mat类拷贝及对象的创建方法 3. Mat 对象元素的高效 ...

  9. 【OpenCV】OpenCV函数精讲之 -- Mat和IplImage之间的相互装换(OpenCV2.0和OpenCV3.0)

    Mat是OpenCV和C++接口的矩阵类,IplImage是OpenCV和C语言接口的结构体. Mat读取显示用的是imread.imshow等,IplImage读取显示用的是cvLoadImage( ...

最新文章

  1. centos yum mysql-devel 5.5_CentOS 6.5下yum安装 MySQL-5.5全过程图文教程
  2. Java finally语句到底是在return之前还是之后执行?
  3. Comparable和Comparator的比较
  4. mutt msmtp
  5. 改造微服务注册到eureka注册中心
  6. mysql按中文拼音字母排序_解析MySQL按常规排序、自定义排序和按中文拼音字母排序的方法...
  7. 爬虫5-BeautifulSoup模块简解
  8. eclipse linux 代码提示,Linux Eclipse代码提示功能设置(Java C/C++)
  9. 如何在 Deno 中构建一个 URL 短链生成器
  10. Momenta 陈凯:从人才角度看 L4 无人驾驶的实现 | AI 研习社职播间第 4 期(附 Momenta 招聘解读)...
  11. linux go 连接oracle,Ubuntu14下golang连接oracle11g (OCI12.1方式)
  12. cpu上干硅脂怎么清理_cpu导热硅脂如何涂抹,涂抹的时候需要注意哪些事项
  13. 算法7-16:弗洛伊德最短路径算法
  14. 《深入浅出MFC》系列之消息映射(一)
  15. arm板配置ssh服务
  16. python爬虫大作业
  17. 学而思pythonlevel3_【学而思网校语言学习】学而思网校【2019-寒】AE英语直播班 Level 3上【报价 价格 评测 怎么样】 -什么值得买...
  18. keras深度学习(3)-单标签多分类问题之新闻分类
  19. JAVA生成热点图,JAVA 后端生成热力图图片返回
  20. 南大人工智能AI学院夏令营面试经历

热门文章

  1. 图片插值数据_结合PS用这招来增强ArcGIS插值图出图效果
  2. 个人作业Alpha项目测试
  3. Xcode9 之 Xcode Server 持续集成
  4. Android Status(状态栏) 着色
  5. 实战Jquery(一)--username校验
  6. python中pop(),popitem()的整理
  7. 【MySQL】性能优化之 straight_join
  8. [转]如何写出不可维护的服务端程序
  9. Android NFC读取电子标签
  10. html对字符串判空,使用XslCompiledTransform获取html作为字符串。结果为空