【Opencv 源码剖析】 一、 create函数

1.

inline Mat::Mat(int _rows, int _cols, int _type) : size(&rows)
{
    initEmpty();//将data、cols、rows等初始化为0
    create(_rows, _cols, _type);
}

2.

inline Mat::Mat(int _rows, int _cols, int _type, const Scalar& _s) : size(&rows)
{
    initEmpty();
    create(_rows, _cols, _type);
    *this = _s;//给矩阵像素赋值为_s
}

3.

inline void Mat::create(int _rows, int _cols, int _type)
{
_type &= TYPE_MASK;
if( dims <= 2 && rows == _rows && cols == _cols && type() == _type && data ) //如果cols rows data已经存在,则返回,什么都不用做
return;
int sz[] = {_rows, _cols};
create(2, sz, _type);
}

4.

void Mat::create(int d, const int* _sizes, int _type)
{
    int i;
    CV_Assert(0 <= d && _sizes && d <= CV_MAX_DIM && _sizes);
    _type = CV_MAT_TYPE(_type);

    if( data && (d == dims || (d == 1 && dims <= 2)) && _type == type() )
    {
        if( d == 2 && rows == _sizes[0] && cols == _sizes[1] )
            return;
        for( i = 0; i < d; i++ )
            if( size[i] != _sizes[i] )
                break;
        if( i == d && (d > 1 || size[1] == 1))
            return;
    }

    release();
    if( d == 0 )
        return;
    flags = (_type & CV_MAT_TYPE_MASK) | MAGIC_VAL;
    setSize(*this, d, _sizes, 0, true);  

    if( total() > 0 )
    {
#ifdef HAVE_TGPU
        if( !allocator || allocator == tegra::getAllocator() ) allocator = tegra::getAllocator(d, _sizes, _type);
#endif
        if( !allocator )//如果没有分配内存,则去分配, 否则则用allocate 把指针指向data就行了,不用重复分配
        {
            size_t totalsize = alignSize(step.p[0]*size.p[0], (int)sizeof(*refcount));
            data = datastart = (uchar*)fastMalloc(totalsize + (int)sizeof(*refcount));
            refcount = (int*)(data + totalsize);
            *refcount = 1;  //引用计数
        }
        else
        {
#ifdef HAVE_TGPU
           try
            {
                allocator->allocate(dims, size, _type, refcount, datastart, data, step.p);
                CV_Assert( step[dims-1] == (size_t)CV_ELEM_SIZE(flags) );
            }catch(...)
            {
                allocator = 0;
                size_t totalSize = alignSize(step.p[0]*size.p[0], (int)sizeof(*refcount));
                data = datastart = (uchar*)fastMalloc(totalSize + (int)sizeof(*refcount));
                refcount = (int*)(data + totalSize);
                *refcount = 1;
            }
#else
            allocator->allocate(dims, size, _type, refcount, datastart, data, step.p);
            CV_Assert( step[dims-1] == (size_t)CV_ELEM_SIZE(flags) );
#endif
        }
    }

    finalizeHdr(*this);
}

Mat 的拷贝构造函数

inline Mat::Mat(const Mat& m)
    : flags(m.flags), dims(m.dims), rows(m.rows), cols(m.cols), data(m.data),
    refcount(m.refcount), datastart(m.datastart), dataend(m.dataend),
    datalimit(m.datalimit), allocator(m.allocator), size(&rows)
{
    if( refcount )
        CV_XADD(refcount, 1);
    if( m.dims <= 2 )
    {
        step[0] = m.step[0]; step[1] = m.step[1];
    }
    else
    {
        dims = 0;
        copySize(m);
    }
}
原文地址:https://www.cnblogs.com/luoyinjie/p/8257390.html