Opencv中資料結構Mat的相關屬性

2021-08-01 03:36:56 字數 3353 閱讀 8872

the class mat represents an n-dimensional dense numerical single-channel or multi-channel array. it can be used to store real or complex-valued vectors and matrices, grayscale or color images, voxel volumes, vector fields, point clouds, tensors, histograms (though, very high-dimensional histograms may be better stored in a sparsemat ).

mat類用於表示乙個多維的單通道或者多通道的稠密陣列。它能夠用來儲存實數或附屬的向量、矩陣、灰度/彩色影象、立體元素、點雲、張量,以及直方圖(雖然高維的直方圖用sparsemat儲存比較好)。

以上摘自opencv 2.4.9的官方文件opencv2refman.pdf。

以前雖然能夠比較熟練的使用opencv,但是最近感覺其實筆者自己對opencv的最底層資料結構mat與iplimage都不怎麼熟悉…… 由於筆者比較反感總是需要管理記憶體的iplimage,所以對mat資料結構做一下學習工作還是有必要的。

官方說明文件opencv2refman.pdf中,寫出了mat的定義如下:

class cv_exports mat

;

下面筆者將從幾個方面總結mat資料結構的主要組成。

參考**:

《opencv中對mat裡面depth,dims,channels,step,data,elemsize和資料位址計算的理解 》

《opencv mat的常見屬性》

《opencv學習筆記(四十)——再談opencv資料結構mat詳解》

參考文件:

《opencv2refman.pdf》

如上面的mat定義原始碼,mat類中有很多重要的資料型別成員。

下面進行簡單的列舉。

把這四個資料成員放在一起,是因為這四個資料成員相互之間有關係。

資料的儲存一直都是個值得關注的問題,所以資料元素儲存的位數和範圍就十分重要了。depth就體現了每乙個畫素的位數,即深度。

mat中包含的影象深度如下所示:

另外還需要注意:大部分opencv的函式支援的資料深度只有8位和32位,所以盡量使用cv_64f。

channels表示了矩陣擁有的通道數量,這個比較容易理解:

type表示矩陣中元素的型別(depth)與矩陣的通道個數(channels),可以理解成上面的depth與channels的綜合說明。type是一系列預定義的常量,命名規則如下:

cv_+位數+資料型別+通道數

具體有如下值:

資料型別12

34cv_8ucv_8uc1

cv_8uc2

cv_8uc3

cv_8uc4

cv_8scv_8sc1

cv_8sc2

cv_8sc3

cv_8sc4

cv_16ucv_16uc1

cv_16uc2

cv_16uc3

cv_16uc4

cv_16scv_16sc1

cv_16sc2

cv_16sc3

cv_16sc4

cv_32scv_32sc1

cv_32sc2

cv_32sc3

cv_32sc4

cv_32fcv_32fc1

cv_32fc2

cv_32fc3

cv_32fc4

cv_64fcv_64fc1

cv_64fc2

cv_64fc3

cv_64fc4

**中,行代表了通道數量channels,列代表了影象深度depth。

例如cv_8uc3,可以拆分為:

注:type一般是在建立mat物件時設定,若要去的mat的元素型別,可以不使用type,使用depth。

elemsize表示了矩陣中每乙個元素的資料大小,單位是位元組。公式如下:

elemsize = channels * depth / 8

例如type == cv_16sc3,則elemsize = 3 * 16 / 8 = 6 bytes。

elemsize1表示了矩陣元素的乙個通道占用的資料大小,單位是位元組。公式如下:

elemsize = depth / 8

例如type == cv_16sc3,則elemsize1 = 16 / 8 = 2 bytes。

使用opencv處理影象時,最普遍的處理方式便是遍歷影象,即訪問所有的影象畫素點。但有的演算法還需要訪問目標畫素的鄰域,所以這時候就需要了解訪問mat資料元素位址的方式。ad

dr(m

i0,i

1,..

.im−

1)=m

.dat

a+m.

step

[0]∗

i0+m

.ste

p[1]

∗i1+

...+

m.st

ep[m

.dim

s−1]

∗imd

ims−

1 如果是二維陣列,則上述公式就簡化成: ad

dr(m

i,j)

=m.d

ata+

m.st

ep[0

]∗i+

m.st

ep[1

]∗j

注:式中m = m.dims,即矩陣的維度。

假設存在乙個二維矩陣如下圖所示:

上面是乙個3 × 4的矩陣。此時我們按照資料型別為cv_8u, cv_8uc3的情況,分別對其進行討論。

首先假設其資料型別為cv_8u,也就是單通道的uchar型別,則可以得出上面的資料成員情況分別為:

若假設其資料型別為cv_8uc3,也就是三通道的uchar型別,則可以得出上面的資料成員情況分別為:

假設存在乙個三維矩陣如下圖所示:

上面是乙個3 × 4 × 6的矩陣。假設其資料型別為cv_16sc4,此時對其進行討論。

關於opencv位址訪問方法及效率的部分,請見筆者的博文《opencv畫素點鄰域遍歷效率比較,以及訪問畫素點的幾種方法 》。

OpenCV中Mat資料結構使用舉例

mat mtx img1 iplimage mat,新的mat型別與原來的iplimage型別共享影象資料,轉換只是建立乙個mat矩陣頭 or mat mtx img1 cvmat oldmat mtx mat cvmat 只是建立矩陣頭,而沒有複製資料,oldmat不用手動釋放 cv assert...

OpenCV中Mat資料結構使用舉例

mat mtx img1 iplimage mat,新的mat型別與原來的iplimage型別共享影象資料,轉換只是建立乙個mat矩陣頭 or mat mtx img1 cvmat oldmat mtx mat cvmat 只是建立矩陣頭,而沒有複製資料,oldmat不用手動釋放 cv assert...

再談OpenCV資料結構Mat詳解

我記得開始接觸opencv就是因為乙個演算法裡面需要2維動態陣列,那時候看core這部分也算是走馬觀花吧,隨著使用的增多,對mat這個結構越來越喜愛,也覺得有必要溫故而知新,於是這次再看看mat。mat最大的優勢跟stl很相似,都是對記憶體進行動態的管理,不需要之前使用者手動的管理記憶體,對於一些大...