Mat類的建構函式,解構函式:
Mat類的建構函式與解構函式太多了,真的太多了,這是可以理解的。矩陣是映像的基本資料結構,對於數位影像處理的人來說,矩陣是我們看待映像的一個重要角度,甚至是一個最主要的角度,因為,我們做的所有動作幾乎都是在矩陣的基礎之上完成的!矩陣是如此得基礎,如此得任重道遠,因此,矩陣類的實現自然不能怠慢。在具體應用上,有時我們直接聲明一個矩陣了事,比如Mat img;有時,我們又需要詳細地定義出矩陣的維度以及長、寬、資料類型等資訊:Mat img(width,height,CV_8U);這就直接導致了Mat類一個龐大的建構函式群,如下所示:
Mat::Mat() Mat::Mat(int rows, int cols, int type) Mat::Mat(Size size, int type) ..... Mat::Mat(int ndims, const int* sizes, int type, void* data, const size_t* steps=0) Mat::Mat(const Mat& m, const Range* ranges)
浩浩蕩蕩,總共20個函數,一定不要怕這些函數,到建構函式的定義部分去看,其實這些函數基本都調用了下面create函數族群:
void create(int rows, int cols, int type); void create(Size size, int type); void create(int ndims, const int* sizes, int type);
舉個例子,在建構函式Mat::Mat(int rows,int cols,int type)中:
inline Mat::Mat(Size _sz, int _type) : size(&rows){ initEmpty(); create( _sz.height, _sz.width, _type );}
所以整個Mat建構函式的精髓部分就是create函數了,再深挖一層create函數,看一下create函數是怎麼實現的,去掉create函數一些邊界條件的小細節,核心部分如下:
void Mat::create(int d, const int* _sizes, int _type)//先行再列{ if( !allocator )//如果當前矩陣沒有記憶體配置器 { //step.p[0]和size.p[0]是個值得說道的量,本Mat源碼分析的下一篇部落格會詳細分析。 //refcount部分是引用計數,C++中一個重要技術,標誌該段記憶體被引用的狀況,很能體現這是C++的OpenCV size_t totalsize = alignSize(step.p[0]*size.p[0], (int)sizeof(*refcount));(矩陣資料總空間大小,4位元組對齊) 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) ); }}
綜上,Mat建構函式部分完成Mat結構中一些成員變數的初始化,以及記憶體的分配,是中規中矩的建構函式。
本部分有必要說下alignSize這個小函數,這個函數涉及到記憶體問題,說得具體點就是記憶體位元組數量的問題。源碼如下:
/*! Aligns buffer size by the certain number of bytes This small inline function aligns a buffer size by the certian number of bytes by enlarging it.*/static inline size_t alignSize(size_t sz, int n){ return (sz + n-1) & -n;}
這種位操作函數是電腦中非常漂亮的函數,完美地利用了電腦中資料類型位元的有限性,源碼注釋中已經說明本函數功能是n位元組對齊了,簡要分析一下:alignSize中,-n就是負數啦,負數在用補碼錶示,負數的補碼是其絕對值所有位按位取反加1,所以對於本例的n=4來說,-n的位元模式是111......11100,最低兩位是0,也就是能夠達到4位元組對齊的目的,所以(sz+n-1)&-n就能夠達到了按照4位元組向上取整對齊的目的了。