一、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更多细节将在后续中逐渐更新。。。