最近开始打算把OpenCV和Caffe的源码研究下,以提高自己对图像处理的理解。在代码的研究过程中使用source insight 4.0来对源码进行阅读,主要参考官方文档。对C++的类而言,每次阅读源码都首先理清类中的属性和方法及继承关系。
1,每个Mat对象的创建过程
首先每一个Mat类的属性如下:(opencv\sources\modules\core\include\opencv2\core\mat.hpp)
enum { MAGIC_VAL = 0x42FF0000, AUTO_STEP = 0, CONTINUOUS_FLAG = CV_MAT_CONT_FLAG, SUBMATRIX_FLAG = CV_SUBMAT_FLAG };
enum { MAGIC_MASK = 0xFFFF0000, TYPE_MASK = 0x00000FFF, DEPTH_MASK = 7 };
/*! includes several bit-fields:
- the magic signature
- continuity flag
- depth
- number of channels
*/
int flags;
//! the matrix dimensionality, >= 2
int dims;
//! the number of rows and columns or (-1, -1) when the matrix has more than 2 dimensions
int rows, cols;
//! pointer to the data
uchar* data;
//! helper fields used in locateROI and adjustROI
const uchar* datastart;
const uchar* dataend;
const uchar* datalimit;
//! custom allocator
MatAllocator* allocator;
//! and the standard allocator
static MatAllocator* getStdAllocator();
static MatAllocator* getDefaultAllocator();
static void setDefaultAllocator(MatAllocator* allocator);
//! interaction with UMat
UMatData* u;
MatSize size;
MatStep step;
每一个Mat对象的创建都是使用的create方法,
inline
Mat::Mat(int _rows, int _cols, int _type, const Scalar& _s)
: flags(MAGIC_VAL), dims(0), rows(0), cols(0), data(0), datastart(0), dataend(0),
datalimit(0), allocator(0), u(0), size(&rows), step(0)
{
create(_rows, _cols, _type);
*this = _s;
}
inline
void Mat::create(int _rows, int _cols, int _type)
{
_type &= TYPE_MASK;
if( dims <= 2 && rows == _rows && cols == _cols && type() == _type && data )
return;
int sz[] = {_rows, _cols};
create(2, sz, _type);
}
(opencv\sources\modules\core\src\matrix.cpp)
在此函数中需要注意的是MatAllocator和finalizeHdr函数内部的细节,可以看到Mat对象的最终内存分配是由MatAllocator的allocate创建的UMatData对象,使用finalizeHdr对对象进行初始化。
void Mat::create(int d, const int* _sizes, int _type)
{
int i;
CV_Assert(0 <= d && d <= CV_MAX_DIM && _sizes);
_type = CV_MAT_TYPE(_type);
if( data && (d == dims || (d == 1 && dims <= 2)) && _type == type() )
{
if( d == 2 && r