Ответ 1
Это о управлении памятью, а не о пропаже (в некоторых случаях важной) памяти или просто резервировании памяти для объекта, который вы будете использовать позже.
То, что я понимаю, может быть, кто-то другой может дать лучшее объяснение.
Я заметил, что новая новая структура cv:: Matx была добавлена в новую версию OpenCV, предназначенную для небольших матриц известного размера во время компиляции, например
cv::Matx31f // matrix 3x1 of float type
Проверка документации Я видел, что большинство операций с матрицами доступны, но я все же не вижу преимуществ использования этого нового типа старого cv:: Mat.
Когда следует использовать Matx вместо Mat?
Это о управлении памятью, а не о пропаже (в некоторых случаях важной) памяти или просто резервировании памяти для объекта, который вы будете использовать позже.
То, что я понимаю, может быть, кто-то другой может дать лучшее объяснение.
Это поздний поздний ответ, но это еще интересный вопрос!
dom answer довольно точен, и ссылка на кучу/стек в user1460044 также интересна.
С практической точки зрения я бы не использовал Matx
(или Vec
), за исключением случаев, когда это было совершенно необходимо. Основными преимуществами Matx являются
Проблема в том, что в конце вам нужно будет переместить ваши данные Matx
в Mat
, чтобы сделать большую часть материала, и поэтому вы снова вернетесь в кучу.
С другой стороны, "крутая инициализация" 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 значений в Matx31, это приведет к сбою (исключение во время выполнения), а при вызове Mat_::operator<<
с 5 значениями будут храниться только первые три.
[1] Эффективен, если ваша программа должна создавать множество матриц менее ~ 10 элементов. В этом случае используйте матрицы Matx
.
Короткий ответ: cv:: Mat использует кучу для хранения своих данных, а cv:: Matx использует стек.
A cv:: Mat использует распределение динамической памяти (в куче). Это подходит для больших матриц (например, изображений) и позволяет делать такие вещи, как мелкие копии матрицы, которая является поведением по умолчанию cv:: Mat.
Однако для небольших матриц, для которых cv:: Matx предназначен, распределение кучи было бы очень дорого по сравнению с тем же самым действием в стеке. Я видел, что блок математики сокращает время обработки более чем на 75%, переключаясь на использование типов, связанных с стеками (например, cv:: Point и cv:: Matx) вместо cv:: Mat.
Есть еще две причины, по которым я предпочитаю Matx
- Mat
:
Чтение: люди, читающие код, могут сразу увидеть размер матриц, например:
cv::Matx34d transform = ...;
Ясно, что это матрица 3x4, поэтому она содержит 3D-преобразование типа (R, t), где R - матрица вращения (в отличие, например, от оси).
Аналогично, доступ к элементу более естественен с помощью transform(i,j)
vs transform.at<double>(i,j)
.
Легкая отладка. Поскольку элементы для Matx
выделяются в стеке в массиве известной длины, IDE или отладчики могут хорошо отображать все содержимое при прохождении кода.