创建Mat类的几种常见方法

来源:互联网 发布:淘宝泻油汤真相 编辑:程序博客网 时间:2024/06/06 18:03

There are many different ways to create a Mat object. The most popular options are listed below:

有许多不同的方法可以创建一个Mat对象,下面列出几个最常用的方法。

  • Use the create(nrows, ncols, type) method or the similar Mat(nrows, ncols, type, fillValue) constructor. A new array of the specified size and type is allocated. type has the same meaning as in the cvCreateMat method. For example, CV_8UC1 means a 8-bit single-channel array, CV_32FC2 means a 2-channel (complex) floating-point array, and so on.

    使用create(nrows, ncols, type)的方法或是类似的Mat(nrows, ncols, type, fillValue)的这种构造。一个新的确定大小和类型的数组就被分配好了。type与cvCreateMat方法中具有相似的意义,指定的是数组的类型(例如CV_8UC1,CV_32FC2等等)。

    // make a 7x7 complex matrix filled with 1+3j.Mat M(7,7,CV_32FC2,Scalar(1,3));// and now turn M to a 100x60 15-channel 8-bit matrix.// The old content will be deallocated 、、、这里是说,当使用create()时,原来7*7的M数组将被释放了,重新分配了一个100*60的15通道的8位数组M.create(100,60,CV_8UC(15));

    As noted in the introduction to this chapter, create() allocates only a new array when the shape or type of the current array are different from the specified ones.

    create()函数会分配一个新的数组,当目前数组的形状或类型与指定的(或之前的)不同时。

  • Create a multi-dimensional array:创建一个多维的数组

    // create a 100x100x100 8-bit arrayint sz[] = {100, 100, 100};Mat bigCube(3, sz, CV_8U, Scalar::all(0));

    It passes the number of dimensions =1 to the Mat constructor but the created array will be 2-dimensional with the number of columns set to 1. So, Mat::dims is always >= 2 (can also be 0 when the array is empty).

    它将维度数(= 1)传递给Mat的构造函数,但列数设置为 1时,创建数组将是 2 维的。因此,Mat::dims 始终是>=2的(该数组为空时,也可以是 0)。(也不是很懂啥意思)

  • Use a copy constructor or assignment operator where there can be an array or expression on the right side (see below). As noted in the introduction, the array assignment is an O(1) operation because it only copies the header and increases the reference counter. The Mat::clone() method can be used to get a full (deep) copy of the array when you need it.

    使用一个复制构造函数或者赋值操作运算符,可以生成一个数组或是表达式。数组赋值运算的复杂度是O(1),因为它仅复制数组头和增加引用计数。而Mat::clone()的方法可以获得一个全(深)的副本数组。

  • Construct a header for a part of another array. It can be a single row, single column, several rows, several columns, rectangular region in the array (called a minor in algebra) or a diagonal. Such operations are also O(1) because the new header references the same data. You can actually modify a part of the array using this feature, for example:

    构造数组中部分成分的头。它可以使一行,一列,几行,几列,一个数组中的矩形区域,或者是一个对角线。这样的操作的复杂度也是o(1),因为新构造的头指向的是相同的数据。可以使用该方法修改数组中的指定部分,例如:

    // add the 5-th row, multiplied by 3 to the 3rd row、、将第5行乘以3,加到第3行M.row(3) = M.row(3) + M.row(5)*3;// now copy the 7-th column to the 1-st column// M.col(1) = M.col(7); // this will not work先构造了一个M1的Mat头,指向M的第一列,然后将M的第7列复制给M1Mat M1 = M.col(1);M.col(7).copyTo(M1);// create a new 320x240 imageMat img(Size(320,240),CV_8UC3);// select a ROIMat roi(img, Rect(10,10,100,100)); //这个还是比较实用的,指定一幅图像的ROI区域// fill the ROI with (0,255,0) (which is green in RGB space);// the original 320x240 image will be modifiedroi = Scalar(0,255,0);

    Due to the additional datastart and dataend members, it is possible to compute a relative sub-array position in the main container array using locateROI():

    由于额外的 datastart 和 dataend 成员,使得用locateROI() 计算子数组在主容器数组中的相对位置成为可能

    Mat A = Mat::eye(10, 10, CV_32S);// extracts A columns, 1 (inclusive) to 3 (exclusive).Mat B = A(Range::all(), Range(1, 3));// extracts B rows, 5 (inclusive) to 9 (exclusive).// that is, C ~ A(Range(5, 9), Range(1, 3))Mat C = B(Range(5, 9), Range::all());Size size; Point ofs;C.locateROI(size, ofs);// size will be (width=10,height=10) and the ofs will be (x=1, y=5)

    As in case of whole matrices, if you need a deep copy, use the clone() method of the extracted sub-matrices.

  • Make a header for user-allocated data. It can be useful to do the following:

    1. Process “foreign” data using OpenCV (for example, when you implement a DirectShow* filter or a processing module for gstreamer, and so on). For example:

      OpenCV处理外来数据。

      void process_video_frame(const unsigned char* pixels,                         int width, int height, int step){    Mat img(height, width, CV_8UC3, pixels, step);    GaussianBlur(img, img, Size(7,7), 1.5, 1.5);}
    2. Quickly initialize small matrices and/or get a super-fast element access.

      快速初始化小尺寸矩阵,或者获得一个超速的元素通道。

      double m[3][3] = {{a, b, c}, {d, e, f}, {g, h, i}};Mat M = Mat(3, 3, CV_64F, m).inv();

    Partial yet very common cases of this user-allocated data case are conversions from CvMat and IplImage to Mat. For this purpose, there are special constructors taking pointers to CvMat or IplImage and the optional flag indicating whether to copy the data or not.

    讲述Mat 与 CvMat和IplImage之间的转换。

    Backward conversion from Mat to CvMat or IplImage is provided via cast operators Mat::operator CvMat()const and Mat::operator IplImage(). The operators do NOT copy the data.

    IplImage* -> Mat-> CvMat,然后比较 IplImage 与 CvMat
    IplImage* img = cvLoadImage("greatwave.jpg", 1);Mat mtx(img); // convert IplImage* -> MatCvMat oldmat = mtx; // convert Mat -> CvMatCV_Assert(oldmat.cols == img->width && oldmat.rows == img->height &&    oldmat.data.ptr == (uchar*)img->imageData && oldmat.step == img->widthStep);
  • Use MATLAB-style array initializers, zeros(), ones(), eye(), for example:

    // create a double-precision identity martix and add it to M.M += Mat::eye(M.rows, M.cols, CV_64F);//  xxx(nrows, ncols, style)
  • Use a comma-separated initializer:  使用逗号分隔的初始化

    // create a 3x3 double-precision identity matrixMat M = (Mat_<double>(3,3) << 1, 0, 0, 0, 1, 0, 0, 0, 1);

    With this approach, you first call a constructor of the Mat_ class with the proper parameters, and then you just put << operator followed by comma-separated values that can be constants, variables, expressions, and so on. Also, note the extra parentheses required to avoid compilation errors.

    使用Mat_类,然后设置类型<xxx>,之后用<<符号输入数值,每个数值之间用逗号隔开,这种方法适合于小尺寸的初始化,同时需要注意的是书写时不要忽略最外层的圆括号。

0 0
原创粉丝点击