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

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

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

2019-11-09 19:22:53
字體:
供稿:網(wǎng)友

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

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

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

2.元素?cái)?shù)據(jù)尋址

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

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類中十分重要的一個(gè)屬性,表示第i維的總大小,單位字節(jié) M.data指向存儲(chǔ)這列的首地址(類似于數(shù)組名) M.dims是總維度

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

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

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

舉個(gè)例子,來說明矩陣的存儲(chǔ)方式,以及矩陣各個(gè)屬性的意義——

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)建一個(gè)3維的矩陣,尺寸為 3 * 4 * 6,那么輸出為

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

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

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

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

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

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

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

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

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

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

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

3.Mat類元素訪問方法

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

Mat的成員函數(shù)at()是一個(gè)模板函數(shù),針對(duì)不同的情況,有多個(gè)重載函數(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ù)時(shí),應(yīng)該知道矩陣元素的類型和通道數(shù),根據(jù)矩陣元素類型和通道數(shù)來確定at函數(shù)傳遞的類型,在上例當(dāng)中,我們定義的src矩陣是CV_32FC3,即3通道float型,對(duì)應(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.參考文獻(xiàn)

[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ā)表評(píng)論 共有條評(píng)論
用戶名: 密碼:
驗(yàn)證碼: 匿名發(fā)表
主站蜘蛛池模板: 东山县| 卢氏县| 洞头县| 侯马市| 肇庆市| 仁化县| 绵阳市| 萝北县| 上栗县| 攀枝花市| 余江县| 平安县| 娄烦县| 永丰县| 绩溪县| 成武县| 固始县| 阳山县| 青铜峡市| 桃园市| 渝北区| 凭祥市| 钟山县| 安国市| 宁远县| 板桥市| 商河县| 铜川市| 兴城市| 青河县| 沂南县| 巫溪县| 耿马| 三河市| 东光县| 弥渡县| 崇阳县| 黄大仙区| 龙岩市| 那曲县| 家居|