OpenCV C++ n-dimensional dense array class The class "Mat" represents an n-dimensional dense numerical single-channel or multi-channel array. It can be used to store real or complex-valued vectors
and matrices, grayscale or color images, voxel volumes, vector fields, point clouds, tensors, histograms (though, very high-dimensional histograms may be better stored in a "SparseMat"). The data layout of the array M is defined by the array "M.step[]", so
that the address of element (i_0,...,i_(M.dims-1)), where 0 <= i_k= M.step[i+1]" (in fact, "M.step[i] >= M.step[i+1]*M.size[i+1]"). This means that 2-dimensional matrices are stored row-by-row, 3-dimensional matrices are stored plane-by-plane, and so on. "M.step[M.dims-1]"
is minimal and always equal to the element size "M.elemSize()". So, the data layout in "Mat" is fully compatible with "CvMat", "IplImage", and "CvMatND" types from OpenCV 1.x. It is also compatible with the majority of dense array types from the standard toolkits
and SDKs, such as Numpy (ndarray), Win32 (independent device bitmaps), and others, that is, with any array that uses *steps* (or *strides*) to compute the position of a pixel. Due to this compatibility, it is possible to make a "Mat" header for user-allocated
data and process it in-place using OpenCV functions. There are many different ways to create a "Mat" object. The most popular options are listed below: * 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. 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 a multi-dimensional array: 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). * 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. * 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: 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()": 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: #. Process "foreign" data using OpenCV (for example, when you implement a DirectShow*
filter or a processing module for "gstreamer", and so on). For example: #. Quickly initialize small matrices and/or get a super-fast element access. 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. 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. * Use MATLAB-style array initializers, "zeros(), ones(), eye()", for example: * Use a comma-separated initializer: 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. Once the array is created,
it is automatically managed via a reference-counting mechanism. If the array header is built on top of user-allocated data, you should handle the data by yourself. The array data is deallocated when no one points to it. If you want to release the data pointed
by a array header before the array destructor is called, use "Mat.release()". The next important thing to learn about the array class is element access. This manual already described how to compute an address of each array element. Normally, you are not required
to use the formula directly in the code. If you know the array element type (which can be retrieved using the method "Mat.type()"), you can access the element M_(ij) of a 2-dimensional array as: assuming that M is a double-precision floating-point array. There
are several variants of the method "at" for a different number of dimensions. If you need to process a whole row of a 2D array, the most efficient way is to get the pointer to the row first, and then just use the plain C operator "[]" : Some operations, like
the one above, do not actually depend on the array shape. They just process elements of an array one by one (or elements from multiple arrays that have the same coordinates, for example, array addition). Such operations are called *element-wise*. It makes
sense to check whether all the input/output arrays are continuous, namely, have no gaps at the end of each row. If yes, process them as a long single row: In case of the continuous matrix, the outer loop body is executed just once. So, the overhead is smaller,
which is especially noticeable in case of small matrices. Finally, there are STL-style iterators that are smart enough to skip gaps between successive rows: The matrix iterators are random-access iterators, so they can be passed to any STL algorithm, including
"std.sort()".
Mat in OpenCV英文文档