opencv之cv::Mat建立
阿新 • • 發佈:2019-01-02
opencv之cv::Mat建立
簡介
cv::Mat 是一個類,由兩個資料部分組成:矩陣資訊頭(包含矩陣尺寸、儲存方法、儲存地址等資訊)和一個指向儲存所有畫素值的矩陣(根據所選儲存方法的不同, 矩陣可以是不同的維數)的指標。如果在程式中傳遞影象並建立副本時,大的開銷是由矩陣造成的,而不是矩陣資訊頭。為了解決矩陣拷貝的問題,opencv中使用了引用計數機制。思路就是讓每個cv::Mat 物件都自己的資訊頭,但是共享同一個矩陣,從而拷貝矩陣只是複製矩陣資訊頭和矩陣指標,而不是賦值矩陣。
cv::Mat A, C; // 建立矩陣資訊頭 A = cv::imread(argv[1], IMREAD_COLOR); // 為矩陣分配記憶體 cv::Mat B(A); // 拷貝建構函式 C = A; // 賦值運算子
注:矩陣A, B, C擁有自己獨特的矩陣資訊頭,但是都指向同一個矩陣。
通過引用計數機制,當計數值為零時,矩陣會自動釋放記憶體
- 拷貝cv::Mat
cv::Mat F = A.clone();
cv::Mat G;
A.copyTo(G);
- Output image allocation for OpenCV functions is automatic (unless specified otherwise).
- You do not need to think about memory management with OpenCVs C++ interface.
- The assignment operator and the copy constructor only copies the header.
- The underlying matrix of an image may be copied using the cv::Mat::clone() and cv::Mat::copyTo() functions.
建立cv::Mat物件的方法
- 使用cv::Mat::Mat函式
cv::Mat matrix(2, 2, CV_8UC3, cv::Scalar(0, 0, 255)); cout << "M = " << endl << " " << M << endl << endl;
注:預先定義的通道數可以多達4個,cv::Scalar()既能用來初始化矩陣,也可以用來表示顏色。
- 使用c/c++陣列初始化
int sz[3] = {2,2,2};
cv::Mat L(3,sz, CV_8UC, cv::Scalar::all(0));
注:該方法可以用來建立二維以上的矩陣,第一個引數為矩陣的維度,第二個引數為陣列的指標,包含每個維度的尺寸。
- cv::Mat::create函式
M.create(4,4, CV_8UC2);
cout << "M = "<< endl << " " << M << endl << endl;
注:該方法不能為矩陣設定初始值,只是用於改變矩陣尺寸,為矩陣開闢新的記憶體。
- 類似Matlab的方式
cv::Mat E = cv::Mat::eye(4, 4, CV_64F);
cout << "E = " << endl << " " << E << endl << endl;
cv::Mat O = cv::Mat::ones(2, 2, CV_32F);
cout << "O = " << endl << " " << O << endl << endl;
cv::Mat Z = cv::Mat::zeros(3,3, CV_8UC1);
cout << "Z = " << endl << " " << Z << endl << endl;
- 對於小矩陣,使用逗號分隔符初始化
cv::Mat C = (cv::Mat_<double>(3,3) << 0, -1, 0, -1, 5, -1, 0, -1, 0);
cout << "C = " << endl << " " << C << endl << endl;
C = (cv::Mat_<double>({0, -1, 0, -1, 5, -1, 0, -1, 0})).reshape(3);
cout << "C = " << endl << " " << C << endl << endl;
- 為已存在的物件建立新資訊頭
cv::Mat RowClone = C.row(1).clone();
cout << "RowClone = " << endl << " " << RowClone << endl << endl;
- 為矩陣賦予隨機值
cv::Mat R = cv::Mat(3, 2, CV_8UC3);
cv::randu(R, cv::Scalar::all(0), cv::Scalar::all(255));
注:randu()
函式的第二三個引數為最小最大值。
參考
opencv Mat資料的三種標準訪問方式 - Zack888 - 部落格園
OpenCv2 學習筆記(6) Mat元素訪問和效率比較 - wanggao_1990的專欄 - CSDN部落格