OpenCV学习(九)之Mat基本数据结构_2

一、Mat Constructors:

C++: Mat::Mat()
C++: Mat::Mat(int rows, int cols, int type)
C++: Mat::Mat(Size size, int type)
C++: Mat::Mat(int rows, int cols, int type, const Scalar& s)
C++: Mat::Mat(Size size, int type, const Scalar& s)
C++: Mat::Mat(const Mat& m)
C++: Mat::Mat(int rows, int cols, int type, void* data, size_t step=AUTO_STEP)
C++: Mat::Mat(Size size, int type, void* data, size_t step=AUTO_STEP)
C++: Mat::Mat(const Mat& m, const Range& rowRange, const Range& colRange=Range::all() )
C++: Mat::Mat(const Mat& m, const Rect& roi)
C++: Mat::Mat(const CvMat* m, bool copyData=false)
C++: Mat::Mat(const IplImage* img, bool copyData=false)
C++: template<typename T, int n> explicit Mat::Mat(const Vec<T, n>& vec, bool copyData=true)
C++: template<typename T, int m, int n> explicit Mat::Mat(const Matx<T, m, n>& vec, bool copyData=true)
C++: template<typename T> explicit Mat::Mat(const vector<T>& vec, bool copyData=false)
C++: Mat::Mat(int ndims, const int* sizes, int type)
C++: Mat::Mat(int ndims, const int* sizes, int type, const Scalar& s)
C++: Mat::Mat(int ndims, const int* sizes, int type, void* data, const size_t* steps=0)
C++: Mat::Mat(const Mat& m, const Range* ranges)
参数解释:

ndims– 数组的维数.


rows – 2维数组中行行数


cols – 2维数组中的列数


size – 2维数组的尺寸Size(cols, rows)Size(width,height).在Size()构造函数中行数和列数在次序上刚好反转过来了。


sizes–指定 n 维数组形状的整数数组,表示维度的数组


type–数组的类型。使用 CV_8UC1,… …,创建 1-4 通道的矩阵,CV_64FC4 或CV_8UC(n),… …,CV_64FC(n)可以创建多通道 (高达 CV_MAX_CN 通道)矩阵。


s–个可选的初始化每个矩阵元素的参数。要在矩阵建成后将所有元素设置为特定值可以用Mat的赋值运算符Mat:operator=(const Scalar& value)。


data–指向用户数据区域的指针。矩阵构造函数传入data和step参数不分配矩阵数据。相反,它们只是初始化矩阵头指向指定的数据,这意味着没有数据的复制。此操作是很高效的,可以用来处理使用 OpenCV 函数的外部数据。外部数据不会自动释放,所以你应该小心处理它。


step – 每个矩阵行占用的字节数。如果任何值应包括每行末尾的填充字节。如果缺少此参数(设置为 AUTO_STEP),假定没有填充和实际的步长用cols*elemSize()计算。请参阅Mat::elemSize(),elemSize() = sizeof(type) * channels.


step1 -- 这里需要介绍一下step1. step1 = step/elemSize1(), elemSize1() = sizeof(type), elemSize1() 返回一个通道的大小,而不是一个像素值的大小。所以step1 = cols * channels。


steps–多维数组(最后一步始终设置为元素大小) 的情况下的 ndims-1个步长的数组。如果没有指定的话,该矩阵假定为连续。


m–分配给构造出来的矩阵的阵列(作为一个整体或部分)。这些构造函数没有复制数据。相反,指向 m 的数据或它的子数组的头被构造并被关联到m上。引用计数器中无论如何都将递增。所以,当您修改矩阵的时候,自然而然就使用了这种构造函数,您还修改 m 中的对应元素。如果你想要独立的子数组的副本,请使用 Mat::clone()。

img –指向老版本的 IplImage图像结构的指针。默认情况下,原始图像和新矩阵之间共享数据。但当 copyData 被设置时,完整的图像数据副本就创建起来了。


vec–矩阵的元素构成的STL 向量。矩阵可以取出单独一列并且该列上的行数和矢量元素的数目相同。矩阵的类型匹配的向量元素的类型。构造函数可以处理任意的有正确声明的DataType类型。这意味着矢量元素不支持的混合型结构,它们必须是数据(numbers)原始数字或单型数值元组。对应的构造函数是显式的。由于 STL 向量不会自动转换为Mat实例,您应显式编写 Mat(vec)。除非您将数据复制到矩阵 (copyData = true),没有新的元素被添加到向量中,因为这样可能会造成矢量数据重新分配,并且因此使得矩阵的数据指针无效。

copyData –指定STL 向量或旧型 CvMat 或 IplImage是应复制到 (true)新构造的矩阵中,还是(false) 与之共享基础数据的标志,复制数据时,使用Mat引用计数机制管理所分配的缓冲区。虽然数据共享的引用计数为 NULL,但是分配数据必须在矩阵被析构之后才可以释放。

rowRange – m 的行数的取值范围。正常情况下,范围开始端是包含的,而末尾段是不包含的。使用 rowRange::all() 来取所有的行。

colRange – m 列数的取值范围。使用 colRange::all() 来取所有的列。

ranges –表示M沿每个维度选定的区域的数组。

expr – 矩阵表达式,请参见矩阵表达式。

下面添加一些函数的测试:

实验环境:VS2010 + OpenCV2.4.9.0

int main(int argc,char** argv)
{
	Mat M(2,2,CV_8UC3,Scalar(0,0,255));
	//Mat M;
	//M.create(4,4,CV_8UC2);
	cout << "M = " << endl <<" " << M << endl << endl;
	system("pause");
	return 0;
}

