**:
我記得開始接觸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 )這裡還需要注意乙個問題,很多opencv的函式支援的資料深度只有8位和32位的,所以要少使用cv_64f,但是vs的編譯器又會把float資料自動變成double型,有些不太爽。• 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 )
還有個需要注意的問題,就是流操作符《對於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很相似,都是對記憶體進行動態的管理,不需要之前使用者手動的管理記憶體,對於一些大...