结合Armadillo库使用OpenCV库的最佳方式是什么?

结合Armadillo库使用OpenCV库的最佳方式是什么?,opencv,armadillo,Opencv,Armadillo,我正在使用OpenCV构建一个图像处理应用程序。我也在使用犰狳库,因为它有一些非常简洁的矩阵相关函数。但问题是,为了在cv::Mat上使用犰狳函数,我需要频繁地将cv::Mat转换为arma::Mat。 为此,我使用如下函数将cv::Mat转换为arma::Mat arma::Mat cvMat2armaMat(cv::Mat M) { copy cv::Mat data to a arma::Mat return arma::Mat } 有更有效的方法吗?为了避免或减少复制,

我正在使用OpenCV构建一个图像处理应用程序。我也在使用犰狳库,因为它有一些非常简洁的矩阵相关函数。但问题是,为了在cv::Mat上使用犰狳函数,我需要频繁地将cv::Mat转换为arma::Mat。 为此,我使用如下函数将cv::Mat转换为arma::Mat

arma::Mat cvMat2armaMat(cv::Mat M)
{
    copy cv::Mat data to a arma::Mat
    return arma::Mat
}

有更有效的方法吗?

为了避免或减少复制,您可以通过成员函数访问犰狳矩阵使用的内存。例如:

mat X(5,6);
double* mem = X.memptr();
double* data = new double[4*5];
// ... fill data ...
mat X(data, 4, 5, false);  // 'false' indicates that no copying is to be done; see docs
在使用上述方法时要小心,因为你不允许自己释放内存(犰狳仍将管理内存)

或者,您可以从现有内存中构造犰狳矩阵。例如:

mat X(5,6);
double* mem = X.memptr();
double* data = new double[4*5];
// ... fill data ...
mat X(data, 4, 5, false);  // 'false' indicates that no copying is to be done; see docs
在这种情况下,您将负责手动管理内存


还要记住Armadillo在中存储和访问矩阵,即先存储第0列,然后存储第1列、第2列等。这与MATLAB、LAPACK和BLAS使用的相同。

这是我最后想到的<代码>模板arma::Mat cvMat2armaMat(cv::Mat cvMatIn){arma::Mat armaConv(cvMatIn.data,cvMatIn.rows,cvMatIn.cols,false);返回armaConv;}我认为您的代码不可靠和/或效率高。代码通过值传递cvMatIn矩阵,该值隐式地在函数内部生成临时副本。然后,它直接从现有的临时内存中创建犰狳矩阵。如果C++编译器使用返回值优化(RVO),则代码会在临时被破坏时被破坏,因此内存将不再有效。如果编译器没有使用RVO,它实际上是在返回时通过复制新创建的犰狳矩阵来生成另一个犰狳矩阵。如果可以保证作为cvMatIn传递的对象与创建的犰狳矩阵一样长,那么沿着以下行编写的代码会更好:模板内联void cvMat2armaMat(const cv::Mat&cvMatIn){return arma::Mat(cvMatIn.data,cvMatIn.rows,cvMatIn.cols,false);}。如果您不能做出保证,请省略最后一个“false”,即:{return arma::Mat(cvMatIn.data,cvMatIn.rows,cvMatIn.cols);}.在这两种情况下,您仍然需要考虑犰狳使用列主顺序,即,如果cvMatIn使用行主顺序,矩阵元素将被转置。我的评论中有一个小错误:更改“void”感谢arma::MatHey的后续评论。是的,我会将函数更改为通过引用获取值。此外,大多数原始矩阵将比armadillo矩阵更长寿。因此,使用“false”复制它应该可以。但我可能会创建两个不同版本的函数来处理这两种情况。