QT和opencv学习(三)基本的图像容器 --Mat

Mat

OpenCV自2001年以来就一直存在。在那些日子里,图书馆是围绕一个C接口构建的,并将图像存储在内存中,他们使用了一个名为IplImage的C结构。这是你将在大多数旧的教程和教育材料中看到的。这个问题的问题在于,它把C语言的所有缺点都带到了桌子上。最大的问题是手动内存管理。它建立在用户负责处理内存分配和回收的假设之上。虽然这不是小程序的问题,但是一旦您的代码库增长了,那么处理所有这些问题将会更加困难,而不是专注于解决您的开发目标。

幸运的是,C++出现了,并引入了类的概念,通过自动内存管理(或多或少)使用户更容易。好消息是,C++与C完全兼容,因此不可能产生兼容性问题。因此,opencv2.0引入了一个新的C++接口,它提供了一种新的做事方式,这意味着您不需要修改内存管理,使您的代码简洁(更少写,以获得更多)。C++接口的主要缺点是,目前许多嵌入式开发系统只支持c.因此,除非您的目标是嵌入式平台,否则使用旧方法是没有意义的(除非您是一个受虐待的程序员,并且您正在自找麻烦)。

关于Mat,您需要知道的第一件事是,您不再需要手动分配它的内存,并在您不需要它的时候立即释放它。虽然这仍然是一种可能,但大多数OpenCV函数都会自动分配它的输出数据。如果你传递一个已经存在的Mat对象,它已经为矩阵分配了所需的空间,那么这将被重用。换句话说,我们在任何时候都只使用我们执行任务所需的内存。

Mat基本上是一个类有两个数据部分:矩阵头(包含信息矩阵的大小等,用于存储的方法,在解决矩阵存储,等等)和一个指向包含像素值的矩阵(采取任何维数取决于选择的方法来存储)。矩阵头的大小是恒定的,但是矩阵本身的大小可能因图像而异,而且通常是按数量级放大的。

OpenCV是一个图像处理库。它包含大量的图像处理功能。要解决计算难题,大多数情况下,您最终会使用库的多个功能。正因为如此,将图像传递给函数是一种常见的做法。我们不应该忘记,我们讨论的是图像处理算法,它的计算量非常大。我们最不想做的事情就是通过不必要地复制潜在的大图片来进一步降低程序的速度。

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

Mat A, C;     // creates just the header parts
A = imread(argv[1], IMREAD_COLOR); // here we'll know the method used (allocate matrix
Mat B(A);   // Use the copy constructor
C = A;   // Assignment operator

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

Mat D (A, Rect(10, 10, 100, 100) ); // using a rectangle
Mat E = A(Range::all(), Range(1,3)); // using row and column boundaries

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

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

现在修改F或G不会影响到由Mat头指向的矩阵。你需要记住的是:

  • OpenCV功能的输出图像分配是自动的(除非另有

  • 0
    点赞
  • 1
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值