//Define some matrices
int main(int argc,char** argv)
{
	Mat E = Mat::eye(4,4,CV_64F);
	cout << "E = " << endl <<" " << E<< endl << endl;

	Mat ON  = Mat::ones(4,4,CV_32F);
	cout << "ON = " << endl <<" " << ON << endl << endl;

	Mat Z = Mat::zeros(3,3,CV_8UC1);
	cout << "Z = " << endl << " " << Z << endl << endl;
	system("pause");
	return 0;
}

//For small matrices,may use comma separated initializers
int main(int argc,char** argv)
{
	Mat C = (Mat_<double>(3,3)<<0,-1,0,-1,5,-1,0,-1,0);
	cout << "C = " << endl <<" " << C<< endl << endl;

	//Create a new header for an existing Mat object and clone() or copyTo() it
	Mat rowClone = C.row(1).clone();
	cout << "rowClone = " << endl <<" " << rowClone << endl << endl;

	Mat rowCopy;
	C.row(1).copyTo(rowCopy);
	cout << "rowCopy = " << endl <<" " << rowCopy << endl << endl;
	
	system("pause");
	return 0;
}

//random function
int main(int argc,char** argv)
{
	Mat R = Mat(3,2,CV_8UC3);
	randu(R,Scalar::all(0),Scalar::all(255));
	cout << "R = " << endl <<" " << R << endl << endl;
	system("pause");
	return 0;
}

//output
int main(int argc,char** argv)
{
	//2D Point
	Point2f P(5,1);
	cout << "Point (2D) = " << P << endl << endl;

	//3D Point
	Point3f P3f(2,6,7);
	cout << "Point (3D) = " << P3f << endl << endl;

	//std::vector via cv::Mat
	vector<float> v;
	v.push_back((float)CV_PI);
	v.push_back(2);
	v.push_back(3.01f);
	cout << "Vector of float via Mat = " << Mat(v) << endl << endl;

	//std::vector of points
	vector<Point2f> vPoints(20);
	for(size_t i = 0;i < vPoints.size();i++)
		vPoints[i] = Point2f((float)(i*5),(float)(i % 7));
	cout << "A vector of 2D Points = " << vPoints << endl << endl;
	system("pause");
	return 0;
}

下面代码是对Mat矩阵的一些基本操作函数的测试:

#include <iostream>
#include <vector>
#include "cv.h"
#include "highgui.h"
#include <math.h>

using namespace std;
using namespace cv;

int main(int argc,char** argv)
{
	//Mat M1(3,3,CV_8UC1,Scalar(1));
	Mat M1 = Mat::eye(3,3,CV_8U);
	cout << "M1 = " << M1 << endl<< endl;

	Mat M2 = (Mat_<int>(3,3) << 8,1,6,3,5,7,4,9,2);  //data type is not compatible
	M2.convertTo(M2,CV_8U);  //convert to the same data type
	//Mat M2;
	//M2.create(3,3,CV_8U);
	cout << "M2 = " << M2 << endl << endl;
	
	//matrix add
	Mat mAdd;
	//mAdd = M1 + M2;
	add(M1,M2,mAdd);
	cout << "mAdd = " << mAdd << endl << endl;

	//matrix subtraction
	Mat mSub,absSub;
	absdiff(M1,M2,absSub);  //|M1 - M2|
	cout << "absSub = " << absSub << endl << endl;
	//mSub = M2 - M1;
	subtract(M2,M1,mSub);  //M2 - M1
	cout << "mSub = " << mSub << endl << endl;

	//matrix multiply
	Mat dotMulti,crossMulti(3,3,CV_8UC3,Scalar::all(0));
	dotMulti = M2.mul(M1);  //dot multiply
	cout << "dotMulti = " << dotMulti << endl<< endl;
	//crossMulti = M3.cross(M4);	//cross multiply
	//cout << "crossMulti = " << crossMulti << endl<< endl;

	//matrix divide
	Mat mDiv;
	//divide(I1,I2,dst,scale,int dtype=-1); //dst=saturate_cast(I1*scale/I2);
	divide(mSub,absSub,mDiv,1);  //dot divide
	cout << "mDiv = " << mDiv << endl<< endl;

	//matrix transpose
	Mat transM;
	transM = M2.t();
	cout << "transM = " << transM << endl<< endl;

	//matrix flip
	Mat flipM;
	//flip(I,dst,int flipCode);	//flipCode = 0是上下翻转,>0时左右翻转,<0时上下左右翻转
	flip(transM,flipM,0);
	cout << "flipM = " << flipM << endl<< endl;

	//matrix pow
	Mat powM;
	pow(M2,2,powM);
	cout << "powM = " << powM << endl<< endl;

	//matrix bit - not
	Mat bitM;
	bitwise_not(M2,bitM);  //取反
	cout << "bitM = " << bitM << endl<< endl;

	//matrix range
	Mat rMat = M2(Range::all(),Range(0,2));  //用矩阵M2初始化rMat,使用M2的所有行,0,1列,注意右端是开区间
	cout << "rMat = " << rMat << endl<< endl;

	//matrix setTo
	Mat setM;
	setM = rMat.setTo(Scalar::all(0));
	cout << "setM = " << setM << endl<< endl;

	//uchar a = M2.ptr<uchar>(1)[1];
	uchar a = M2.at<uchar>(1,1);  //得不到值?? why?
	cout << "a = " << a << endl;

	system("pause");
	return 0;
}

参考博客: OpenCV的基本数据结构       OpenCV矩阵运算   

关于Mat更多细节将在后续中逐渐更新。。。







  • 0
    点赞
  • 3
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值