opencv中Mat数据结构

opencv中Mat数据结构

  • 1 Mat类结构
    • 1.1 数据部分
    • 1.2 函数部分
      • 1.2.1 构造函数和析构函数
      • 1.2.2 运算符重载
      • 1.2.3 数据访问函数
      • 1.2.4 其它常用函数
  • 2 矩阵元素数据存储方式
    • 2.1 存储方式
    • 2.2 矩阵数据的读写(不用opencv)

1 Mat类结构

Mat是matrix矩阵的简写,Mat类中数据部分主要分为两个部分:头和数据指针。头中定义一些矩阵的行数、列数、通道数、维度等信息;数据指针中定义uchar* data的数据地址。函数部分主要包括大量构造函数、大量模版函数以及一些非模版函数。
我们知道在c++中类实例化的对象中,真正拥有的是数据部分。

1.1 数据部分

int flags; //signature
int dims; //维数,灰度图像二维,rgb图像三维
int rows, cols; //行数和列数,这里说的是逻辑上的矩阵的行数和列数,而不是物理存储时
uchar* data; // 矩阵元素数据的首地址,类型是uchar*,在c/c++中通常最小的数据处理大小是一个字节

//图像ROI的辅助指针
uchar* datastart;
uchar* dataend;
uchar* datalimit;

MSize size; //一行含有的字节数,MSize和MStep是定义的结构体
MStep step;
//...

1.2 函数部分

1.2.1 构造函数和析构函数

Mat();
Mat(int rows, int cols, int type);
Mat(Size size, int type);
Mat(int rows, int cols, int type, const Scalar& s);
Mat(Size size, int type, const Scalar& s);
Mat(int ndims, const int* sizes, int type);
Mat(int ndims, const int* sizes, int type, const Scalar& s);

Mat(const Mat& m);

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);

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);

Mat(const IplImage* img, bool copyData=false);
//...
~Mat();

1.2.2 运算符重载

Mat& operator = (const Mat& m); //赋值运算符重载,做的是浅拷贝
Mat& operator = (const MatExpr& expr);
Mat& operator = (const Scalar& s);

Mat operator()( Range rowRange, Range colRange ) const;
Mat operator()( const Rect& roi ) const;
Mat operator()( const Range* ranges ) const;

CV_EXPORTS MatExpr operator * (const Mat& a, const Mat& b);//矩阵内积

operator CvMat() const;
operator CvMatND() const;
operator IplImage() const;

template<typename _Tp> operator vector<_Tp>() const;
template<typename _Tp, int n> operator Vec<_Tp, n>() const;
template<typename _Tp, int m, int n> operator Matx<_Tp, m, n>() const;

1.2.3 数据访问函数

ptr函数


// 返回矩阵元素指针
uchar* ptr(const int* idx);
const uchar* ptr(const int* idx) const;

template<typename _Tp> _Tp* ptr(int i0=0);
template<typename _Tp> const _Tp* ptr(int i0=0) const;

template<typename _Tp> _Tp* ptr(int i0, int i1);
template<typename _Tp> const _Tp* ptr(int i0, int i1) const;

template<typename _Tp> _Tp* ptr(int i0, int i1, int i2);
template<typename _Tp> const _Tp* ptr(int i0, int i1, int i2) const;

template<typename _Tp> _Tp* ptr(const int* idx);
template<typename _Tp> const _Tp* ptr(const int* idx) const;

template<typename _Tp, int n> _Tp* ptr(const Vec<int, n>& idx);
template<typename _Tp, int n> const _Tp* ptr(const Vec<int, n>& idx) const;

at函数

template<typename _Tp> _Tp& at(int i0=0);
template<typename _Tp> const _Tp& at(int i0=0) const;

template<typename _Tp> _Tp& at(int i0, int i1);
template<typename _Tp> const _Tp& at(int i0, int i1) const;

