OpeCV图像处理---基本图像容器Mat

前沿

翻译:OpenCV_tutorials(2.1Mat---The Basic Image container)
版本:3.0.0
需要:C++知识
第一次翻译,不好的地方多多斧正。

学习图像处理都是从冈萨雷斯的数字图像处理开始的,学习OpenCV第一步都得熟悉图像在内存中的存储吧,图像在内存中存储都是以  Mat 类对象存储。以前的1.0.0版本的OpenCV中存储是用C语言中的struct。这带来很大的问题就是手动内存的管理,随着我们的代码量越来越大时候,内存的管理和释放将会是很麻烦的。幸运的是,从OpenCV2.0.0版本开始,提供新的C++接口,这一种新的方法不需要去操作内存管理让我们代码更加简洁,使我们专注于我们所解决的问题。但是C++主要的问题就是不支持嵌入式开发系统,除非你针对的是嵌入式平台,否则使用老的OpenCV是没有意义的。

Mat

首先我们明确不需要手动的的分配和释放 Mat 类,但是函数中也可能那么做,大部分OpenCV函数将自动分配输出数据。另一个便利的是:如果需要传递一个已经存在的 Mat 类对象,被开辟的空间会被重用。换句话说,每次我们使用的内存空间整好能满足我们的任务需求( In other words we use at all times only as much memory as weneed to perform the task.
Mat 有两部分组成:矩阵信息头(包含矩阵大小、存储的方法、地址信息等)和一个指向包含像素值矩阵的指针(不同的存储方法有不同的维度)。矩阵头的大小是恒定的。然而,矩阵本身的尺寸会根据图像的不同而不同,一般比矩阵头的尺寸多几个数量级。( however the size of the matrix itself may vary from image to image and usually is larger by orders of magnitude.
OpenCV是一个图像库,包含了大量的图像处理函数。为了解决计算挑战( computational challenge),大部分情况下需要调用库中的多个函数。因此,给函数传递图形变得很常见。同时我们不要忘了我们主要任务是计算量很大的图像处理的算法,我们最不想看到的就是复制很大的图像而降低程序的运行速度。
OpenCV使用引用计数系统来解决这个问题。主要思想就是:让每个 Mat 类对象都有自己的信息头,通过让自己的矩阵指针指向同一个地址来共享一块地址空间。此外,拷贝构造函数(copy operators)仅仅拷贝的是消息头和指向矩阵的指针,并没有复制矩阵部分。
Mat  A, C;                //仅仅新建一个信息头部分
A = imread(argv[1], CV_LOAD_IMAGE_COLOR);  //这里,我们才知道分配矩阵方法
Mat  B(A);          //复制构造函数,将对象A 复制给 B(C++知识)
C = A;                //赋值操作
以上的全部对象,最后都指向相同的单一数据矩阵,他们的信息头不同,然而修改其中一个类,其他的类也会被改变。实际上不同的对象仅仅提供了不同的访问相同的底层数据的方法,然而它们的信息头不同。很有趣的是我们能新建一个引用部分数据的信息头。举个例子,在一个图像中新建一个
感兴趣区域(region of interest--ROI),你只需要新建一个包含新的边界的消息头。
Mat D (A, Rect(10,10,100,100) ); // 使用矩形
Mat E = A(Rang::all(), Range(1,3) ); //使用行和列边界
现在修改对象 F 或者 G 将不对影响 Mat 消息头指向的矩阵。你需要记住如下的几点:
OpenCV函数将自动分配输出图像内存(除非特殊声明)。
使用OpenCV的C++接口时候不需要考虑内存的管理。
赋值运算符和拷贝构造函数只是拷贝这个消息头。
可以通过函数 clone() 和 copyTo() 复制函数的矩阵。

存储方法

这章节讨论如何存储像素值。需要选择颜色空间和使用的数据类型。最简单的颜色空间是灰度空间,只需要处理黑色和白色的。黑色和白色的组合可以生成许多个灰度等级。对于彩色方法我们可以选择多种颜色空间。每种颜色空间都是有三、四种基本的颜色分量组成,我们能组合这些基本颜色来生成其他的颜色。最常见的一种是 RGB 颜色空间,主要是因为这也是我们眼睛构成颜色的方式。它的基本颜色是红色、绿色、蓝色。有时候为了表示透明的颜色,引入了第四个分量:alpha(A)。
然而,不同的颜色系统有自己的优势:
RGB 是最常见的空间模型和我们的眼睛工作机机制,所以一些显示设备使用这种空间模型。
这个 HSV 和 HLS 颜色空间模型把颜色分解成色调、饱和度和量度,对我们来说,这是一种非常自然的方式描述颜色。举个例子,你可以忽略最后一个分量,让你的算法对输入图像的光照强度不敏感。
YCrCb 空间模型是被用在流行的 JPEG 图像格式上。
CIE L*a*b* 是一个感知均匀的空间模型,它可以很方便的测量从一个被给的颜色到另一个颜色。
        每个组成元素都有其自己的定义域,取决于其数据类型。如何存储一个元素决定了我们在其定义域上能够控制的精度。 Each of the building components has their own valid domains. This leads to the data type used. How we store a component defines the control we have over its domain. )最小的数据类型是 char ,占有一个字节或者八位。它可能是无符号的(存储的值是从0--255)或者是有符号的(值是从-127--127)。虽然三个 char 可以表示出 1600万中颜色(使用 RGB空间模型)。我们可能要求一个更好的控制效果,可以使用浮点型数据类型(4字节=32位)或者双精度(8字节=64位)数据类型表示每一个分量。然而,需要记住的是增加了颜色分量也增加了整个图像在内存中的存储。

显式的创建一个 Mat类对象



















你可能感兴趣的:(OpenCV学习)