OpenCV學習再談OpenCV資料結構Mat

2021-06-25 22:55:59 字數 3253 閱讀 4706

**:

我記得開始接觸opencv就是因為乙個演算法裡面需要2維動態陣列,那時候看core這部分也算是走馬觀花吧,隨著使用的增多,對mat這個結構越來越喜愛,也覺得有必要溫故而知新,於是這次再看看mat。

mat最大的優勢跟stl很相似,都是對記憶體進行動態的管理,不需要之前使用者手動的管理記憶體,對於一些大型的開發,有時候投入的lpimage記憶體管理的時間甚至比關注演算法實現的時間還要多,這顯然是不合適的。除了有些嵌入式場合必須使用c語言,我任何時候都強烈像大家推薦mat。

mat這個類有兩部分資料。乙個是matrix header,這部分的大小是固定的,包含矩陣的大小,儲存的方式,矩陣儲存的位址等等。另乙個部分是乙個指向矩陣包含畫素值的指標。

view plain

mat a, c; 

// creates just the header parts

a = imread(argv[1], cv_load_image_color); 

// here we』ll know the method used (allocate matrix)

mat b(a); 

// use the copy constructor

c = a; 

// assignment operator

需要注意的是,

copy這樣的操作只是copy了矩陣的matrix header和那個指標,而不是矩陣的本身,也就意味著兩個矩陣的資料指標指向的是同乙個位址,需要開發者格外注意。比如上面這段程式,a、b、c指向的是同一塊資料,他們的header不同,但對於a的操作同樣也影響著b、c的結果。剛剛提高了記憶體自動釋放的問題,那麼當我不再使用a的時候就把記憶體釋放了,那時候再操作b和c豈不是很危險。不用擔心,opencv的大神為我們已經考慮了這個問題,是在最後乙個mat不再使用的時候才會釋放記憶體,咱們就放心用就行了。

如果想建立互不影響的mat,是真正的複製操作,需要使用函式

clone()或者copyto()。

說到資料的儲存,這一直就是乙個值得關注的問題,mat_對應的是cv_8u,mat_對應的是cv_8u,mat_對應的是cv_8s,mat_對應的是cv_32s,mat_對應的是cv_32f,mat_對應的是cv_64f,對應的資料深度如下:

• cv_8u - 8-bit unsigned integers ( 0..255 )

• cv_8s - 8-bit signed integers ( -128..127 )

• cv_16u - 16-bit unsigned integers ( 0..65535 )

• cv_16s - 16-bit signed integers ( -32768..32767 )

• cv_32s - 32-bit signed integers ( -2147483648..2147483647 )

• cv_32f - 32-bit floating-point numbers ( -flt_max..flt_max, inf, nan )

• cv_64f - 64-bit floating-point numbers ( -dbl_max..dbl_max, inf, nan )

這裡還需要注意乙個問題,很多opencv的函式支援的資料深度只有8位和32位的,所以要少使用cv_64f,但是vs的編譯器又會把float資料自動變成double型,有些不太爽。

還有個需要注意的問題,就是流操作符《對於mat的操作,僅限於mat是2維的情況。

還有必要說一下mat的儲存是逐行的儲存的。

再說說mat的建立,方式有兩種,羅列一下:1.呼叫create(行,列,型別)2.mat(行,列,型別(值))。例如:

view plain

// make a 7x7 complex matrix filled with 1+3j.

mat m(7,7,cv_32fc2,scalar(1,3)); 

// and now turn m to a 100x60 15-channel 8-bit matrix.

// the old content will be deallocated

m.create(100,60,cv_8uc(15)); 

要是想建立更高維的矩陣,要寫成下面的方式

view plain

// create a 100x100x100 8-bit array

intsz = ; 

mat bigcube(3, sz, cv_8u, scalar::all(0)); 

對於矩陣的行操作或者列操作,方式如下:(

注意對列操作時要新建乙個mat,我想應該跟列位址不連續有關)

view plain

// add the 5-th row, multiplied by 3 to the 3rd row

m.row(3) = m.row(3) + m.row(5)*3; 

// now copy the 7-th column to the 1-st column

// m.col(1) = m.col(7); // this will not work

mat m1 = m.col(1); 

m.col(7).copyto(m1); 

下面的東西就比較狂暴了,

對於外來的資料,比如你從別的地方接受了一幅,但可以不是mat結構的,而只有乙個資料的指標,看看接下來的**是如何應付的,重點哦,親

view plain

void

process_video_frame(

const

unsigned 

char

* pixels, 

intwidth, 

intheight, 

intstep)  

親,有木有很簡單!!!

還有一種快速初始化資料的辦法,如下:

view plain

double

m[3][3] = , , }; 

mat m = mat(3, 3, cv_64f, m).inv(); 

也可以把原來的iplimage格式的直接用mat(iplimage)的方式轉成mat結構,也可以像matlab一樣呼叫zeros()、ones()、eye()這樣的函式進行初始化。

如果你需要提前釋放資料的指標和記憶體,可以呼叫release()。

對於資料的獲取,當然還是呼叫at(3, 3)這樣的格式為最佳。其他的方法我甚少嘗試,就不敢介紹了。

最後要提的一點是關於mat的表示式,這個也非常多,加減乘除,轉置求逆,我怎麼記得我以前介紹過呢。那就不多說啦~

OpenCV第一發 測試VS配置OpenCV

最近看到網上的視覺處理特別有意思,作為乙個甚至是計算機的門外漢來說直接學習第三方庫是很困難的,悔恨當初沒有去學計算機專業,哈哈哈哈哈哈哈哈哈,沒辦法了,為了對得起我的好奇心,我決定開始攻克它。第四步 開幹.配置環境變數,我的目錄是 e opencv build bin c 新增庫檔案目錄,我的目錄是...

再談PN學習

分類 cv相關 2012 06 09 09 35 6780人閱讀 收藏 舉報演算法c 之前翻譯過一篇pn學習的文章 但該文章的內容還是略顯生澀,不太容易理解。尤其是在tld跟蹤演算法中,pn學習又是乙個很重要的模組。如果不能很好理解該部分,是很難完全掌握tld演算法精髓的。所以,這裡我在上次翻譯的基...

再談OpenCV資料結構Mat詳解

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