【转】OpenCV Mat数据结构
转载自xiahouzuoxin原文 OpenCV基础篇之Mat数据结构
程序及分析
/*
* FileName : MatObj.cpp
* Author : xiahouzuoxin @163.com
* Version : v1.0
* Date : Thu 15 May 2014 09:12:45 PM CST
* Brief :
*
* Copyright (C) MICL,USTB
*/
#include <cv.h>
#include <highgui.h>
#include <iostream> using namespace std;
using namespace cv; int main(void)
{
/*
* Create Mat
*/
Mat M(2,2,CV_8UC3, Scalar(0,0,255));
cout << "M=" << endl << " " << M << endl << endl; /*
* Matlab style
*/
Mat E = Mat::eye(4,4,CV_64F);
cout << "E=" << endl << " " << E << endl << endl;
E = Mat::ones(4,4,CV_64F);
cout << "E=" << endl << " " << E << endl << endl;
E = Mat::zeros(4,4,CV_64F);
cout << "E=" << endl << " " << E << endl << endl; /*
* Convert IplImage to Mat
*/
IplImage *img = cvLoadImage("../test_imgs/Lena.jpg");
Mat L(img);
namedWindow("Lena.jpg", CV_WINDOW_AUTOSIZE);
imshow("Lena.jpg", L);
waitKey(0); /*
* Init Mat with separated data
*/
Mat C = (Mat_<int>(3,3) << 0,1,2,3,4,5,6,7,8);
cout << "C=" << endl << " " << C << endl << endl; return 0;
}
Mat 是OpenCV最基本的数据结构,Mat即矩阵(Matrix)的缩写,Mat数据结构主要包含2部分:Header和Pointer。Header中主 要包含矩阵的大小,存储方式,存储地址等信息;Pointer中存储指向像素值的指针。我们在读取图片的时候就是将图片定义为Mat类型,其重载的构造函 数一大堆,
class CV_EXPORTS Mat
{
public:
//! default constructor
Mat();
//! constructs 2D matrix of the specified size and type
// (_type is CV_8UC1, CV_64FC3, CV_32SC(12) etc.)
Mat(int _rows, int _cols, int _type);
Mat(Size _size, int _type);
//! constucts 2D matrix and fills it with the specified value _s.
Mat(int _rows, int _cols, int _type, const Scalar& _s);
Mat(Size _size, int _type, const Scalar& _s); //! constructs n-dimensional matrix
Mat(int _ndims, const int* _sizes, int _type);
Mat(int _ndims, const int* _sizes, int _type, const Scalar& _s); //! copy constructor
Mat(const Mat& m);
//! constructor for matrix headers pointing to user-allocated data
Mat(int _rows, int _cols, int _type, void* _data, size_t _step=AUTO_STEP);
Mat(Size _size, int _type, void* _data, size_t _step=AUTO_STEP);
Mat(int _ndims, const int* _sizes, int _type, void* _data, const size_t* _steps=0); //! creates a matrix header for a part of the bigger matrix
Mat(const Mat& m, const Range& rowRange, const Range& colRange=Range::all());
Mat(const Mat& m, const Rect& roi);
Mat(const Mat& m, const Range* ranges);
//! converts old-style CvMat to the new matrix; the data is not copied by default
Mat(const CvMat* m, bool copyData=false);
//! converts old-style CvMatND to the new matrix; the data is not copied by default
Mat(const CvMatND* m, bool copyData=false);
//! converts old-style IplImage to the new matrix; the data is not copied by default
Mat(const IplImage* img, bool copyData=false); ......
}
要了解如何初始化Mat结构,就应该了解它的构造函数,比如程序中的第一初始化方式调用额就是
Mat(int _rows, int _cols, int _type, const Scalar& _s);
这个构造函数。
IplImage*是C语言操作OpenCV的数据结构,在当时C操纵OpenCV的时候,地位等同于Mat,OpenCV为其提供了一个接口,很方便的直接将IplImage转化为Mat,即使用构造函数
Mat(const IplImage* img, bool copyData=false);
上面程序中的第二种方法就是使用的这个构造函数。
关于Mat数据复制:前面说过Mat包括头和数据指针,当使用Mat的构造函数初始化的时候,会将头和数据指针复制(注意:只是指针复制,指针指向的地址不会复制),若要将数据也复制,则必须使用copyTo或clone函数

Mat还有几个常用的成员函数,在之后的文章中将会使用到:
//! returns true iff the matrix data is continuous
// (i.e. when there are no gaps between successive rows).
// similar to CV_IS_MAT_CONT(cvmat->type)
bool isContinuous() const;
这了解上面的函数作用前,得了解下OpenCV中存储像素的方法,如下,灰度图(单通道)存储按行列存储,

三通道RGB存储方式如下,每列含有三个通道,

为了加快访问的速度,openCV往往会在内存中将像素数据连续地存储成一行,isContinus()函数的作用就是用于判断是否连续存储成一行。存储成一行有什么好处呢?给定这行的头指针p,则只要使用p++操作就能逐个访问数据。
因此当判断存放在一行的时候,可以通过数据指针++很容易遍历图像像素:
long nRows = M.rows * M.channels(); // channels()也是Mat中一个常用的函数,用于获取通道数(RGB=3,灰度=1)
long nCols = M.cols;
uchar *p = M.data; // 数据指针
if(M.isContinuous())
{
nCols *= nRows;
for (long i=0; i < nCols; i++) {
*p++ = ...; // 像素赋值或读取操作
}
}
请注意以上几个常用的Mat成员遍历和函数:
M.row; // 返回图像行数
M.nCols; // 返回图像列数
M.channels(); //返回通道数
M.isContinuous(); // 返回bool类型表示是否连续存储
更多关于Mat的信息请参考安装目录下的include/opencv2/core.hpp文件
效果

