我想知道如何将std::vector<double>
转换为std::vector<Eigen:Vector3d>
。上下文是我正在从HDF 5文件中阅读点云数据(x,y,z点),该文件已被展平为1d数组,转换为std::vector<double>
,因此std::vector<double>
始终具有nx 3个点。
我使用的是libeigen 3-dev(3.3.7)。
之前,我从h5文件中阅读数据到std::vector<double>
中,然后使用Eigen::Map
转换为Eigen::VectorXd
,如下所示:
Eigen::VectorXd readH5Data(H5::DataSet &dataset, H5::VarLenType memType, H5::DataSpace &dataspace, H5::DataSpace &memspace, int index) {
// Initialize hyperslabs
hsize_t dataCount[1];
hsize_t dataOffset[1];
hsize_t memCount[1];
hsize_t memOffset[1];
// Select hyperslabs
dataCount[0] = 1;
dataOffset[0] = index;
memCount[0] = 1;
memOffset[0] = 0;
dataspace.selectHyperslab(H5S_SELECT_SET, dataCount, dataOffset);
memspace.selectHyperslab(H5S_SELECT_SET, memCount, memOffset);
// Read out the data as std::vector<double>
std::vector<hvl_t> varlenSpecs(1);
dataset.read(varlenSpecs.data(), memType, memspace, dataspace);
auto dataPtr = static_cast<double*>(varlenSpecs[0].p);
std::vector<double> readOut(dataPtr, dataPtr + varlenSpecs[0].len);
H5free_memory(varlenSpecs[0].p);
// Convert std::vector<double> to Eigen::VectorXd
double* ptr = &readOut[0];
Eigen::Map<Eigen::VectorXd> dataOut(ptr, readOut.size());
return dataOut;
}
然后,我可以将1d Eigen::VectorXd
转换为nx 3 Eigen::MatrixXd
,如下所示,并进行任何其他处理:
Eigen::VectorXd points = readH5Data(datasetPts, memTypeDbl, dataspacePts, memspacePts, 0);
Eigen::MatrixXd ptsMat = Eigen::Map<Eigen::MatrixXd>(points.data(), 3, nPoints).transpose();
但是,我现在需要使用这些数据点构造一个Open3D PointCloud,其构造如下:
PointCloud (const std::vector< Eigen::Vector3d > &points)
因此,我需要将数据设置为std::vector<Eigen::Vector3d>
。因此,理想情况下,我想修改readH 5Data函数以返回std::vector<Eigen::Vector3d>
。我相信我可以从Eigen::MatrixXd
like this进行转换:
std::vector<Eigen::Vector3d> vec(ptsMat.colwise().begin(), ptsMat.colwise().end());
但是我想知道我是否可以避免中间步骤,直接从std::vector<double>
到std::vector<Eigen::Vector3d>
。
1条答案
按热度按时间4nkexdtk1#
好的,让我们把这个分解一下,主要是为了我对你的代码的理解。请仔细检查一下。这也意味着我的解决方案只有在这些条件成立的情况下才有效。
这告诉我,无论你的内存数据类型是什么,它都不是类似
struct
的类型或任何花哨的类型,只是一个基本的双精度数组。因此,3行,N列以列为主的顺序,这意味着
std::vector<Eigen::Vector3d>
将在内存中具有相同的布局。这里有两个重要的方面需要注意:std::vector
的内存布局不是不透明的,它必须实现为动态数组,您可以自由地将其视为动态数组Eigen::Vector3d
没有填充这意味着你可以简单地使用
memcpy
。它并不花哨,但它可以以最小的开销完成工作。有人可能会反对缺乏内存安全性,但坦率地说,大多数HDF5的API缺乏内存安全性,而Eigen::Map
也没有。整个阅读功能也可以清理。
注意使用1大小的数组是没有意义的。只使用标量。我也不认为有理由传入
DataSpace
对象。如果有的话,它会使它更容易出错。