我注意到新的 OpenCV 版本中添加了一个新的数据结构 cv :: Matx ,用于编译时已知大小的小矩阵,例如< / p>
cv::Matx31f // matrix 3x1 of float type
检查documentation我看到大多数矩阵操作都可用,但我仍然没有看到使用这种新类型而不是旧的cv :: Mat的优点。
我应该何时使用Matx代替Mat?
答案 0 :(得分:11)
这是关于内存管理而不是浪费(在某些情况下很重要)内存或只是为稍后使用的对象保留内存。
这就是我理解的方式 - 可能是别人可以给出更好的解释。
答案 1 :(得分:8)
简短回答:cv :: Mat使用堆来存储数据,而cv :: Matx使用堆栈。
cv :: Mat使用动态内存分配(在堆上)。这适用于大矩阵(如图像),并允许您执行矩阵的浅拷贝,这是cv :: Mat的默认行为。
但是,对于cv :: Matx设计的小矩阵,与在堆栈上执行相同操作相比,堆分配将非常昂贵。通过切换到使用堆栈分配类型(例如cv :: Point和cv :: Matx)而不是cv :: Mat,我看到一个数学块将处理时间减少了75%以上。
答案 2 :(得分:7)
这是一个迟到的答案,但它仍然是一个有趣的问题!
dom的答案非常准确,user1460044中的堆/堆栈引用也很有趣。
从实际的角度来看,我不会使用 Matx
(或Vec
),除非它是完全必要的。 Matx的主要优点是
问题是,最后你必须将Matx
数据移动到Mat
以完成大部分工作,因此,你将再次回到堆中。
另一方面,&#34;酷初始化&#34; Matx
的{{1}}可以在普通的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个值放入Matx31,它将崩溃(运行时异常),而调用带有5个值的Mat_::operator<<
只会存储前三个。
[1] 高效如果你的程序必须创建大量小于10个元素的矩阵。在这种情况下,使用Matx
矩阵。
答案 3 :(得分:3)
我更喜欢Matx
到Mat
的其他两个原因:
可读性:阅读代码的人可以立即看到矩阵的大小,例如:
cv::Matx34d transform = ...;
很明显,这是一个3x4矩阵,因此它包含类型(R,t)的3D变换,其中R是旋转矩阵(与轴角相反)。
同样,使用transform(i,j)
vs transform.at<double>(i,j)
来访问元素更为自然。
轻松调试。由于Matx
的元素在堆栈中以已知长度的数组分配,因此IDE或调试器在单步执行代码时可以很好地显示整个内容。