点云场景下:如何将std::vector<double>直接转std::vector<Eigen::Vector3d>
直接将std::vector转换为std::vectorEigen::Vector3d的方法
针对你从HDF5读取展平点云数据的场景,完全可以跳过中间的Eigen::VectorXd和Eigen::MatrixXd步骤,直接完成转换,以下是两种可行方案:
方法一:手动遍历构造(直观易懂)
从一维数组中每3个元素为一组,直接构造Eigen::Vector3d并添加到目标容器,适合快速理解逻辑:
std::vector<double> flatPoints = ...; // 从HDF5读取的n×3个double size_t nPoints = flatPoints.size() / 3; std::vector<Eigen::Vector3d> pointVec; pointVec.reserve(nPoints); // 预分配内存提升效率 for (size_t i = 0; i < nPoints; ++i) { const double* ptr = &flatPoints[i * 3]; pointVec.emplace_back(ptr[0], ptr[1], ptr[2]); }
方法二:利用Eigen Map批量转换(高效简洁)
借助Eigen的Map将一维数组映射为3行n列的矩阵视图,再通过矩阵迭代器直接构造目标vector,避免手动遍历,效率更高:
std::vector<double> flatPoints = ...; size_t nPoints = flatPoints.size() / 3; // 将flatPoints映射为3行n列的矩阵(每列对应一个点的x、y、z) Eigen::Map<const Eigen::Matrix<double, 3, Eigen::Dynamic>> mat(flatPoints.data(), 3, nPoints); // 直接从矩阵列迭代器构造vector<Eigen::Vector3d> std::vector<Eigen::Vector3d> pointVec(mat.colwise().begin(), mat.colwise().end());
修改readH5Data函数直接返回目标类型
将原函数返回类型改为std::vector<Eigen::Vector3d>,读取到std::vector<double>后直接用上述方法转换,省去中间步骤:
#include <Eigen/Dense> #include <vector> #include <H5Cpp.h> std::vector<Eigen::Vector3d> readH5Data(H5::DataSet &dataset, H5::VarLenType memType, H5::DataSpace &dataspace, H5::DataSpace &memspace, int index) { // 初始化hyperslabs(原逻辑不变) hsize_t dataCount[1]; hsize_t dataOffset[1]; hsize_t memCount[1]; hsize_t memOffset[1]; 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); // 读取数据到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); // 直接转换为std::vector<Eigen::Vector3d> size_t nPoints = readOut.size() / 3; Eigen::Map<const Eigen::Matrix<double, 3, Eigen::Dynamic>> mat(readOut.data(), 3, nPoints); return std::vector<Eigen::Vector3d>(mat.colwise().begin(), mat.colwise().end()); }
注意事项
- 确保
readOut.size()始终是3的整数倍,符合你场景中“元素数量为n×3”的前提; - 上述代码兼容Eigen 3.3.7版本,
colwise().begin()在该版本已完全支持; - 方法二中的
Map是零拷贝视图,仅创建数据映射,转换为vector时才会复制数据到目标容器。
内容的提问来源于stack exchange,提问作者Nate Bartlett
相关产品推荐
相关产品推荐

