OpenCV 3.1.0中的Mat对象使用

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

一: 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++)
86 2
|
2月前
|
Serverless 计算机视觉
语义分割笔记(三):通过opencv对mask图片来画分割对象的外接椭圆
这篇文章介绍了如何使用OpenCV库通过mask图像绘制分割对象的外接椭圆。首先,需要加载mask图像,然后使用`cv2.findContours()`寻找轮廓,接着用`cv2.fitEllipse()`拟合外接椭圆,最后用`cv2.ellipse()`绘制椭圆。文章提供了详细的代码示例,展示了从读取图像到显示结果的完整过程。
59 0
语义分割笔记(三):通过opencv对mask图片来画分割对象的外接椭圆
|
7月前
|
存储 新制造 开发工具
Baumer工业相机堡盟工业相机如何联合NEOAPI SDK和OpenCV实现相机图像转换为Mat图像格式(C#)
Baumer工业相机堡盟工业相机如何联合NEOAPI SDK和OpenCV实现相机图像转换为Mat图像格式(C#)
74 0
|
6月前
|
存储 算法 API
OpenCV 3.1.0中的Mat对象使用
OpenCV 3.1.0中的Mat对象使用
40 2
|
6月前
|
存储 编解码 API
【图像文本化】Base64编解码OpenCV4中 Mat 对象
【图像文本化】Base64编解码OpenCV4中 Mat 对象
94 0
|
6月前
|
openCL API 计算机视觉
OpenCV3.x中UMat对象介绍与使用
OpenCV3.x中UMat对象介绍与使用
124 0
|
7月前
|
存储 定位技术 计算机视觉
Armadillo与OpenCV矩阵数据mat、vec与Mat的相互转换
Armadillo与OpenCV矩阵数据mat、vec与Mat的相互转换
|
7月前
|
计算机视觉
OpenCV(四):Mat支持的运算
OpenCV(四):Mat支持的运算
77 0
|
7月前
|
存储 计算机视觉
OpenCV(三):Mat类数据的读取
OpenCV(三):Mat类数据的读取
198 0
|
7月前
|
存储 Android开发 计算机视觉
OpenCV(二):认识Mat容器
OpenCV(二):认识Mat容器
119 0