cv :: Matx的优点

Jav*_*ock 25 opencv matrix

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

cv::Matx31f  // matrix 3x1 of float type
Run Code Online (Sandbox Code Playgroud)

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

什么时候应该使用Matx代替Mat?

dom*_*dom 11

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

这就是我理解的方式 - 可能是别人可以给出更好的解释.


use*_*044 8

简短回答:cv :: Mat使用堆来存储其数据,而cv :: Matx使用堆栈.

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

但是,对于cv :: Matx设计的小型矩阵,与在堆栈上执行相同操作相比,堆分配将非常昂贵.通过切换到使用堆栈分配类型(例如cv :: Point和cv :: Matx)而不是cv :: Mat,我看到一个数学块将处理时间缩短了75%以上.

  • 我相信循环展开也可以获得很多性能,这对于动态大小的矩阵是无法实现的. (2认同)

Яoi*_*ois 7

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

dom的答案非常准确,user1460044中的堆/堆栈引用也很有趣.

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

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

问题是,最后你必须将你的Matx数据移动Mat到大部分的东西,所以,你将再次回到堆中.另一方面,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);
Run Code Online (Sandbox Code Playgroud)

此外,初始化(超出堆/堆栈)的东西也有所不同.如果你试图将5个值放入Matx31,它将崩溃(运行时异常),而调用Mat_::operator<<with 5值只会存储前三个.

[1] 高效如果程序有可能创造大量的小于约10组的元素矩阵.在那种情况下使用Matx矩阵.


Dan*_*ciu 6

还有为什么我喜欢2个原因MatxMat

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

    cv::Matx34d transform = ...;
    
    Run Code Online (Sandbox Code Playgroud)

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

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