OpenCV 3.1.0中的Mat对象使用

简介: OpenCV 3.1.0中的Mat对象使用

一: Mat介绍


        OpenCV刚出来的时候图像加载内存之后的对象是IplImage作为数据对象,里面存储了图像的像素数据和宽、高、位图深度、图像大小、通道数等基本属性。IplImage结构是C语言体系下定义出来的接口,使用它时候最大的问题是要自己负责内存管理,控制内存分配和释放,很容易导致内存问题。


        OpenCV从2.0版本开始引入Mat对象,它会自动分配和释放内存,让开发人员把精力放在图像处理问题上面,不被内存问题所困扰,Mat是一个C++的类对象,它有两个部分组成:一个矩阵头部分(包含矩阵大小、存储方法等)另外一部分是一个指针指向矩阵像素的,其中矩阵头部分是固定常量大小。但是整个矩阵的大小跟图像实际大小有关系。


        另外一个改进就是引用计数系统,对Mat对象来说,图像处理可能是一系列算法的组合,会调用多个图像处理的算法,这个时候Mat作为引用被传到各个对应的算法处理函数,除非有必要,一般情况下只会复制Mat的头和指针,不会真正复制像素数据本身。


例子如下:

Mat A, C
A = imread(argv[1], IMREAD_COLOR);
Mat B(A); // copy constructor
C = A;

上面的三个指针,虽然头部不一样,但是都指向同一个图像的像素数据矩阵。通常我们需要创建ROI区域,可以使用Mat来实现:

Mat D (A, Rect(10, 10, 100, 100));

如果想跟图像数据一起复制,OpenCV提供了两个相关的API操作:cv::Mat::clone()与cv::Mat::copyTo()。

Mat F = A.clone(); 
Mat G; A.copyTo(G);

所以关于使用Mat图像像素矩阵要记住如下四点:

1. 输出图像的内存分配是自动的

2. 使用OpenCV的C++接口,不需要考虑内存管理问题

3. 赋值操作和拷贝构造函数操作,只会复制头部分,像素数据部分仍然相同


4. 使用克隆clone和copyTo将会复制图像数据矩阵Mat



二:存储方法


这里是指存储图像像素值,它跟两个因素有关系,一个是色彩空间另外一个数据类型。常见的色彩空间包括:


RGB - 最常见的色彩空间,OpenCV标准显示都是基于RGB色彩空间


HSV/HLS - 三个通道分别为HUE、饱和度、亮度,一个常用的例子就是排出光线干扰,丢弃最后一个通道的值处理。


YCrCb - 在JPEG图像格式中比较流行使用


每一种色彩空间的每个通道值都有它自己的取值范围和应用场景。


创建一个Mat对象


cv::Mat::Mat 构造函数

Mat  M(2,2, CV_8UC3, Scalar(0,0,255));     
cout << "M = " << endl << " " << M << endl << endl;

其中前两个参数分别表示行(row)跟列(column)、第三个参数CV_8UC3中的8表示每个通道占8位、U表示无符号、C表示Char类型、3表示通道数目是3,第四个参数是个向量表示初始化每个像素值是多少,向量长度对应通道数目一致。创建多维数据:

int sz[3] = {2,2,2};     
Mat  L(3,sz, CV_8UC(1), Scalar::all(0));

上面是一个创建多维(大于2维)数组的例子,只是第二个参数不通,其它都跟第一个例子相似。

cv::Mat::create功能

M.create(4, 4, CV_8UC(2));
cout << "M = "<< endl << " "  << M << endl << endl;

这种构造函数无法初始化每个像素值。此外OpenCV还提供类似Matlab风格的初始化函数:

Mat E = Mat::eye(4, 4, CV_64F);     
cout << "E = " << endl << " " << E << endl << endl;     
 
Mat O = Mat::ones(2, 2, CV_32F);     
cout << "O = " << endl << " " << O << endl << endl;    
 
Mat Z = Mat::zeros(3,3, CV_8UC1);     
cout << "Z = " << endl << " " << Z << endl << endl;

定义小的数组,可以使用如下方式:

Mat C = (Mat_<double>(3,3) << 0, -1, 0, -1, 5, -1, 0, -1, 0);     
cout << "C = " << endl << " " << C << endl << endl;

克隆定义好的二维数组数据

Mat RowClone = C.row(1).clone();     
cout << "RowClone = " << endl << " " << RowClone << endl << endl;

参考资料:

http://docs.opencv.org/3.1.0/d6/d6d/tutorial_mat_the_basic_image_container.html

相关文章
|
7月前
|
存储 新制造 开发工具
Baumer工业相机堡盟工业相机如何联合NEOAPI SDK和OpenCV实现相机图像转换为Mat图像格式(C++)
Baumer工业相机堡盟工业相机如何联合NEOAPI SDK和OpenCV实现相机图像转换为Mat图像格式(C++)
89 2
|
2月前
|
Serverless 计算机视觉
语义分割笔记(三):通过opencv对mask图片来画分割对象的外接椭圆
这篇文章介绍了如何使用OpenCV库通过mask图像绘制分割对象的外接椭圆。首先,需要加载mask图像,然后使用`cv2.findContours()`寻找轮廓,接着用`cv2.fitEllipse()`拟合外接椭圆,最后用`cv2.ellipse()`绘制椭圆。文章提供了详细的代码示例,展示了从读取图像到显示结果的完整过程。
70 0
语义分割笔记(三):通过opencv对mask图片来画分割对象的外接椭圆
|
7月前
|
存储 新制造 开发工具
Baumer工业相机堡盟工业相机如何联合NEOAPI SDK和OpenCV实现相机图像转换为Mat图像格式(C#)
Baumer工业相机堡盟工业相机如何联合NEOAPI SDK和OpenCV实现相机图像转换为Mat图像格式(C#)
77 0
|
6月前
|
存储 编解码 API
【图像文本化】Base64编解码OpenCV4中 Mat 对象
【图像文本化】Base64编解码OpenCV4中 Mat 对象
112 0
|
6月前
|
openCL API 计算机视觉
OpenCV3.x中UMat对象介绍与使用
OpenCV3.x中UMat对象介绍与使用
133 0
|
7月前
|
存储 定位技术 计算机视觉
Armadillo与OpenCV矩阵数据mat、vec与Mat的相互转换
Armadillo与OpenCV矩阵数据mat、vec与Mat的相互转换
|
7月前
|
计算机视觉
OpenCV(四):Mat支持的运算
OpenCV(四):Mat支持的运算
87 0
|
7月前
|
存储 计算机视觉
OpenCV(三):Mat类数据的读取
OpenCV(三):Mat类数据的读取
229 0
|
7月前
|
存储 Android开发 计算机视觉
OpenCV(二):认识Mat容器
OpenCV(二):认识Mat容器
123 0
|
2月前
|
计算机视觉
Opencv学习笔记(三):图像二值化函数cv2.threshold函数详解
这篇文章详细介绍了OpenCV库中的图像二值化函数`cv2.threshold`,包括二值化的概念、常见的阈值类型、函数的参数说明以及通过代码实例展示了如何应用该函数进行图像二值化处理,并展示了运行结果。
528 0
Opencv学习笔记(三):图像二值化函数cv2.threshold函数详解
下一篇
DataWorks