基于PCL库实现可视化/旋转至指定平面等功能

基于PCL库实现附加功能

可视化

  1. ubuntu下使用PCL_viewer实现白底黑点效果
    原理:修改背景back color、修改前景front color、修改点云大小point size
    pcl_viewer -bc 255,255,255 -fc 0,0,0 -ps 4 source.pcd
  2. 同时显示基础点云和上色点云
    效果图
    //使用函数
    pcl::visualization::PCLVisualizer::Ptr
    simpleVis(pcl::visualization::PCLVisualizer::Ptr viewer, pcl::PointCloud<pcl::PointXYZ>::ConstPtr cloud_base,
              pcl::PointCloud<pcl::PointXYZ>::ConstPtr cloud_key = nullptr)
    { // --------------------------------------------
        // -----Open 3D viewer and add point cloud-----
        // --------------------------------------------
        viewer->setBackgroundColor(255, 255, 255);
        pcl::visualization::PointCloudColorHandlerCustom<pcl::PointXYZ> color_handler_base(cloud_base, 0, 0, 0);
        viewer->addPointCloud<pcl::PointXYZ>(cloud_base, color_handler_base, "base cloud");
        viewer->setPointCloudRenderingProperties(pcl::visualization::PCL_VISUALIZER_POINT_SIZE, 3, "base cloud");
    
        if (cloud_key != nullptr)
        {
            pcl::visualization::PointCloudColorHandlerCustom<pcl::PointXYZ> color_handler_key(cloud_key, 255, 0, 0);
            viewer->addPointCloud<pcl::PointXYZ>(cloud_key, color_handler_key, "key cloud");
            viewer->setPointCloudRenderingProperties(pcl::visualization::PCL_VISUALIZER_POINT_SIZE, 3, "key cloud");
        }
    
        viewer->addCoordinateSystem(1.0, "global");
        viewer->initCameraParameters();
        return (viewer);
    }
    
    调用方式
    pcl::visualization::PCLVisualizer::Ptr viewer(new pcl::visualization::PCLVisualizer("3D Viewer"));
    viewer = simpleVis(viewer, cloud, cloud_filtered);//白底,cloud点云黑色,cloud_filtered点云红色
    viewer->spin();
    
  3. 左右两窗口分别显示点云
    参考链接: pcl可视化:在一个视图窗口下显示两片点云,并设置点云颜色及背景色
    pcl::visualization::PCLVisualizer::Ptr
    simpleVis2(pcl::visualization::PCLVisualizer::Ptr viewer, pcl::PointCloud<pcl::PointXYZ>::ConstPtr cloud1,
               pcl::PointCloud<pcl::PointXYZ>::ConstPtr cloud2)
    {
        // 在一个视图里显示两张点云图
        int v1(0);
        viewer->createViewPort(0.0, 0.0, 1.0 / 2.0, 1.0, v1);
        viewer->setBackgroundColor(28, 28, 28, v1);
        viewer->addText("Radius:0.01", 10, 10, "v1 text", v1);
        pcl::visualization::PointCloudColorHandlerCustom<pcl::PointXYZ> source_color(cloud1, 0, 0, 0);
        viewer->addPointCloud<pcl::PointXYZ>(cloud1, source_color, "sample cloud1", v1);
    
        int v2(0);
        viewer->createViewPort(1.0 / 2.0, 0.0, 1.0, 1.0, v2);
        viewer->setBackgroundColor(28, 28, 28, v2);
        viewer->addText("Radius:0.1", 10, 10, "v2 text", v2);
        pcl::visualization::PointCloudColorHandlerCustom<pcl::PointXYZ> source_color2(cloud2, 0, 0, 0);
        viewer->addPointCloud<pcl::PointXYZ>(cloud2, source_color2, "sample cloud2", v2);
    
        viewer->setPointCloudRenderingProperties(pcl::visualization::PCL_VISUALIZER_POINT_SIZE, 3, "sample cloud1");
        viewer->setPointCloudRenderingProperties(pcl::visualization::PCL_VISUALIZER_POINT_SIZE, 3, "sample cloud2");
    
        viewer->addCoordinateSystem(1.0, "global");
        viewer->initCameraParameters();
        return (viewer);
    }
    
    调用方式与2类似
    pcl::visualization::PCLVisualizer::Ptr viewer(new pcl::visualization::PCLVisualizer("3D Viewer"));
    viewer = simpleVis(viewer, cloud1, cloud2);
    viewer->spin();
    

空间平面点云旋转到指定平面

  1. 函数

    void change2XOY(const pcl::PointCloud<pcl::PointXYZ>::Ptr &cloud, pcl::PointCloud<pcl::PointXYZ>::Ptr &cloud_filtered)
    {
        // 计算原点云协方差矩阵
        Eigen::Matrix3f covariance_matrix;
        Eigen::Vector4f centroid;
        pcl::compute3DCentroid(*cloud, centroid);
        pcl::computeCovarianceMatrixNormalized(*cloud, centroid, covariance_matrix);
    
        // 求解原点云特征向量和特征值
        Eigen::SelfAdjointEigenSolver<Eigen::Matrix3f> eigen_solver(covariance_matrix, Eigen::ComputeEigenvectors);
        Eigen::Vector3f n1 = eigen_solver.eigenvectors().col(0);
    
        // 定义目标平行面的法向量n2
        Eigen::Vector3f n2(0, 0, 1); // 目标平面法向量
    
        // 求解旋转轴,即求解垂直于原平面法向量n1与目标平面法向量n2的向量
        Eigen::Vector3f axis = n1.cross(n2).normalized(); // 叉乘求得旋转轴,normalized()用于将向量归一化
    
        // 求解n1与n2之间的夹角φ
        float angle = std::acos(n1.dot(n2) / (n1.norm() * n2.norm())); // 夹角φ
    
        Eigen::AngleAxisf rotation(angle, axis);
        Eigen::Matrix3f rotationMatrix = rotation.toRotationMatrix();
    
        std::cout << "Rotation Matrix:\n"
                  << rotationMatrix << std::endl;
    
        Eigen::Matrix4f Transform = Eigen::Matrix4f::Identity();	 // 创建一个4x4的单位矩阵(齐次变换矩阵)
        Transform.block<3, 3>(0, 0) = rotationMatrix;				//将前述旋转矩阵赋值到齐次变换矩阵上
    
        // 假设你已经将平面点云数据加载到cloud中
        pcl::transformPointCloud(*cloud, *cloud_filtered, Transform);
    }
    
  2. 调用:

    pcl::PointCloud<pcl::PointXYZ>::Ptr cloud(new pcl::PointCloud<pcl::PointXYZ>);
    pcl::PCDReader reader;
    reader.read<pcl::PointXYZ>("source.pcd", *cloud);
    
    pcl::PointCloud<pcl::PointXYZ>::Ptr cloud_XOY(new pcl::PointCloud<pcl::PointXYZ>);      // 存储二次初步滤波结果
    change2XOY(cloud, cloud_XOY);//旋转后点云保存至cloud_XOY
    
  3. 补充:绕指定轴旋转

    // 点云绕z轴旋转
    float rotation_angle = -3; // 旋转角度(单位:度)
    Eigen::Affine3f rotation_transform = Eigen::Affine3f::Identity();
    rotation_transform.rotate(Eigen::AngleAxisf(rotation_angle * M_PI / 180.0, Eigen::Vector3f::UnitZ()));
    pcl::transformPointCloud(*current_pc_ptr, *cloud_trans_ptr, rotation_transform);
    
  • 22
    点赞
  • 19
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值