抱著學習的態度,閱讀opencv原始碼。我閱讀的版本是opencv2.4.8,其實2.x在思路上是很相似的。opencv自帶了詳盡的文件。其中opencv_tutorials.pdf是opencv入門文件,該文件中有大量的示例;opencv2refman.pdf是函式手冊。這兩個文件也是重要的參考資料。
本章主要內容:mat類的結構、記憶體管理、運算、_inputarray類
主要涉及檔案有:
include | opencv2 | core | core.hpp 其中有mat類定義
| mat.hpp 其中有mat類實現
| types_c.h c語言型別定義和部分函式
modules | core | src | arithm.cpp 演算法實現
| matop.cpp mat的運算
mat是opencv中最關鍵的類之一,破解mat類對把握opencv有重要作用,同時通過這部分閱讀可以了解opencv的設計理念。
另外,opencv中定義了matx(小矩陣)的結構,vec(向量)是matx的子類。他們通過_inputarray(輸入陣列)類實現相互轉換。在矩陣運算、影象處理等函式中,通過以_inputarray類為**,訪問mat或vec。mat_是mat的子類,是mat的模板化。
【core.hpp 1475-2010行】【opencv2refman.pdf 25-44頁】
/*! 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;
//! pointer to the reference counter;
// when matrix points to user-allocated data, the pointer is null
int* refcount;
//! helper fields used in locateroi and adjustroi
uchar* datastart;
uchar* dataend;
uchar* datalimit;
//! custom allocator
matallocator* allocator;
msize size;
mstep step;
(1) flag
是標記,他由五部分組成:
1、0-2位:深度,在types_c.h中深度值如下:
cv_8u
00x000
cv_8s
10x001
cv_16u
20x010
cv_16s
30x011
cv_32s
40x100
cv_32f
50x101
cv_64f
60x110
cv_usrtype1
70x111
2、3-11位:通道數減1,因為即灰度影象(1通道)時3-11位是0x000000000,彩色影象(
3通道)時3-11位是0x000000010
3、14位:mat_cont_flag,矩陣的資料儲存是否連續的標記,1表示連續,0表示不連續
4、15位:submat_flag,子矩陣標記,mat支援從大矩陣中取出子矩陣,資料沒有複製。
例如,假設mat a是3×3的矩陣
| 1 2 3 |
a = | 4 5 6 |
| 7 8 9 |
mat b = a.rowrange(1,2);//b取a的第2到3行,行號以0開始
則 b = | 4 5 6 |
| 7 8 9 |,
b的資料並沒有新增加,而是直接指向了a的資料,b的datastart和dataend表明了起止位置,rows和cols表明了尺寸。具體將在mat的記憶體管理中說明。
5、16-31位:預設的標記
magic_val,由於矩陣有很多種型別,
_inputarray**所有的資料輸入時,需要依賴這個量來判斷資料型別,
這個值就表達了該類的型別。
檢視原始碼可以知道 型別
magic_val
值sparsemat(係數矩陣)
0x42fd0000
mat0x42ff0000
cvmat
0x42420000
cvma***
0x42430000
cvsparsemat
0x42440000
cvhistogram
0x42450000
cvmemstorage
0x42890000
cvseq
0x42990000
cvset
0x42980000
iplimage
0x00000070
他們都是類或結構體的前兩個位元組(int)。iplimage來自以往的庫,他的前兩個位元組是int nsize,是結構體的大小,也就是說他的magic_val是0x00000070。
(2)dims是維度(一般是2);rows是行數;cols是列數。
(3)data指標指向了資料;refcount指標指向了乙個計數器,這個計數器記錄著多少個mat指向了同乙個data,當計數為0時,釋放data;allocator是動態記憶體申請器。
(4)step儲存了一行的寬度,完整連續的影象step.p[0]與cols相等,子矩陣的step.p[0]與原始影象的cols相等。
**注釋非常給力,以下幾行注釋清楚地表現了mat的結構:
建構函式、賦值運算、型別轉換都表現了資料轉換能力:
(1)建構函式
1、空建構函式【
1690行】
2、指定尺寸和型別【1692行】,或由scalar結構定義尺寸和型別【1696行】
3、高維【
1700行】
4、從其他mat拷貝【1704行】
5、從資料塊拷貝並指定尺寸和型別【1706行】
6、只定義乙個頭,資料指向其他mat中一部分(行列範圍、roi)【1711行】
7、從老式的cvmat、cvma***、iplimage轉換成mat【1715-1719行
】8、從新式的std::vector、cv::vec、cv::matx、2d point、3d point、comma initializer轉換成mat【1722-1731行】
(2)賦值運算
9、const mat& m從另乙個mat轉換【1740行】
10、const matexpr& expr從矩陣表示式轉換成mat【1741行】
矩陣表示式matexpr,構造了乙個運算結構,具體在mat的計算中解釋
11、const scalar& s從scalar轉換成mat,是用一種顏色將整個影象填充【1774行】
(3)資料轉換運算
11、括號運算子:擷取子矩陣【1842-1844行】
12、資料轉換:由mat轉換成老式結構cvmat、cvma***、iplimage【1846-1851行】
13、資料轉換:由mat轉換成
vector<_tp>、
vec<_tp n>、
matx<_tp m n>【1853-1855行】
OpenCV原始碼閱讀 1
開始從讀取檔案的函式說起,這裡主要有兩個函式用於讀取影象的 實際上,當我們在做數字影象處理系統的時候,主要要考慮的也是怎麼讀乙個進來。第乙個函式 cvloadimage主要是用於返回乙個iplimage 的資料結構。第二個函式 cvloadimagem主要是用於返回乙個cvmat 的資料結構。實際上...
Opencv原始碼閱讀 HogDescriptor
opencv中hog特徵提取寫在類hogdescriptor中 預設的建構函式如下 cv wraphogdescriptor winsize 64,128 blocksize 16,16 blockstride 8,8 cellsize 8,8 nbins 9 derivaperture 1 win...
Digester 1 1 原始碼閱讀
size medium 前一段時間我們閱讀了digester的最初始的版本1.0版,現在我們再看一下1.1版,看看變化 來領悟作者的重構思路。首先我們來看一下這個版本的更新 size size medium 1.增加了乙個rules介面,原來是放到digester裡面的 用乙個hashmap 的來儲...