关于MAT


在对图像进行处理时,首先需要将图像载入到内存中,而Mat就是图像在内存中的容器,管理着图像在内存中的数据。
Mat是C++ 的一个类,由于OpenCV2中引入了内存自动管理机制,所以不必手动的为Mat开辟内存空间以及手动的释放内存。
Mat中包含的数据主要由两个部分构成

1.矩阵头(矩阵尺寸、存储方法、存储地址等信息)(大小固定)
2.一个指向存储图像所有像素值的矩阵(根据所选的存储方法不同的矩阵可以是不同的维数)的指针

在图像处理中,对图像的处理不可能是在一个函数中完成的,这就需要在不同的函数间传递Mat
同时,图像处理的计算量是很大,除非万不得已就不要去传递比较大的Mat。这就要求使用某种机制来实现Mat的快速传递
Mat中主要有矩阵头和一个指向矩阵的指针,矩阵头是一个常数值,但是矩阵保存了图像所有的像素值,通常会比矩阵头大几个数量级,因此传递Mat是主要的消耗是在矩阵复制上


为了解决这个问题,OpenCV中引入了计数机制
每个Mat都有自己的信息头,但是共享同一个矩阵,也就是在传递Mat时,只复制矩阵头和指向矩阵的指针。

   1:      Mat a,c ; 
   2:      a = imread("d:\\test.jpg",1) ;
   3:      Mat b(a) ; //拷贝构造函数
   4:      a = c ; //复制运算符
 
 
上面代码中3个Mat对象a,b,c指向同一个矩阵,由于都指向了同一个矩阵某一个对象对矩阵进行操作时也会影响到其他对象读取到的矩阵
多个对象同时使用一个矩阵,那么当不需要该矩阵时, 谁来负责清理 ?   
简单的回答是,最后一个使用它的对象
通过引用计数机制,无论什么时候Mat对象的信息头被复制了,都会增加矩阵的引用次数加1;
反之,当一个Mat的信息头被释放后,引用计数就会被减1;当计数被减到0时,矩阵就会被释放。
有些时候还是需要拷贝矩阵本身的,这时候可以使用clonecopyTo

通过clone和copyTo创建的Mat,都有自己的矩阵,修改其中一个的矩阵不会对其他的造成影响。








mat的数据存储


Mat_<uchar>对应的是CV_8U,
Mat_<char>对应的是CV_8S,
Mat_<int>对应的是CV_32S,
Mat_<uint>对应的是CV_32U,
Mat_<float>对应的是CV_32F,
Mat_<double>对应的是CV_64F

这里还需要注意一个问题,很多OpenCV的函数支持的数据深度只有8位和32位的,
所以要少使用CV_64F,但是vs的编译器又会把float数据自动变成double型,有些不太爽。
还有个需要注意的问题,就是流操作符<<对于Mat的操作,仅限于Mat是2维的情况。

Mat的存储是逐行的存储的。


Mat的创建

方式有两种:

1.Mat(行,列,类型(值))
2. 调用create(行,列,类型)
// make a 7x7 complex matrix filled with 1+3j.
1. Mat M(7,7,CV_32FC2,Scalar(1,3));
// and now turn M to a 100x60 15-channel 8-bit matrix.
 2. M.create(100,60,CV_8UC(15));  // C代表channel通道数

要是想创建更高维的矩阵,要写成下面的方式:
int sz[] = {100, 100, 100}; 
Mat bigCube(3, sz, CV_8U, Scalar::all(0));  



 
 
 
GitHub 加速计划 / opencv31 / opencv
142
15
下载
OpenCV: 开源计算机视觉库
最近提交(Master分支:3 个月前 )
d9a139f9 Animated WebP Support #25608 related issues #24855 #22569 ### Pull Request Readiness Checklist See details at https://github.com/opencv/opencv/wiki/How_to_contribute#making-a-good-pull-request - [x] I agree to contribute to the project under Apache 2 License. - [x] To the best of my knowledge, the proposed patch is not based on a code under GPL or another license that is incompatible with OpenCV - [x] The PR is proposed to the proper branch - [x] There is a reference to the original bug report and related work - [ ] There is accuracy test, performance test and test data in opencv_extra repository, if applicable Patch to opencv_extra has the same branch name. - [ ] The feature is well documented and sample code can be built with the project CMake 1 天前
09030615 V4l default image size #25500 Added ability to set default image width and height for V4L capture. This is required for cameras that does not support 640x480 resolution because otherwise V4L capture cannot be opened and failed with "Pixel format of incoming image is unsupported by OpenCV" and then with "can't open camera by index" message. Because of the videoio architecture it is not possible to insert actions between CvCaptureCAM_V4L::CvCaptureCAM_V4L and CvCaptureCAM_V4L::open so the only way I found is to use environment variables to preselect the resolution. Related bug report is [#25499](https://github.com/opencv/opencv/issues/25499) Maybe (but not confirmed) this is also related to [#24551](https://github.com/opencv/opencv/issues/24551) This fix was made and verified in my local environment: capture board AVMATRIX VC42, Ubuntu 20, NVidia Jetson Orin. ### Pull Request Readiness Checklist See details at https://github.com/opencv/opencv/wiki/How_to_contribute#making-a-good-pull-request - [X] I agree to contribute to the project under Apache 2 License. - [X] To the best of my knowledge, the proposed patch is not based on a code under GPL or another license that is incompatible with OpenCV - [X] The PR is proposed to the proper branch - [X] There is a reference to the original bug report and related work - [ ] There is accuracy test, performance test and test data in opencv_extra repository, if applicable Patch to opencv_extra has the same branch name. - [ ] The feature is well documented and sample code can be built with the project CMake 1 天前
Logo

旨在为数千万中国开发者提供一个无缝且高效的云端环境,以支持学习、使用和贡献开源项目。

更多推荐