基于PCL库实现附加功能
可视化
- ubuntu下使用PCL_viewer实现白底黑点效果
原理:修改背景back color、修改前景front color、修改点云大小point size
pcl_viewer -bc 255,255,255 -fc 0,0,0 -ps 4 source.pcd
- 同时显示基础点云和上色点云
调用方式//使用函数 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();
- 左右两窗口分别显示点云
参考链接: pcl可视化:在一个视图窗口下显示两片点云,并设置点云颜色及背景色
调用方式与2类似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); }
pcl::visualization::PCLVisualizer::Ptr viewer(new pcl::visualization::PCLVisualizer("3D Viewer")); viewer = simpleVis(viewer, cloud1, cloud2); viewer->spin();
空间平面点云旋转到指定平面
-
函数
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); }
-
调用:
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
-
补充:绕指定轴旋转
// 点云绕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);