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

首頁 > 學(xué)院 > 開發(fā)設(shè)計 > 正文

OpenCV學(xué)習(xí)筆記(05):Mat類詳解(二)

2019-11-10 17:09:55
字體:
供稿:網(wǎng)友

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

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

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

2.元素數(shù)據(jù)尋址

Mat類是一個n維單通道或多通道的稠密型數(shù)值陣列,可以用于存儲實數(shù)或者負(fù)數(shù)向量和矩陣(real or complex-valued vectors or matrices)、灰度圖和彩色圖(grayscale or color images )、矢量場(vector fields)等,陣列M的數(shù)據(jù)分布取決于數(shù)組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維的總大小,單位字節(jié) M.data指向存儲這列的首地址(類似于數(shù)組名) 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維包含的個數(shù),這也就意味著,二維矩陣是按行存儲(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;

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

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

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

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

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

step[1] = 6 *12 =72 字節(jié)

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

step[2] = 12字節(jié)

step1(i)表示第i維的包含的通道數(shù) 第一維,包含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成員函數(shù)at<>()訪問元素

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

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

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

(2)使用Mat的成員函數(shù)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函數(shù)也應(yīng)該知道矩陣元素的類型和通道數(shù)

(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


發(fā)表評論 共有條評論
用戶名: 密碼:
驗證碼: 匿名發(fā)表
主站蜘蛛池模板: 潼关县| 嘉禾县| 莲花县| 习水县| 民丰县| 荔波县| 昆山市| 富平县| 高邑县| 恩施市| 云龙县| 顺平县| 扎鲁特旗| 黄大仙区| 乌苏市| 武山县| 珠海市| 光泽县| 浪卡子县| 安宁市| 普安县| 嘉鱼县| 靖远县| 东方市| 长治县| 高密市| 正安县| 会东县| 溧水县| 泰州市| 武山县| 孝昌县| 四子王旗| 大英县| 西华县| 塔河县| 通山县| 上饶县| 石棉县| 汾西县| 来凤县|