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

目录
相关文章
|
4月前
|
存储 新制造 开发工具
Baumer工业相机堡盟工业相机如何联合NEOAPI SDK和OpenCV实现相机图像转换为Mat图像格式(C++)
Baumer工业相机堡盟工业相机如何联合NEOAPI SDK和OpenCV实现相机图像转换为Mat图像格式(C++)
42 2
|
6月前
|
存储 Cloud Native Linux
openCV 图像对象的创建和赋值
openCV 图像对象的创建和赋值
|
7月前
|
存储 编译器 数据库
[笔记]OpenCV+FFmpeg+Qt实现视频编辑器之OpenCV核心类型 Mat
[笔记]OpenCV+FFmpeg+Qt实现视频编辑器之OpenCV核心类型 Mat
|
4月前
|
存储 新制造 开发工具
Baumer工业相机堡盟工业相机如何联合NEOAPI SDK和OpenCV实现相机图像转换为Mat图像格式(C#)
Baumer工业相机堡盟工业相机如何联合NEOAPI SDK和OpenCV实现相机图像转换为Mat图像格式(C#)
33 0
|
5月前
|
存储 定位技术 计算机视觉
Armadillo与OpenCV矩阵数据mat、vec与Mat的相互转换
Armadillo与OpenCV矩阵数据mat、vec与Mat的相互转换
|
5月前
|
计算机视觉
OpenCV(四):Mat支持的运算
OpenCV(四):Mat支持的运算
37 0
|
5月前
|
存储 计算机视觉
OpenCV(三):Mat类数据的读取
OpenCV(三):Mat类数据的读取
93 0
|
5月前
|
存储 Android开发 计算机视觉
OpenCV(二):认识Mat容器
OpenCV(二):认识Mat容器
57 0
|
9月前
|
存储 监控 算法
Baumer工业相机堡盟相机中的JPEG图像压缩相机如何通过BGAPI SDK和OpenCV的Mat进行图像转换(C++)
Baumer工业相机堡盟相机中的JPEG图像压缩相机如何通过BGAPI SDK和OpenCV的Mat进行图像转换(C++)
98 0
|
9月前
|
监控 开发工具 C#
Baumer工业相机堡盟相机BGAPI SDK联合OpenCV进行Mat图像转换(C#)
Baumer工业相机堡盟相机BGAPI SDK联合OpenCV进行Mat图像转换(C#)
69 1