从2001年以来,opencv的函数库一直是基于C接口构建的,因此在opencv1.0版本中,一般使用IplImage的C结构体在内存中存储图像,因此,我们在很多较经典的书籍或者开源项目中依然可见IplImage。但是用其存储图像的时候必须在退出前将图像内存手动release掉,即添加语句cvReleaseImage(&IplImage);,否则会造成内存泄漏。Mat类带来了自动的内存管理,同时它的操作也更加简单,比如用imshow显示图像,imread读取图像等等,跟Matlab有点接近。下面是将图像容器类mat转化成IplImage结构体的一种方法,最后别忘了cvReleaseImage(&pImg)。

Mat frame,frame1;
IplImage* pImg;
frame=capture.read();
frame1=frame.clone();
pImg=cvCreateImage(cvSize(frame.cols,frame.rows),8,3);
pImg->imageData=(char*)frame1.data;...

Mat是一个类,它由两个数据部分组成:矩阵头和一个指向存储所有像素值的矩阵的指针。其中矩阵头包含了矩阵的尺寸、存储方法、储存地址等信息,由此可以看出矩阵头所占的内存很小,通常是一个常数值,而具体存储所有像素值的矩阵则非常大。因此,在程序中传递图像并创建副本时,大的开销是由矩阵造成的,而不是信息头。其实上面给的mat转IplImage结构体就是一个例子,显然复制图像会增加算法的复杂度,降低程序的性能。形象点说,在一个班级里,矩阵头就相当于存储了班级里有多少人、男女比多少、平均身高等信息,而矩阵就储存了班级中所有同学的所有基本信息,每一个同学就相当于是一个像素矩阵中的一个元素,那么根据不同的存储方法就得到了不同的元素表示方法,显然矩阵要比矩阵头复杂得多。

为了解决上述代码存在的问题。opencv使用了引用计数机制,其思路就是让每个Mat对象有自己的信息头,但是共享同一个矩阵。也就是让矩阵指针指向同一地址,共用一片内存来实现。复制图像的时候只是复制了矩阵头的信息和矩阵指针,并不是复制了整个矩阵。例如下面这段代码:

Mat A,C;//仅创建信息头部分
A= imread("1.jpg",CV_LOAD_IMAGE_COLOR);//这里为矩阵开辟内存
Mat B(A);//使用拷贝构造函数
C=A;

这段代码中,A、B和C都是Mat类型,它们都指向同一个也是唯一一个数据矩阵。虽然它们的信息头不同,但通过任何一个对象所做的改变也会影响其它对象。而通过clone()或者copyTo()来复制一个图像,就包括了矩阵本身,也因此,改变复制对象的内容并不会改变源矩阵,例如frame1显然是复制frame,因此对frame1的操作并不改变frame。

Mat的常见属性

属性 说明
data uchar型的指针。Mat类分为了两个部分:矩阵头和指向矩阵数据部分的指针,data就是指向矩阵数据的指针。
dims 矩阵的维度,例如5*6矩阵是二维矩阵,则dims=2,三维矩阵dims=3.
rows 矩阵的行数
cols 矩阵的列数
size 矩阵的大小,size(cols,rows)
channels() 矩阵元素拥有的通道数,例如常见的彩色图像,每一个像素由RGB三个通道组成
type() 表示了矩阵中元素的类型以及矩阵的通道个数,它是一系列的预定义的常量,其命名规则为CV_(位数)+(数据类型)+(通道数)如:,CV_8UC3
depth() 矩阵中元素的一个通道的数据类型,这个值和type是相关的。例如 type为 CV_8UC3,一个3通道的16位的有符号整数。那么,depth则是CV_8UC
elemSize() 矩阵一个元素占用的字节数(不区分通道,即多个通道的总和)
elemSize1() 矩阵一个元素每个通道占用的字节数(区分通道,单个通道的值)
flags 一个int型数字,保存了许多有用的信息,flags说明;

创建Mat的方式:

1、Mat M 
创建一个矩阵头,没有数据。 
2、Mat M(2,2,CV_8UC3,Scalar(0,0,1)); 
2*2大小的矩阵,每个元素为3通道8位无符号整数,如下:

0 0 1 0 0 1 
0 0 1 0 0 1 
3、Mat M(2,2,CV_8UC1,Scalar(10)); 
与上面类似: 
10 10 
10 10 
4、Mat M(2,2,CV_8UC1,Scalar::all(0));
5、以逗号分隔符初始化赋值:Mat M = (Mat_(3,3) << 1,2,3,4,5,6,7,8,9); 
6、为已经存在的IplImage指针创建信息头,例如:

IplImage* img=cvLoadImage("1.jpg",1);
Mat mtx(img);//转换IplImage*为Mat

7、利用create()函数

Mat M;M.create(4,4,CV_8UC(2));
cout<<"M="M<<endl;

但是这种方法不能为矩阵设初值,只是在改变尺寸时重新为矩阵数据开辟内存而已。

8、Mat还有一些matlab式函数用来创建和初始化矩阵: 
Mat E = Mat::eye(4,4,CV_64F); //单位矩阵
Mat Z = Mat::zeros(4,4,CV_32F); //0矩阵
Mat O = Mat::ones(4,4,CV_8UC1); //1矩阵
9、为已经存在的对象创建新的信息头

