• 激光雷达点云地面水平校准


    博客转载自:https://blog.csdn.net/ethan_guo/article/details/80683181

    激光雷达采集的数据,可能由于颠簸或者雷达安装倾斜或者地面本身是有坡度的,造成地面在雷达坐标系中不是水平的。不是水平的,会影响我们后续的对点云的分割分类等处理,所以校准很有必要。

    校准方法是(参考):用PCL中基于RANSAC的平面检测方法检测出平面,得到平面:ax+by+cz+d=0。对于一个平面,上式中xyz的系数,就是它的法向量。然后,雷达坐标系中的竖直向量是(0,0,1),计算出从平面法向量旋转到竖直向量的旋转矩阵,再把此旋转矩阵应用到点云,点云即可得到旋转。
    1. 分割平面,得到平面的法向量

        pcl::SACSegmentation<pcl::PointXYZ> plane_seg;
        pcl::PointIndices::Ptr plane_inliers ( new pcl::PointIndices );
        pcl::ModelCoefficients::Ptr plane_coefficients ( new pcl::ModelCoefficients );
        plane_seg.setOptimizeCoefficients (true);
        plane_seg.setModelType ( pcl::SACMODEL_PLANE );
        plane_seg.setMethodType ( pcl::SAC_RANSAC );
        plane_seg.setDistanceThreshold ( 0.3 );
        plane_seg.setInputCloud ( cloud_in );
        plane_seg.segment (*plane_inliers, *plane_coefficients);//得到平面系数,进而得到平面法向量
    

    2.计算两个向量之间的旋转矩阵:

    关于在已知两个向量坐标的情况下如何求两者的旋转矩阵的问题,可以看这个这个。其中,会用到两个向量的点乘和叉乘,什么是点乘和叉乘,看这里。怎么实现点乘和叉乘,看这里,用eigen库非常方便,都已经封装好了。

    Eigen::Matrix4f CreateRotateMatrix(Vector3f before,Vector3f after)
    {
        before.normalize();
        after.normalize();
     
        float angle = acos(before.dot(after));
        Vector3f p_rotate =before.cross(after);
        p_rotate.normalize();
     
        Eigen::Matrix4f rotationMatrix = Eigen::Matrix4f::Identity();
        rotationMatrix(0, 0) = cos(angle) + p_rotate[0] * p_rotate[0] * (1 - cos(angle));
        rotationMatrix(0, 1) = p_rotate[0] * p_rotate[1] * (1 - cos(angle) - p_rotate[2] * sin(angle));//这里跟公式比多了一个括号,但是看实验结果它是对的。
        rotationMatrix(0, 2) = p_rotate[1] * sin(angle) + p_rotate[0] * p_rotate[2] * (1 - cos(angle));
     
     
        rotationMatrix(1, 0) = p_rotate[2] * sin(angle) + p_rotate[0] * p_rotate[1] * (1 - cos(angle));
        rotationMatrix(1, 1) = cos(angle) + p_rotate[1] * p_rotate[1] * (1 - cos(angle));
        rotationMatrix(1, 2) = -p_rotate[0] * sin(angle) + p_rotate[1] * p_rotate[2] * (1 - cos(angle));
     
     
        rotationMatrix(2, 0) = -p_rotate[1] * sin(angle) +p_rotate[0] * p_rotate[2] * (1 - cos(angle));
        rotationMatrix(2, 1) = p_rotate[0] * sin(angle) + p_rotate[1] * p_rotate[2] * (1 - cos(angle));
        rotationMatrix(2, 2) = cos(angle) + p_rotate[2] * p_rotate[2] * (1 - cos(angle));
     
        return rotationMatrix;
    }
    

    3. 利用旋转矩阵,将点云旋转

    pcl::transformPointCloud(*cloud_in, *cloud_final, rotation);
    
  • 相关阅读:
    自由群(2)|完整版
    模1|同态
    交换代数笔记1|Atiyah,Chpt.1
    微分形式的几何第一章笔记
    矩阵群的一些简单习题1
    自由群1:基本概念
    代数的一些习题2|自由群与自由交换群
    蛤车1:两个习题,群作用与覆叠空间,N-S定理
    提升引理:唯一提升与同伦提升
    复变函数:复函数的空间与Montel定理
  • 原文地址:https://www.cnblogs.com/flyinggod/p/10053871.html
Copyright © 2020-2023  润新知