点云是一系列点的集合,pcl在存储时放在cloud->points中(vector容器,内存连续),在处理点云时,有时需要将点云数据点格式转换为矩阵格式进行计算,如果直接进行赋值,会重新开辟内存空间,对大数据点云来说并不现实。因此使用Eigen::Map进行内存映射,节省内存空间,加快处理速度。
Eigen::Map是将一段连续的内存空间映射成Eigen中Matrix的形式,可以直接使用相关的矩阵运算,极大的节省了内存占用,提升了计算处理效率。
pcl点云中有函数getMatrixXfMap用于生成Eigen::Map
inline Eigen::Map<Eigen::MatrixXf, Eigen::Aligned, Eigen::OuterStride<> >
getMatrixXfMap (int dim, int stride, int offset)
{
if (Eigen::MatrixXf::Flags & Eigen::RowMajorBit)
return (Eigen::Map<Eigen::MatrixXf, Eigen::Aligned, Eigen::OuterStride<> >(reinterpret_cast<float*>(&points[0])+offset, points.size (), dim, Eigen::OuterStride<> (stride)));
else
return (Eigen::Map<Eigen::MatrixXf, Eigen::Aligned, Eigen::OuterStride<> >(reinterpret_cast<float*>(&points[0])+offset, dim, points.size (), Eigen::OuterStride<> (stride)));
}
其中参数,列优先时,
dim:行数
stride:每列数据的跨度
offset:首地址偏移量
Eigen::Map<Eigen::Matrix<float,-1,-1>,
16,Eigen::OuterStride<>> mat = cloud->getMatrixXfMap(4,4,0);
上述代码表示将XYZ转换为size*4的矩阵
pcl转换中无法将矩阵转换为行优先
Eigen::Map<Eigen::Matrix<float,-1,-1,Eigen::RowMajor>,
16,Eigen::OuterStride<>> mat = cloud->getMatrixXfMap(4,8,0);
上面的代码会报错。
可以采用以下方式进行行优先的map映射
Eigen::Map<Eigen::Matrix<float,-1,-1,1>, Eigen::Aligned, Eigen::OuterStride<4> > mat1
(reinterpret_cast<float*>(&(cloud->points[0])), cloud->points.size(), 3);
以上代码就是直接将数据映射到Eigen::Matrix
根据以上方法可以计算点云的包围盒:
Eigen::Map<Eigen::Matrix<float,-1,-1>,
16,Eigen::OuterStride<>> mat_x = cloud->getMatrixXfMap(1,4,0);
Eigen::Map<Eigen::Matrix<float, -1, -1>,
16, Eigen::OuterStride< >> mat_y = cloud->getMatrixXfMap(1, 4, 1);
Eigen::Map<Eigen::Matrix<float, -1, -1>,
16, Eigen::OuterStride< >> mat_z = cloud->getMatrixXfMap(1, 4, 2);
std::cout << mat_x.minCoeff(), mat_y.minCoeff(), mat_z.minCoeff();
std::cout << mat_x.maxCoeff(), mat_y.maxCoeff(), mat_z.maxCoeff();