我記得開始接觸OpenCV就是因為一個算法里面需要2維動態(tài)數(shù)組,那時候看core這部分也算是走馬觀花吧,隨著使用的增多,對Mat這個結(jié)構(gòu)越來越喜愛,也覺得有必要溫故而知新,于是這次再看看Mat。
Mat最大的優(yōu)勢跟STL很相似,都是對內(nèi)存進行動態(tài)的管理,不需要之前用戶手動的管理內(nèi)存,對于一些大型的開發(fā),有時候投入的lpImage內(nèi)存管理的時間甚至比關注算法實現(xiàn)的時間還要多,這顯然是不合適的。除了有些嵌入式場合必須使用c語言,我任何時候都強烈像大家推薦Mat。
Mat這個類有兩部分數(shù)據(jù)。一個是matrix header,這部分的大小是固定的,包含矩陣的大小,存儲的方式,矩陣存儲的地址等等。另一個部分是一個指向矩陣包含像素值的指針。
Mat A, C; // creates just the header partsA = imread(argv[1], CV_LOAD_IMAGE_COLOR); // here we’ll know the method used (allocate matrix)Mat B(A); // Use the copy constructorC = A; // Assignment operator
如果想建立互不影響的Mat,是真正的復制操作,需要使用函數(shù)clone()或者copyTo()。
說到數(shù)據(jù)的存儲,這一直就是一個值得關注的問題,Mat_<uchar>對應的是CV_8U,Mat_<uchar>對應的是CV_8U,Mat_<char>對應的是CV_8S,Mat_<int>對應的是CV_32S,Mat_<float>對應的是CV_32F,Mat_<double>對應的是CV_64F,對應的數(shù)據(jù)深度如下:
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 ?oating-point numbers ( -FLT_MAX..FLT_MAX, INF, NAN )
CV_64F - 64-bit ?oating-point numbers ( -DBL_MAX..DBL_MAX, INF, NAN )
這里還需要注意一個問題,很多OpenCV的函數(shù)支持的數(shù)據(jù)深度只有8位和32位的,所以要少使用CV_64F,但是vs的編譯器又會把float數(shù)據(jù)自動變成double型,有些不太爽。
還有個需要注意的問題,就是流操作符<<對于Mat的操作,僅限于Mat是2維的情況。
還有必要說一下Mat的存儲是逐行的存儲的。
再說說Mat的創(chuàng)建,方式有兩種,羅列一下:1.調(diào)用create(行,列,類型)2.Mat(行,列,類型(值))。例如:
// 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 deallocatedM.create(100,60,CV_8UC(15));
// create a 100x100x100 8-bit arrayint sz[] = {100, 100, 100};Mat bigCube(3, sz, CV_8U, Scalar::all(0));
// add the 5-th row, multiplied by 3 to the 3rd rowM.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 workMat M1 = M.col(1);M.col(7).copyTo(M1);
void process_video_frame(const unsigned char* pixels,int width, int height, int step){Mat img(height, width, CV_8UC3, pixels, step);GaussianBlur(img, img, Size(7,7), 1.5, 1.5);}
還有一種快速初始化數(shù)據(jù)的辦法,如下:
double m[3][3] = {{a, b, c}, {d, e, f}, {g, h, i}};Mat M = Mat(3, 3, CV_64F, m).inv();
如果你需要提前釋放數(shù)據(jù)的指針和內(nèi)存,可以調(diào)用release()。
對于數(shù)據(jù)的獲取,當然還是調(diào)用at<float>(3, 3)這樣的格式為最佳。其他的方法我甚少嘗試,就不敢介紹了。
最后要提的一點是關于Mat的表達式,這個也非常多,加減乘除,轉(zhuǎn)置求逆,我怎么記得我以前介紹過呢。那就不多說啦~
聯(lián)系客服