Mat - 基本圖像容器
Mat A, C; // 只創建信息頭部分
A = imread(argv[1], CV_LOAD_IMAGE_COLOR); // 這裏爲矩陣開闢內存
Mat B(A); // 使用拷貝構造函數
C = A;
以上代碼中的所有Mat對象最終都指向同一個也是唯一一個數據矩陣。雖然它們的信息頭不同,但通過任何一個對象所做的改變也會影響其它對象。實際上,不同的對象只是訪問相同數據的不同途徑而已。這裏還要提及一個比較棒的功能:你可以創建只引用部分數據的信息頭。比如想要創建一個感興趣區域( ROI ),你只需要創建包含邊界信息的信息頭:Mat D (A, Rect(10, 10, 100, 100) ); // using a rectangle
Mat E = A(Range:all(), Range(1,3)); // using row and column boundaries
Mat F = A.clone();
Mat G;
A.copyTo(G);
總結一下,你需要記住的:
- OpenCV函數中輸出圖像的內存分配是自動完成的(如果不特別指定的話)。
- 使用OpenCV的C++接口時不需要考慮內存釋放問題。
- 賦值運算符和拷貝構造函數( ctor )只拷貝信息頭。
- 使用函數 clone() 或者 copyTo() 來拷貝一副圖像的矩陣。
存儲 方法
有很多的顏色系統,各有自身優勢:
- RGB是最常見的,這是因爲人眼採用相似的工作機制,它也被顯示設備所採用。
- HSV和HLS把顏色分解成色調、飽和度和亮度/明度。這是描述顏色更自然的方式,比如可以通過拋棄最後一個元素,使算法對輸入圖像的光照條件不敏感。
- YCrCb在JPEG圖像格式中廣泛使用。
- CIE L*a*b*是一種在感知上均勻的顏色空間,它適合用來度量兩個顏色之間的 距離 。
顯式地創建一個 Mat 對象
Mat M(2,2, CV_8UC3, Scalar(0,0,255));
CV_[The number of bits per item][Signed or Unsigned][Type Prefix]C[The channel number]比如 CV_8UC3 表示使用8位的 unsigned char 型,每個像素由三個元素組成三通道。
int sz[3] = {2,2,2};
Mat L(3,sz, CV_8UC(1), Scalar::all(0));
上面的例子演示瞭如何創建一個超過兩維的矩陣:指定維數,然後傳遞一個指向一個數組的指針,這個數組包含每個維度的尺寸;其餘的相同-
爲已存在IplImage指針創建信息頭:
IplImage* img = cvLoadImage("greatwave.png", 1); Mat mtx(img); // convert IplImage* -> Mat
-
Create() function: 函數
M.create(4,4, CV_8UC(2)); cout << "M = "<< endl << " " << M << endl << endl;
- MATLAB形式的初始化方式: zeros(), ones(), :eyes() 。使用以下方式指定尺寸和數據類型:
Mat E = Mat::eye(4, 4, CV_64F);
Mat O = Mat::ones(2, 2, CV_32F);
Mat Z = Mat::zeros(3,3, CV_8UC1);
- 對於小矩陣你可以用逗號分隔的初始化函數:
Mat C = (Mat_<double>(3,3) << 0, -1, 0, -1, 5, -1, 0, -1, 0);
格式化打印
-
默認方式
cout << "R (default) = " << endl << R << endl << endl;
-
以逗號分隔的數值 (CSV)
cout << "R (csv) = " << endl << format(R,"csv" ) << endl << endl;
-
Numpy
cout << "R (numpy) = " << endl << format(R,"numpy" ) << endl << endl;
-
C語言
cout << "R (c) = " << endl << format(R,"C" ) << endl << endl;
-
2維點
Point2f P(5, 1); cout << "Point (2D) = " << P << endl << endl;
-
3維點
Point3f P3f(2, 6, 7); cout << "Point (3D) = " << P3f << endl << endl;
-
基於cv::Mat的std::vector
vector<float> v; v.push_back( (float)CV_PI); v.push_back(2); v.push_back(3.01f); cout << "Vector of floats via Mat = " << Mat(v) << endl << endl;
-
std::vector點
vector<Point2f> vPoints(20); for (size_t E = 0; E < vPoints.size(); ++E) vPoints[E] = Point2f((float)(E * 5), (float)(E % 7)); cout << "A vector of 2D Points = " << vPoints << endl << endl;