OpenCV源码阅读——1.1 Mat的结构
来源:互联网 发布:winpe数据恢复版 编辑:程序博客网 时间:2024/04/30 14:38
抱着学习的态度,阅读OpenCV源码。我阅读的版本是OpenCV2.4.8,其实2.X在思路上是很相似的。OpenCV自带了详尽的文档。其中opencv_tutorials.pdf是OpenCV入门文档,该文档中有大量的示例;opencv2refman.pdf是函数手册。这两个文档也是重要的参考资料。
第一章 Mat
本章主要内容:Mat类的结构、内存管理、运算、_InputArray类
主要涉及文件有:
include | opencv2 | core | core.hpp 其中有Mat类定义
| mat.hpp 其中有Mat类实现
| types_c.h C语言类型定义和部分函数
modules | core | src | arithm.cpp 算法实现
| matop.cpp Mat的运算
Mat是OpenCV中最关键的类之一,破解Mat类对把握OpenCV有重要作用,同时通过这部分阅读可以了解OpenCV的设计理念。
Mat是Matrix的简称,中文含义是矩阵,OpenCV2.x摒弃了1.x中区别对待IplImage、CvMat等结构的思路,将所有的问题划归到数学概念中去,图像在线性空间中的表达就是矩阵。
另外,OpenCV中定义了Matx(小矩阵)的结构,Vec(向量)是Matx的子类。他们通过_InputArray(输入数组)类实现相互转换。在矩阵运算、图像处理等函数中,通过以_InputArray类为代理,访问Mat或Vec。Mat_<T>是Mat的子类,是Mat的模板化。
1.1 Mat的结构
【core.hpp 1475-2010行】【opencv2refman.pdf 25-44页】
1.1.1 Mat中成员变量
/*! includes several bit-fields: - the magic signature - continuity flag - depth - number of channels */ int flags; //! the matrix dimensionality, >= 2 int dims; //! the number of rows and columns or (-1, -1) when the matrix has more than 2 dimensions int rows, cols; //! pointer to the data uchar* data; //! pointer to the reference counter; // when matrix points to user-allocated data, the pointer is NULL int* refcount; //! helper fields used in locateROI and adjustROI uchar* datastart; uchar* dataend; uchar* datalimit; //! custom allocator MatAllocator* allocator; MSize size; MStep step;
(1) flag是标记,他由五部分组成:
1、0-2位:深度,在types_c.h中深度值如下:
CV_8U00x000CV_8S
10x001CV_16U
20x010CV_16S
30x011CV_32S
40x100CV_32F
50x101CV_64F
60x110CV_USRTYPE1
70x111
2、3-11位:通道数减1,因为即灰度图像(1通道)时3-11位是0x000000000,彩色图像(3通道)时3-11位是0x000000010
3、14位:MAT_CONT_FLAG,矩阵的数据存储是否连续的标记,1表示连续,0表示不连续
4、15位:SUBMAT_FLAG,子矩阵标记,Mat支持从大矩阵中取出子矩阵,数据没有复制。
例如,假设Mat A是3×3的矩阵
| 1 2 3 |
A = | 4 5 6 |
| 7 8 9 |
Mat B = A.rowRange(1,2);//B取A的第2到3行,行号以0开始
则 B = | 4 5 6 |
| 7 8 9 |,
B的数据并没有新增加,而是直接指向了A的数据,B的datastart和dataend表明了起止位置,rows和cols表明了尺寸。具体将在Mat的内存管理中说明。
5、16-31位:默认的标记MAGIC_VAL,由于矩阵有很多种类型,_InputArray代理所有的数据输入时,需要依赖这个量来判断数据类型,这个值就表达了该类的类型。
查看源码可以知道
类型MAGIC_VAL值SparseMat(系数矩阵)0x42FD0000Mat0x42FF0000cvMat0x42420000CvMatND0x42430000CvSparseMat0x42440000CvHistogram0x42450000CvMemStorage0x42890000CvSeq0x42990000CvSet0x42980000IPLImage0x00000070
他们都是类或结构体的前两个字节(int)。IPLImage来自以往的库,他的前两个字节是int nSize,是结构体的大小,也就是说他的MAGIC_VAL是0x00000070。
(2)dims是维度(一般是2);rows是行数;cols是列数。
(3)data指针指向了数据;refcount指针指向了一个计数器,这个计数器记录着多少个Mat指向了同一个data,当计数为0时,释放data;allocator是动态内存申请器。
(4)step保存了一行的宽度,完整连续的图像step.p[0]与cols相等,子矩阵的step.p[0]与原始图像的cols相等。
代码注释非常给力,以下几行注释清楚地表现了Mat的结构:
1.1.2 Mat的构造函数、赋值运算符、数据类型转换运算符
构造函数、赋值运算、类型转换都表现了数据转换能力:
(1)构造函数
1、空构造函数【1690行】
2、指定尺寸和类型【1692行】,或由Scalar结构定义尺寸和类型【1696行】
3、高维【1700行】
4、从其他Mat拷贝【1704行】
5、从数据块拷贝并指定尺寸和类型【1706行】
6、只定义一个头,数据指向其他Mat中一部分(行列范围、ROI)【1711行】
7、从老式的CvMat、CvMatND、IplImage转换成Mat【1715-1719行】
8、从新式的std::vector、cv::Vec、cv::Matx、2D point、3D point、comma initializer转换成Mat【1722-1731行】
(2)赋值运算
9、const Mat& m从另一个Mat转换【1740行】
10、const MatExpr& expr从矩阵表达式转换成Mat【1741行】
矩阵表达式MatExpr,构造了一个运算结构,具体在Mat的计算中解释
11、const Scalar& s从Scalar转换成Mat,是用一种颜色将整个图像填充【1774行】
(3)数据转换运算
11、括号运算符:截取子矩阵【1842-1844行】
12、数据转换:由Mat转换成老式结构CvMat、CvMatND、IplImage【1846-1851行】
13、数据转换:由Mat转换成vector<_Tp>、Vec<_Tp, n>、Matx<_Tp, m, n>【1853-1855行】
- OpenCV源码阅读——1.1 Mat的结构
- OpenCV源码阅读——1.2 Mat的内存管理
- OPENCV里的Mat结构
- GrFmtReader的类结构----OpenCV源码阅读之六
- OpenCV Mat结构
- OpenCV-Mat结构详解
- OpenCV Mat 结构
- opencv——mat操作
- OpenCV学习——Mat
- OpenCV ——mat---ROI
- OpenCV——Mat类
- OpenCV——数据结构Mat
- opencv(一) Mat结构访问
- opencv中的Mat结构操作
- OpenCV的下载安装及简单的Mat结构介绍
- OpenCV源码阅读(1)---matx.h---mat类与vec类
- opencv Mat结构和CImage的转化和显示
- OpenCV中Mat结构图像元素的获取
- 【VC6.0】打开文件时出错,利用filetool解决win7、win8不兼容VC6.0
- CSS设计指南(1)
- 基于51单片机的12864驱动
- 用emacs写C程序
- 读取资源文件
- OpenCV源码阅读——1.1 Mat的结构
- 你有情 盼我有义
- C++代码注释规范
- 驴妈妈管理的一点经验总结
- 两个UIView的翻转动画 貌似必须把它们加到同一个View上
- Linux下gvim简单配置
- Ubuntu 10.04设置Samba服务器
- C++语言之声明与定义
- 苹果App Store审核指南(中文翻译)-App Store Review Guidelines