2012-11-20 53 views
7

假设mat的类型为Eigen::MatrixXd并且已经包含一些数据。在试图避免重复记忆,我试图实例从指针flann::Matrix<double>对象由Eigen3分配的原始内存块:Eigen :: MatrixXd to flann ::矩阵<double>转换

flann::Matrix<double> input(const_cast<double *>(mat.data(), mat.rows(), mat.cols()) 

然而,我的算法输出的垃圾,但仅仅是用丑恶的罚款:

flann::Matrix<double> input(new double[mat.rows()*mat.cols()], mat.rows(), mat.cols()); 
for (int i = 0; i < mat.rows(); i++) { 
for (int j = 0; j < mat.cols(); j++) { 
    input[i][j] = mat(i, j); 
} 

}

我调查从FLANN子类基Matrix_类型来创建一个适配器Eigen3矩阵的选项。但问题是,Matrix_依赖于在其接口中实现[]运算符。这让我觉得我可能会遇到与上面显示的简单(但是破碎的)解决方案相同的内存问题。

您认为什么可以解释这种行为?

回答

0

Eigen ::矩阵存储数据连续,所以你不应该得到跨步问题。如果你正试图构建一个Eigen :: Matrix(但我无法想象这是怎么可能的),那么对齐可能是问题。默认情况下,Eigen :: Matrix是专栏,这可能是你的问题。我不知道flann如何处理矩阵,如果它们是排行榜的话,就是这样。以下示例与Eigen :: Matrix < double,-1,-1,Eigen :: RowMajor>一起使用,并且与Eigen :: MatrixXd一起失败。

int k = 0; 
for (int i = 0; i<mat.rows(); ++i) 
{ 
    for (int j = 0; j<mat.cols(); ++j, ++k) { 
     mat(i, j) = k; 
    } 
} 

double* mptr = mat.data(); 
for (int i = 0; i<mat.rows() * mat.cols(); ++i) { 
    assert(mptr[i] == i); 
} 

我还没有得到你对Eigen :: Map的抱怨。将数据作为特征矩阵(注意,它仍然是默认的列专业),从矩阵进行子类化或实现自定义特征表达式可能是痛苦的,这是最好的方法。

7

我也得到了libflann的作者Marius Muja的确认,flann::Matrix以行优先顺序存储,而Eigen默认使用列优先。下面是他给了我通过电子邮件回答:

的问题是最有可能的是,在列主顺序征商店矩阵>而FLANN要求他们按行优先顺序。

解决方法是使用Matrix<double, Dynamic, Dynamic, RowMajor>而不是MatrixXd,然后FLANN和Eigen矩阵可以共享相同的内存,否则将需要一个副本。 Marius Muja

+0

我与nanoFLANN有同样的问题(尽管它在两种方式下都有效,但默认Column-Major对于我的应用程序非常笨拙),谢谢! –