29

我注意到新的OpenCV版本中添加了一个新的数据结构cv::Matx,用于编译时已知大小的小矩阵,例如

cv::Matx31f  // matrix 3x1 of float type

检查文档我看到大多数矩阵运算都是可用的,但我仍然没有看到使用这种新类型而不是旧的 cv::Mat 的优势。

我什么时候应该使用 Matx 而不是 Mat?

4

4 回答 4

11

它是关于内存管理,而不是浪费(在某些情况下很重要)内存或只是为稍后使用的对象保留内存。

这就是我的理解——也许其他人可以给出更好的解释。

于 2012-06-08T08:53:28.520 回答
11

简短的回答: cv::Mat 使用堆来存储它的数据,而 cv::Matx 使用堆栈。

cv::Mat 使用动态内存分配(在堆上)。这适用于大矩阵(如图像),并允许您执行矩阵的浅拷贝等操作,这是 cv::Mat 的默认行为。

但是,对于 cv::Matx 设计的小矩阵,与在堆栈上做同样的事情相比,堆分配会非常昂贵。我已经看到一个数学块通过切换到使用堆栈分配类型(例如 cv::Point 和 cv::Matx)而不是 cv::Mat 将处理时间减少了 75% 以上。

于 2014-07-09T15:27:25.510 回答
8

这是一个迟到的答案,但它仍然是一个有趣的问题!

dom 的答案相当准确,user1460044 中的堆/堆栈引用也很有趣。

从实际的角度来看,我不会使用 Matx(或Vec),除非它是完全必要的。Matx 的主要优点是

  1. 使用堆栈(高效![1])
  2. 初始化。

问题是,最后你将不得不将你的Matx数据移动到 aMat来做大部分事情,因此你将再次回到堆中。另一方面,a 的“酷初始化”Matx可以在普通 Mat 中完成:

// Matx initialization:
Matx31f A(1.f,2.f,3.f);
// Mat initialization:
Mat B = (Mat_<float>(3,1) << 1.f, 2.f, 3.f);

此外,初始化(堆/堆栈之外)的东西也有所不同。如果您尝试将 5 个值放入 M​​atx31,它将崩溃(运行时异常),而Mat_::operator<<使用 5 个值调用只会存储前三个。

[1]如果您的程序必须创建大量少于约 10 个元素的矩阵,则效率很高。在这种情况下使用Matx矩阵。

于 2014-07-16T13:24:34.047 回答
6

Matx我更喜欢其他两个原因Mat

  1. 可读性:阅读代码的人可以立即看到矩阵的大小,例如:

    cv::Matx34d transform = ...;
    

    很明显,这是一个 3x4 矩阵,因此它包含 (R,t) 类型的 3D 变换,其中 R 是旋转矩阵(与轴角相对)。transform(i,j)同样,使用vs访问元素更自然transform.at<double>(i,j)

  2. 易于调试。由于 for 的元素以Matx已知长度的数组分配在堆栈上,因此 IDE 或调试器可以在单步执行代码时很好地显示整个内容。

于 2017-04-14T13:00:37.750 回答