Mat E=Mat::eye(4,4,CV_64F);
Mat Row=E.row(1).clone();
cout<<Row<<endl;

转载于:https://www.cnblogs.com/cvtoEyes/p/8502602.html

opencv的基本数据结构(一)(转)相关推荐

  1. OPENCV中图像数据结构及其转化

    OPENCV中图像数据结构及其转化 1. IplImage 它是openCV库中表示图像的结构体. 初始化: cvLoadImage(),cvCreateImage() 访问元素:[行指针] b = ...

  2. OPENCV中的数据结构总结

    最近在写自己的算法,其实就是对一些传统算法的改进.传统算法可以参考opecv的源代码.在阅读源代码的过程中,我慢慢领会到了opencv的强大之处,并不是因为它实现了各种算法,而是在于它对于基本数据结构 ...

  3. OpenCV中的数据结构

    首先介绍2维点对Point_,它的是一个模板类.我们可以直接访问数据成员x,y.它不仅定了+.-.==.!=这4个基本的操作,还定义了点乘.叉乘等操作.特别的这个类还提供了inside函数来判断一个点 ...

  4. OpenCV中基本数据结构(7)_Vec

    Vec系列数据结构是Matx的一个派生类,其矩阵的行的大小永远固定为一行,列大小从1到6不等,可以认为类似与C++ vector,但与C++ 的vector又有很大不同,,以下不同来自于一段技术博客, ...

  5. OpenCV中基本数据结构(5)_RotatedRect

    RotatedRect也是表示一个矩形框,但是与Rect不同的是,RotatedRect可以带倾斜角的矩形,如下图所示: RotatedRect结构中包括三个变量: Point2f center:为矩 ...

  6. OpenCV中基本数据结构(4)_Rect

    Rect数据结构经常是在OpenCV中被用来表示为一个矩形尺寸,其成员包括x,y, width,height,其中x和y分别表示矩形框的左上角的起始点坐标,width和height分别表示宽和高. R ...

  7. OpenCV中基本数据结构(3)_Size

    Size数据结构经常被OpenCV用来表示尺寸,其成员为width和height,被用来表示矩阵或者图片的宽和高. Size Size预定义个几个类型有: Size2i:整型int Size2l:in ...

  8. OpenCV中基本数据结构(1)_Point

    为了便于对一些常见的数据进行操作,OpenCV定义了一些常见的数据结构(Point ,Scalar等),以方便后续对数据算法的实现,主要分为basic data type.helper objects ...

  9. OpenCV的基本数据结构

    参考<OpenCV中文参考手册> 1.图像数据结构 (1) IPL :IplImage|-- int nChannels; // 颜色通道数目 (1,2,3,4)|-- int depth ...

  10. 【OpenCV】KeyPoint数据结构

    KeyPoint数据结构 KeyPoint数据结构官方说明网站:(http://docs.opencv.org/3.3.0/d2/d29/classcv_1_1KeyPoint.html) 公有属性 ...

最新文章

  1. node 压缩图片_1Mb压缩成100k,图片无损压缩我选择它
  2. 感知机算法的两种表示
  3. 使用vue-cli+element-ui+expsess+mysql做一个简易的登录功能
  4. Cpp 对象模型探索 / 编译器为对象创建缺省析构函数的条件
  5. arm-linux-gcc 4.7.4 源码编译 手工制作
  6. spring事务管理-演示事务的环境准备
  7. 淘系音视频技术的演进之路
  8. C++ 的基础概念(3)——多态详解。
  9. Android Caused by: java.lang.IllegalArgumentException: column '_id' does not exist
  10. SpringBoot + MyBatis(注解版),常用的SQL方法
  11. python内存消耗大吗_如何减少python内存的消耗?
  12. hdu5106 小于x的数(二进制1确定的数)的和 数位dp(first mine)
  13. JCI标准认证对我国医院建设有什么意义?
  14. 【GAMES101】三维旋转矩阵中绕三个轴旋转的矩阵公式
  15. 阿里图标css的使用中的使用方法,iconfont阿里巴巴矢量图标库的正确使用方法
  16. 根文件系统的作用 VSF的作用 Linux系统结构详解 加载内核映像和根文件系统映像
  17. [OpenHarmony RK3568] (二)基础开发
  18. android 摄像头比例,Android摄像头是全屏预览最简单的方式.doc
  19. 深圳知名语音ic品牌,语音芯片方案公司,多功能语音芯片,WTV890
  20. java8 集合的交集、并集、差集

热门文章

  1. 解决mysql报错Can’t connect to local MySQL server through socket ‘/var/lib/mysql/mysql.sock
  2. Tomcat中组件的生命周期管理(三)
  3. eclipse连接hdfs操作设置用户名
  4. (MariaDB/MySQL)之DML(2):数据更新、删除
  5. 浅析epoll-为何多路复用I/O要使用epoll
  6. drf6 权限和频率控制组件
  7. java打开文件出错_打开文件错误太多,java.io.FileNotFoundException
  8. 如何通过apache运行php,apache-2.2 – 如何使所有URL通过单个PHP文件运行?
  9. 试题 历届试题 买不到的数目(dp/数学)
  10. P1119 灾后重建(经典floyd)