template<typename _Tp> _Tp& at(int i0, int i1, int i2);
template<typename _Tp> const _Tp& at(int i0, int i1, int i2) const;

template<typename _Tp> _Tp& at(const int* idx);
template<typename _Tp> const _Tp& at(const int* idx) const;

template<typename _Tp, int n> _Tp& at(const Vec<int, n>& idx);
template<typename _Tp, int n> const _Tp& at(const Vec<int, n>& idx) const;

//! special versions for 2D arrays (especially convenient for referencing image pixels)
template<typename _Tp> _Tp& at(Point pt);
template<typename _Tp> const _Tp& at(Point pt) const;

迭代器函数

template<typename _Tp> MatIterator_<_Tp> begin();
template<typename _Tp> MatIterator_<_Tp> end();
template<typename _Tp> MatConstIterator_<_Tp> begin() const;
template<typename _Tp> MatConstIterator_<_Tp> end() const;

1.2.4 其它常用函数

  1. matlab风格的初始化函数,静态函数
  2. 矩阵运算
  3. 返回通道数等
  4. 深拷贝函数
//matlab风格的初始化函数,静态函数
static MatExpr zeros(int rows, int cols, int type);
static MatExpr zeros(Size size, int type);
static MatExpr ones(int rows, int cols, int type);
static MatExpr ones(Size size, int type);
static MatExpr eye(int rows, int cols, int type);
static MatExpr eye(Size size, int type);

//矩阵运算
Mat cross(InputArray m) const; //一维向量的叉乘,即外积
double dot(InputArray m) const; //一维向量内积,结果是一个数
MatExpr mul(InputArray m, double scale=1) const; //矩阵对应元素的乘积
//两个矩阵的内积有重载的*可以实现 即 C=A*B,A的行数要与B的列数一致
MatExpr inv(int method=DECOMP_LU) const; //矩阵的逆矩阵
MatExpr t() const; //矩阵转置

//
size_t total() const;//返回图像中像素点总数量=rows*cols
int type() const; //返回类型CV_8UC1 CV_16SC1 CV_32FC3等
int depth() const;
int channels() const; //返回通道数
size_t elemSize() const; //返回像素元素的大小以字节的方式,包括通道。
bool isContinuous() const; //判断数据存储是否连续
void create(int rows, int cols, int type); //如果之前矩阵没有创建数据,可以创建

//深拷贝函数
Mat clone() const;
void copyTo( OutputArray m ) const;
void copyTo( OutputArray m, InputArray mask ) const;
//...

2 矩阵元素数据存储方式

2.1 存储方式

uchar data;对应的是数据的首元素存储地址。
数据存储时,逐步扫描行,在内存中按照读的顺序存储。
opencv中Mat数据结构_第1张图片
根据数据的存储方式,可知要获取一个图像或矩阵的元素的数据,有几个关键点:

  1. 获得存储数据的首地址,即uchar* data;
  2. 获得图像或矩阵的通道数,是单通道(灰度图像)还是三通道(RGB)图像,即

Mat src;
int src.channels();

  1. 获得每个元素的字节大小。

src.elemSize(); //返回元素所有通道一共的字节大小。如CV_8UC3,返回的就是1*3=3
src.elemSize1(); //返回元素单通道的字节大小。如CV_8UC3,返回的就是1

2.2 矩阵数据的读写(不用opencv)

//data 是数据存储的首地址,
//channels是图像的通道数,
//elemSize是每个元素单通道中的字节数
// rows 行数
// cols 列数
void work(uchar* data,int channels,int elemSize,int rows,int cols)
{
	for (int i=0;i<rows;i++)
	{
		uchar* p = data + cols*channels*elemSize*i; //获得i行的首地址
		for (int j=0;j<cols;j++)
		{
			uchar* pj = p+j*channels*elemSize; //获得第j列的首地址
			//do something   
		}
	}
}

你可能感兴趣的:(opencv)