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博客