Mat_类最开始是从http://blog.csdn.net/abcjennifer/article/details/7628655这篇文章看到的.比如:Mat_<Vec3f>
先举一个例子
Mat_<Vec3f> M(3,4)等同于Mat M(3,4,CV32FU3),即Mat_<type> M(3,4)等效于Mat M(3,4,type)
这样做有什么好处呢?
答:在大多数情况下,使用cv::Mat就足够了,但是cv::Mat_会更方便在你进行大量元素的访问操作时,且在编译时你已经知道矩阵类型的情况下。
下面是opencv对于Mat_类的解释说明:
模板matrix类来源于Mat.
Mat_类是一个“瘦身”的cv::Mat类。他没有额外的数据段,不管是Mat_还是Mat类都没有虚拟方法,所以引用或指针对这两种类会很安全当从一种转换成另外一种时。但是使用时要非常小心,例如:
//创建一个100*100,8位矩阵
Mat M(100,100,CV_8U);
//这句话会编译成功。这中间没有发生任何数据转换
Mat_<float>& M1=(Mat_<float>&)M;
//这个程序很可以会崩溃在下面这句声明时
M1(99,99)=1.f;
在大多数情况下,使用cv::Mat就足够了,但是cv::Mat_会更方便在你进行大量元素的访问操作时,且在编译时你已经知道矩阵类型的情况下。
记住这些:cv::Mat::at<_Tp>(int y,int x)和cv::Mat_<_Tp>::operator()(int y,int x)做的是同样的事情,运行速度也一样,但是后者更短一些(不是指时间,应该指的是代码长度)。
Mat_<double> M(20,20);
for(int i = 0; i < M.rows; i++)
for(int j = 0; j < M.cols; j++)
M(i,j) = 1./(i+j+1);
Mat E, V;
eigen(M,E,V);
cout << E.at<double>(0,0)/E.at<double>(M.rows-1,0);
使用Mat_类用于处理多通道图像/矩阵是非常容易的,只需要把cv::Vec传递给cv::Mat_的模板参数。
//分配320*240的彩色图像,并用绿色填充(RGB空间)
Mat_<Vec3b> img(240,320,Vec3b(0,255,0));
//画一个白色对角线
for(int i=0;i<100;i++)
img(i,i)=Vec3b(255,255,255);
//修改美国元素的第二个通道
for(int i=0;i<img.rows;i++)
for(int j=0;j<img.cols;j++)
img(i,j)[2]=(uchar)(i+j); //img(y,x)[c]访问元素(x,y)的第c个通道
//英文解释
/*!
Template matrix class derived from Mat
The class Mat_ is a "thin" template wrapper on top of cv::Mat. It does not have any extra data fields,
nor it or cv::Mat have any virtual methods and thus references or pointers to these two classes
can be safely converted one to another. But do it with care, for example:
\code
// create 100x100 8-bit matrix
Mat M(100,100,CV_8U);
// this will compile fine. no any data conversion will be done.
Mat_<float>& M1 = (Mat_<float>&)M;
// the program will likely crash at the statement below
M1(99,99) = 1.f;
\endcode
While cv::Mat is sufficient in most cases, cv::Mat_ can be more convenient if you use a lot of element
access operations and if you know matrix type at compile time.
Note that cv::Mat::at<_Tp>(int y, int x) and cv::Mat_<_Tp>::operator ()(int y, int x) do absolutely the
same thing and run at the same speed, but the latter is certainly shorter:
\code
Mat_<double> M(20,20);
for(int i = 0; i < M.rows; i++)
for(int j = 0; j < M.cols; j++)
M(i,j) = 1./(i+j+1);
Mat E, V;
eigen(M,E,V);
cout << E.at<double>(0,0)/E.at<double>(M.rows-1,0);
\endcode
It is easy to use Mat_ for multi-channel images/matrices - just pass cv::Vec as cv::Mat_ template parameter:
\code
// allocate 320x240 color image and fill it with green (in RGB space)
Mat_<Vec3b> img(240, 320, Vec3b(0,255,0));
// now draw a diagonal white line
for(int i = 0; i < 100; i++)
img(i,i)=Vec3b(255,255,255);
// and now modify the 2nd (red) channel of each pixel
for(int i = 0; i < img.rows; i++)
for(int j = 0; j < img.cols; j++)
img(i,j)[2] ^= (uchar)(i ^ j); // img(y,x)[c] accesses c-th channel of the pixel (x,y)
\endcode
//Mat_类的构造函数
Mat_();
//! equivalent to Mat(_rows, _cols, DataType<_Tp>::type)
Mat_(int _rows, int _cols);
//! constructor that sets each matrix element to specified value
Mat_(int _rows, int _cols, const _Tp& value);
//! equivalent to Mat(_size, DataType<_Tp>::type)
explicit Mat_(Size _size);
//! constructor that sets each matrix element to specified value
Mat_(Size _size, const _Tp& value);
//! n-dim array constructor
Mat_(int _ndims, const int* _sizes);
//! n-dim array constructor that sets each matrix element to specified value
Mat_(int _ndims, const int* _sizes, const _Tp& value);
//! copy/conversion contructor. If m is of different type, it's converted
Mat_(const Mat& m);
//! copy constructor
Mat_(const Mat_& m);