1. 程式人生 > >opencv之cv::Mat建立

opencv之cv::Mat建立

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部落格