关于 Mat ,首先要知道的是你不必再手动地为其开辟空间在不需要时立即将空间释放。但手动地做还是可以的:大多数OpenCV函数仍会手动地为输出数据开辟空间。当传递一个已经存在的 Mat 对象时,开辟好的矩阵空间会被重用。也就是说,我们每次都使用大小正好的内存来完成任务。
基本上讲 Mat 是一个类,由两个数据部分组成:矩阵头(包含矩阵尺寸,存储方法,存储地址等信息)和一个指向存储所有像素值的矩阵(根据所选存储方法的不同矩阵可以是不同的维数)的指针。矩阵头的尺寸是常数值,但矩阵本身的尺寸会依图像的不同而不同,通常比矩阵头的尺寸大数个数量级。因此,当在程序中传递图像并创建拷贝时,大的开销是由矩阵造成的,而不是信息头。OpenCV是一个图像处理库,囊括了大量的图像处理函数,为了解决问题通常要使用库中的多个函数,因此在函数中传递图像是家常便饭。同时不要忘了我们正在讨论的是计算量很大的图像处理算法,因此,除非万不得已,我们不应该拷贝 大 的图像,因为这会降低程序速度。
为了搞定这个问题,OpenCV使用引用计数机制。其思路是让每个 Mat 对象有自己的信息头,但共享同一个矩阵。这通过让矩阵指针指向同一地址而实现。而拷贝构造函数则 只拷贝信息头和矩阵指针 ,而不拷贝矩阵。
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 |
// 梁笔记 // https://zouzhongliang.com/ #include <iostream> #include <opencv2/opencv.hpp>//opencv的头文件 using namespace std; using namespace cv; int main() { //Mat(); Mat img; cout << img.size() << endl; cout << img << endl; cout << "\n"; //Mat(int rows, int cols, int type); Mat img1(3,2, CV_8UC1); cout << img1.size() << endl; cout << img1 << endl; cout << "\n"; //Mat(Size size, int type); Mat img2(Size(3, 4), CV_8UC1); cout << img2.size() << endl; cout << img2 << endl; cout << "\n"; //Mat(int rows, int cols, int type, const Scalar & s); Mat img3(3,5, CV_8UC3,Scalar(128,255,0)); cout << img3.size() << endl; cout << img3 << endl; cout << "\n"; //Mat(Size size, int type, const Scalar & s); Mat img4(Size(3, 5), CV_8UC3, Scalar(128, 255, 0)); cout << img4.size() << endl; cout << img4 << endl; cout << "\n"; //Mat(const Mat& m); Mat img5(img4); cout << img5.size() << endl; cout << img5 << endl; cout << "\n"; //Mat(int rows, int cols, int type, void* data, size_t step = AUTO_STEP); uchar data[8] = { 0,1,2,3,4,5,6,7 }; Mat img6(2,4, CV_8UC1, (void*)data); cout << img6.size() << endl; cout << img6 << endl; cout << "\n"; return 0; } |
Opencv Mat构造函数运用测试结果:
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 |
[0 x 0] [] [2 x 3] [205, 205; 205, 205; 205, 205] [3 x 4] [205, 205, 205; 205, 205, 205; 205, 205, 205; 205, 205, 205] [5 x 3] [128, 255, 0, 128, 255, 0, 128, 255, 0, 128, 255, 0, 128, 255, 0; 128, 255, 0, 128, 255, 0, 128, 255, 0, 128, 255, 0, 128, 255, 0; 128, 255, 0, 128, 255, 0, 128, 255, 0, 128, 255, 0, 128, 255, 0] [3 x 5] [128, 255, 0, 128, 255, 0, 128, 255, 0; 128, 255, 0, 128, 255, 0, 128, 255, 0; 128, 255, 0, 128, 255, 0, 128, 255, 0; 128, 255, 0, 128, 255, 0, 128, 255, 0; 128, 255, 0, 128, 255, 0, 128, 255, 0] [3 x 5] [128, 255, 0, 128, 255, 0, 128, 255, 0; 128, 255, 0, 128, 255, 0, 128, 255, 0; 128, 255, 0, 128, 255, 0, 128, 255, 0; 128, 255, 0, 128, 255, 0, 128, 255, 0; 128, 255, 0, 128, 255, 0, 128, 255, 0] [4 x 2] [ 0, 1, 2, 3; 4, 5, 6, 7] |