【Opencv】Mat基础
1.Mat::imread()
C++: Mat imread(const string& filename, int flags=1 )
filename – Name of file to be loaded.
flags –
Flags specifying the color type of a loaded image:
- CV_LOAD_IMAGE_ANYDEPTH - If set, return 16-bit/32-bit image when the input has the corresponding depth, otherwise convert it to 8-bit.
- CV_LOAD_IMAGE_COLOR - If set, always convert image to the color one
- CV_LOAD_IMAGE_GRAYSCALE - If set, always convert image to the grayscale one
- >0 Return a 3-channel color image.
- Note In the current implementation the alpha channel, if any, is stripped from the output image. Use negative value if you need the alpha channel.
- =0 Return a grayscale image.
- <0 Return the loaded image as is (with alpha channel).
- 2.Mat::create()
P36 “使用输入输出函数”一节中,提到的“额外的复制操作可以通过一种实现技巧来避免”,额外的复制操作是指:Mat imageClone = image.clone();
这里不是说不需要复制,而是说不需要显式的分配一个同等大小的数组内存,我们可以利用Mat::create成员函数,加入我们定义一个Mat copy,此时copy一定不会和image同等大小(copy为空),那么create就会为copy分配与image同等大小的数组,为什么要这样做呢?文中提到这样做可以使用户决定是否采用in-place操作,采用in-place操作,势必会改变原图像,而当我们输入输出都制定为image时,create函数将会直接返回。此时函数中image1(形参image)和image2(形参result)都引用了同一个变量image,指向同一块内存地址,而image1为常量引用,image2为普通引用,虽然不能通过image1进行in-place操作(const引用无法更改变量值),但我们可以通过image2来进行in-place操作。(假如a常量引用b,c普通引用b,a不能更改b但是不代表所有b的引用都不能,c就可以改变b的值)
Mat::create() create()函数只在当前数组大小或者类型与指定的不一样时才分配新的数组。
Allocates new array data if needed.
C++: void Mat::create(int rows, int cols, int type)
C++: void Mat::create(Size size, int type)
C++: void Mat::create(int ndims, const int* sizes, int type)
Parameters:
- ndims – New array dimensionality.
- rows – New number of rows.
- cols – New number of columns.
- size – Alternative new matrix size specification: Size(cols, rows)
- sizes – Array of integers specifying a new array shape.
- type – New matrix type.
This is one of the key Mat methods. Most new-style OpenCV functions and methods that produce arrays call this method for each output array. The method uses the following algorithm:
- If the current array shape and the type match the new ones, return immediately. Otherwise, de-reference the previous data by callingMat::release().
- Initialize the new header.
- Allocate the new data of total()*elemSize() bytes.
- Allocate the new, associated with the data, reference counter and set it to 1.
Such a scheme makes the memory management robust and efficient at the same time and helps avoid extra typing for you. This means that usually there is no need to explicitly allocate output arrays. That is, instead of writing:
Mat color; ... Mat gray(color.rows, color.cols, color.depth()); --没必要的,因为cvtColor 会帮我们先调用一个create方法。 cvtColor(color, gray, CV_BGR2GRAY); you can simply write: Mat color; ... Mat gray; cvtColor(color, gray, CV_BGR2GRAY);
because cvtColor , as well as the most of OpenCV functions, calls Mat::create() for the output array internally.