国产探花免费观看_亚洲丰满少妇自慰呻吟_97日韩有码在线_资源在线日韩欧美_一区二区精品毛片,辰东完美世界有声小说,欢乐颂第一季,yy玄幻小说排行榜完本

首頁 > 學院 > 開發設計 > 正文

OpenCV學習筆記(05):Mat類詳解(二)

2019-11-09 19:10:59
字體:
來源:轉載
供稿:網友

1. 前言:Mat類的深入解讀

我在學《數據結構》的時候,每接觸一種新的ADT(abstract data type, 抽象數據類型 ),一般的套路都是這樣的—— 1.先了解ADT的結構,如何定義?包括哪些數據對象?如,線性表是n個具有相同特性的數據元素的有限序列。 2.再學習基于該ADT結構的一些操作和算法。如,線性表的增刪查改,基于順序表的排序算法; 3.最后再學習該ADT的存儲方式和實現過程。如,鏈表在計算機內存中的存儲。

那么,在了解了基本結構之后,作為OpenCV最重要的ADT——Mat類,在計算中如何存儲,以及有哪些基本操作的呢?

2.元素數據尋址

Mat類是一個n維單通道或多通道的稠密型數值陣列,可以用于存儲實數或者負數向量和矩陣(real or complex-valued vectors or matrices)、灰度圖和彩色圖(grayscale or color images )、矢量場(vector fields)等,陣列M的數據分布取決于數組M.step[],因此M陣列中元素(i0,...,iM.dims?1)的地址可以計算為:

addr(Mi0,...,iM.dims?1)=M.data+M.step[0]?i0+M.step[1]?i1+...+M.step[M.dims?1]?iM.dims?1

其中, step[i]是Mat類中十分重要的一個屬性,表示第i維的總大小,單位字節 M.data指向存儲這列的首地址(類似于數組名) M.dims是總維度

例如,二維矩陣的尋址可以表示為:

addr(Mi,j)=M.data+M.step[0]?i+M.step[1]?j

注意, M.step[i] >= M.step[i+1] ,實際上, M.step[i] >= M.step[i+1]* M.size[i+1],其中,M.size[i]表示第i維包含的個數,這也就意味著,二維矩陣是按行存儲(stored row-by-row),而三維矩陣是按面存儲(stored plane-by-plane),高維以此類推。M.size[M.dims-1]表示矩陣的最低維,大小與M.elemSize() 相等

舉個例子,來說明矩陣的存儲方式,以及矩陣各個屬性的意義——

int sizeMat[] = { 3, 4, 6 };Mat src(3, sizeMat, CV_32FC3, Scalar::all(0));cout << "src.dims = " << src.dims << endl;cout << "src.step[0] = " << src.step[0] << endl;cout << "src.step[1] = " << src.step[1] << endl;cout << "src.step[2] = " << src.step[2] << endl << endl;cout << "src.size[0] = " << src.size[0] << endl;cout << "src.size[1] = " << src.size[1] << endl;cout << "src.size[2] = " << src.size[2] << endl << endl;cout << "src.step1[0] = " << src.step1(0) << endl;cout << "src.step1[1] = " << src.step1(1) << endl;cout << "src.step1[2] = " << src.step1(2) << endl << endl;cout << "src.elemSize() = " << src.elemSize() << endl;cout << "src.elemSize1() = " << src.elemSize1() << endl;

創建一個3維的矩陣,尺寸為 3 * 4 * 6,那么輸出為

Mat類型維度是從高維度到低維度排列的,比如3維矩陣,按照面、行、點的順序對應其維度大小,我們上面所定義的矩陣包含3個面、每個面包含4行,每行包含6個點。

因此,step[0]表示第一維,面( plane),所包含總元素的字節大小

我們定義的矩陣每個面有4*6=24個點,每個點定義為CV_32FC3類型,即3通道的32位float型,一個元素包含3個float,即 3 *4=12字節,那么整個面的大小就為 24 *12 =288 字節

同理,step[1]表示第二維,行( row) ,所包含總元素的大小

step[1] = 6 *12 =72 字節

step[2]表示第三維,點( point) ,所包含總元素大小

step[2] = 12字節

step1(i)表示第i維的包含的通道數 第一維,包含4 * 6個點, 每個點都是3通道的,因此,第一維包含4 * 6 * 3 =72個通道 同理,第二維包含 18個通道,第三維包含3個通道

屬性size表示每個維度的大小,即—— 第一維大小為3,size(0) = 3 第二維為4,size(1) = 4 第三維為6,size(2) = 6

屬性elemSize表示的是每一個矩陣元素的大小,這個元素可能包含多個通道,而elemSize1表示的是每個通道下所包含基本類型的大小,即elemSize=channels * elemSize1

最后再通過一張圖來表示Mat類的尋址方式

3.Mat類元素訪問方法

(1)Mat成員函數at<>()訪問元素

Mat的成員函數at()是一個模板函數,針對不同的情況,有多個重載函數可供選擇,在這里,我們使用最常見的二維矩陣的at函數

for (int r = 0; r < src.rows; r++) { for (int c = 0; c < src.cols; c++) { cout<< src.at<Vec3f>(r,c)<<endl; } }

注意,使用at函數時,應該知道矩陣元素的類型和通道數,根據矩陣元素類型和通道數來確定at函數傳遞的類型,在上例當中,我們定義的src矩陣是CV_32FC3,即3通道float型,對應Vec3f可以兼容該類型。

(2)使用Mat的成員函數ptr<>()訪問元素

Vec3f*temp(NULL);for (int r = 0; r < src.rows; r++) { temp = src.ptr<Vec3f>(r); for (int c = 0; c < src.cols; c++) { cout<< temp[c]; } }

注意,ptr 是指向矩陣的行,同樣,使用ptr函數也應該知道矩陣元素的類型和通道數

(3)使用OpenCV迭代器

MatIterator_<Vec3b> it_src; MatIterator_<Vec3b> itEnd_src;it_src = src.begin<Vec3f>(); itEnd_src = src.end<Vec3f>(); for (; it_src != itEnd_src; it_src++) { cout<< *it_src; }

4.參考文獻

[1] https://www.douban.com/note/265479171/

[2] http://blog.csdn.net/qianqing13579/article/details/45318279

[3] http://blog.csdn.net/bendanban/article/details/30527785


發表評論 共有條評論
用戶名: 密碼:
驗證碼: 匿名發表
主站蜘蛛池模板: 沽源县| 雅安市| 即墨市| 嘉荫县| 额济纳旗| 周宁县| 滦南县| 新郑市| 延川县| 安泽县| 明水县| 同江市| 陇南市| 富平县| 霍山县| 新民市| 高州市| 靖安县| 墨玉县| 岳阳县| 五指山市| 铜鼓县| 郴州市| 炉霍县| 隆德县| 四子王旗| 文登市| 通山县| 云浮市| 中山市| 从化市| 桓台县| 临猗县| 灵石县| 十堰市| 德江县| 金秀| 吴桥县| 张家港市| 廉江市| 沁阳市|