左边是矩阵的一些操作输出结果,右边的图是通过IplImage *结构读入,转换为Mat后显示结果。
【转】OpenCV Mat数据结构的更多相关文章
- OpenCV(2)-Mat数据结构及访问Mat中像素
Mat数据结构 一开始OpenCV是基于C语言的,在比较早的教材例如<学习OpenCV>中,讲解的存储图像的数据结构还是IplImage,这样需要手动管理内存.现在存储图像的基本数据结构是 ...
- Opencv 的数据结构
opencv的基本数据结构 结构 成员 意义 CvPoint int x,y 图像中的点 CvPoint2D32f float x,y 二维空间中的点 CvPoint3D32f float x,y,z ...
- OpenCV Mat数据类型及位数总结(转载)
OpenCV Mat数据类型及位数总结(转载) 前言 opencv中很多数据结构为了达到內存使用的最优化,通常都会用它最小上限的空间来分配变量,有的数据结构也会因为图像文件格式的关系而给予适当的变量, ...
- opencv 基本数据结构
转自:http://www.cnblogs.com/guoqiaojin/p/3176692.html opencv 基本数据结构 DataType : 将C++数据类型转换为对应的opencv数 ...
- Opencv基本数据结构
Opencv的数据结构:CvPoint系列.CvSize系列 .CvSize.CvRect.CvScalar.CvAr 大多数据结构都在cxtypes.h这个头文件里定义 1.CvPoint系列: ...
- Matlab to OpenCV Mat
convert Matlab matrix to OpenCV Mat. Support CV_32FC3 only currently. The Code int matlab2opencv(cv: ...
- OpenCV Mat数据类型指针ptr的使用
OpenCV Mat数据类型指针ptr的使用 cv::Mat image = cv::Mat(400, 600, CV_8UC1); //宽400,长600 uchar * data00 = imag ...
- Qt QImage与OpenCV Mat转换
本系列文章由 @yhl_leo 出品,转载请注明出处. 文章链接: http://blog.csdn.net/yhl_leo/article/details/51029382 应一个朋友的要求,整理总 ...
- 快速遍历OpenCV Mat图像数据的多种方法和性能分析 | opencv mat for loop
本文首发于个人博客https://kezunlin.me/post/61d55ab4/,欢迎阅读! opencv mat for loop Series Part 1: compile opencv ...
随机推荐
- Windows: 在系统启动时运行程序、定时计划任务、定时关机
lesca今天介绍一些让系统在启动时,而非登录时,加载用户自定义的应用程序或脚本的方法,推荐度从前到后依次递减. 1. Windows任务计划(task scheduler) 用户可以按以下步骤进行操 ...
- lumen 框架的特殊使用
1. 配置代码格式管理工具: composer require squizlabs/php_codesniffer, 使用 php artisan cs 检查代码格式: 2.单元测试用例编写 1./d ...
- 用OpenSSL命令行生成证书文件
用OpenSSL命令行生成证书文件 1.首先要生成服务器端的私钥(key文件): openssl genrsa -des3 -out server.key 1024 运行时会提示输入密码,此密码用于加 ...
- 791. Custom Sort String
S and T are strings composed of lowercase letters. In S, no letter occurs more than once. S was sort ...
- 向SD卡写入树莓派的操作系统
这是 meelo 原创的 玩转树莓派 系列文章 用到的工具: Win32 Disk Imager: sd卡读卡器 Raspbian操作系统镜像:下载地址 步骤1:下载操作系统的镜像 树莓派基金会的网 ...
- [实战]MVC5+EF6+MySql企业网盘实战(24)——视频列表
写在前面 上篇文章实现了文档列表,所以实现视频列表就依葫芦画瓢就行了. 系列文章 [EF]vs15+ef6+mysql code first方式 [实战]MVC5+EF6+MySql企业网盘实战(1) ...
- Java虚拟机四:垃圾回收算法与垃圾收集器
在Java运行时的几个数据区域中,程序计数器,虚拟机栈,本地方法栈3个区域随着线程而生,随线程而灭,因此这几个区域的内存分配和回收具有确定性,不需要过多考虑垃圾回收问题,因为方法结束或者线程结束时,内 ...
- lr11_Vugen_Genrial Options选项介绍:
lr11_Vugen_Genrial Options选项介绍:
- RSA私钥和公钥文件格式 (pkcs#1, pkcs#8, pkcs#12, pem)
RSA私钥和公钥文件格式 (pkcs#1, pkcs#8, pkcs#12, pem) 2018年03月07日 11:57:22 阅读数:674 Format Name Description PKC ...
- Ubuntu编译安装nginx,php,mysql
摘要: 整理的Ubuntu编译安装nginx,php,mysql的步骤,主要来自对驻云的sh-1.4.1中脚本的整理,随时代进步,内容中的软件或者命令请自行更新 目录准备 创建用户 userdel w ...