OpenCV核心功能---MAT

Mat介绍

OpenCV自2001年开始出现。当时,这个库是围绕一个C接口构建的,并将图像存储在内存中,它们使用了一个名为IplImage的C结构。这是您在大多数旧教程和教学材料中看到的内容。 这个问题是它带来了C语言的所有缺点。最大的问题是手动内存管理。它建立在用户负责处理内存分配和释放的假设之上。虽然这对于较小的程序来说不是问题,但是一旦你的代码库增长,处理所有这些问题将更加困难,而不是专注于解决你的开发目标。

幸运的是,C ++出现并通过自动内存管理(或多或少)引入了类更容易为用户创建的概念。 好消息是C ++与C完全兼容,因此进行更改不会产生兼容性问题。 因此,OpenCV 2.0引入了一种新的C ++接口,它提供了一种新的工作方式,这意味着您不需要操作内存管理,使您的代码更简洁(更少编写,实现更多)。C ++界面的主要缺点是目前许多嵌入式开发系统只支持C.因此,除非你的目标是嵌入式平台,否则使用旧方法是没有意义的。

Mat基本上是一个包含两个数据部分的类:矩阵头(包含矩阵大小,用于存储的方法,存储矩阵的地址等信息)和指向包含矩阵的矩阵的指针。 像素值(取决于选择存储的方法取任何维度)。 矩阵标题大小是恒定的,但是矩阵本身的大小可能随图像而变化,并且通常大几个数量级。

OpenCV是一个图像处理库。 它包含大量图像处理功能。 为了解决计算挑战,大多数时候您最终会使用库的多个功能。 因此,将图像传递给函数是一种常见的做法。 我们不应该忘记我们正在讨论图像处理算法,这些算法往往计算量很大。 我们要做的最后一件事是通过制作不必要的潜在大图像副本来进一步降低程序的速度。

为解决此问题,OpenCV使用引用计数系统。 这个想法是每个Mat对象都有自己的头,但是矩阵可以通过让它们的矩阵指针指向同一个地址来共享它们的两个实例。 此外,复制操作符只会将标题和指针复制到大矩阵,而不是数据本身。

最后,所有上述对象都指向相同的单个数据矩阵。 但是,它们的标题不同,并且使用它们中的任何一个进行修改也会影响所有其他标题。 实际上,不同的对象只是为相同的底层数据提供不同的访问方法。 然而,他们的标题部分是不同的。 真正有趣的部分是您可以创建仅引用完整数据的子部分的标题。 例如,要在图像中创建感兴趣区域(ROI),只需使用新边界创建新标题:

现在您可能会询问矩阵本身是否属于多个Mat对象,这些对象在不再需要时负责清理它。 简短的回答是:使用它的最后一个对象。 这是通过使用引用计数机制来处理的。 每当有人复制Mat对象的标题时,矩阵的计数器就会增加。 每当清洁标题时,该计数器都会减少。 当计数器达到零时,矩阵也被释放。 有时您也希望复制矩阵本身,因此OpenCV提供了cv :: Mat :: clone()和cv :: Mat :: copyTo()函数。

存储方式

颜色空间指的是我们如何组合颜色组件以编码给定颜色。 最简单的是灰度,我们处理的颜色是黑色和白色。 这些组合使我们能够创造出许多灰色阴影。

对于丰富多彩的方式,我们有更多的方法可供选择。 它们中的每一个都将其分解为三个或四个基本组件,我们可以使用这些组合来创建其他组件。 最受欢迎的是RGB,主要是因为这也是我们的眼睛如何建立颜色。 它的基色是红色,绿色和蓝色。 要编码颜色的透明度,有时需要第四个元素:添加alpha(A)。

然而,还有许多其他颜色系统各有其优点:

  • RGB是最常见的,因为我们的眼睛使用类似的东西,但请记住,OpenCV标准显示系统使用BGR颜色空间(红色和蓝色通道的开关)组成颜色。
  • HSV和HLS将颜色分解为色调,饱和度和值/亮度分量,这是我们描述颜色的更自然的方式。
  • YCrCb由流行的JPEG图像格式使用。
  • CIE L * a * b *是一个感知上均匀的色彩空间,如果你需要测量给定色彩与另一种色彩的距离,它就会派上用场。

每个构建组件都有自己的有效域。 这导致使用的数据类型。 我们如何存储组件定义了我们对其域的控制。 可能的最小数据类型是char,这意味着一个字节或8位。 这可能是无符号的(因此可以存储0到255之间的值)或有符号(值从-127到+127)。 虽然在三个组件的情况下,这已经提供了1600万种可能的颜色来表示(如在RGB的情况下),我们可以通过使用浮点(4字节= 32位)或双(8字节= 64位)数据来获得更精细的控制 每个组件的类型。 不过,请记住,增加组件的大小也会增加内存中整个图片的大小。

创建一个Mat对象

 您可以通过多种方式创建Mat对象:

  • cv::Mat::Mat Constructor。对于二维和多通道图像,我们首先定义它们的大小:行和列计数。然后我们需要指定用于存储元素的数据类型和每个矩阵点的通道数。 为此,我们根据以下约定构建了多个定义:
  • Use C/C++ arrays and initialize via constructor。下面的示例显示了如何创建具有两个以上维度的矩阵。 指定其尺寸,然后传递包含每个尺寸的尺寸的指针,其余尺寸保持不变。
  • cv::Mat::create function。您无法使用此构造初始化矩阵值。 如果新尺寸不适合旧尺寸,它将仅重新分配其矩阵数据存储器。
  • MATLAB style initializer。cv :: Mat :: zeros,cv :: Mat :: ones,cv :: Mat :: eye。 指定要使用的大小和数据类型:
  • 对于小型矩阵,您可以使用逗号分隔的初始值设定项。
  • 为现有的Mat对象和cv :: Mat :: clone或cv :: Mat :: copyTo创建一个新的头。

输出格式

  • 默认格式:
  • python格式:
  • 逗号分隔值(CSV)格式:
  • Numpy格式:
  • C格式:

其他常见输出格式

  • 2D Point:
  • 3D Point:
  • std::vector via cv::Mat
  • std::vector of points:

猜你喜欢

转载自blog.csdn.net/LYKymy/article/details/83119070