内容抄自CSDN点云侠:2024最新版】PCL点云处理算法汇总(C++长期更新版)。质量无忧,可放心复制粘贴。
一、概述
主曲率的计算是点云处理中重要的一步,用于理解点云局部表面几何结构的弯曲程度。主曲率的大小直接反映了表面在某点附近的变化趋势,较大的主曲率意味着表面弯曲剧烈,较小的主曲率则表示表面趋于平坦。
二、代码
#include <iostream>
#include <pcl/io/pcd_io.h>
#include <pcl/point_types.h>
#include <pcl/features/normal_3d.h>
#include <pcl/features/principal_curvatures.h>
#include <pcl/visualization/pcl_visualizer.h>
#include <boost/thread/thread.hpp>
using namespace std;
int main(int argc, char** argv)
{
// 1. 读取点云数据
pcl::PointCloud<pcl::PointXYZ>::Ptr cloud(new pcl::PointCloud<pcl::PointXYZ>);
pcl::io::loadPCDFile<pcl::PointXYZ>("dragon.pcd", *cloud);
// 2. 创建用于计算法向量的对象
pcl::NormalEstimation<pcl::PointXYZ, pcl::Normal> ne;
pcl::search::KdTree<pcl::PointXYZ>::Ptr tree(new pcl::search::KdTree<pcl::PointXYZ>());
pcl::PointCloud<pcl::Normal>::Ptr normals(new pcl::PointCloud<pcl::Normal>);
ne.setInputCloud(cloud); // 设置输入点云
ne.setSearchMethod(tree); // 设置搜索方法
ne.setRadiusSearch(0.03); // 设置搜索半径
ne.compute(*normals); // 计算法向量
// 3. 创建用于计算主曲率的对象
pcl::PrincipalCurvaturesEstimation<pcl::PointXYZ, pcl::Normal, pcl::PrincipalCurvatures> pce;
pcl::PointCloud<pcl::PrincipalCurvatures>::Ptr curvatures(new pcl::PointCloud<pcl::PrincipalCurvatures>);
pce.setInputCloud(cloud); // 设置输入点云
pce.setInputNormals(normals); // 设置法向量
pce.setSearchMethod(tree); // 设置搜索方法
pce.setRadiusSearch(0.03); // 设置搜索半径
pce.compute(*curvatures); // 计算主曲率
// 4. 可视化原始点云与法向量
// 创建PCL可视化器
pcl::visualization::PCLVisualizer::Ptr viewer(new pcl::visualization::PCLVisualizer("Curvatures Viewer"));
// 创建视口1,显示原始点云
int vp_1;
viewer->createViewPort(0.0, 0.0, 0.5, 1.0, vp_1);
viewer->setBackgroundColor(0.0, 0.0, 0.0, vp_1); // 设置白色背景
viewer->addText("Original PointCloud", 10, 10, "vp1_text", vp_1);
pcl::visualization::PointCloudColorHandlerCustom<pcl::PointXYZ> cloud_color_handler(cloud, 255, 0, 0); // 红色点云
viewer->addPointCloud(cloud, cloud_color_handler, "original_cloud", vp_1);
// 创建视口2,显示主曲率
int vp_2;
viewer->createViewPort(0.5, 0.0, 1.0, 1.0, vp_2);
viewer->setBackgroundColor(0.01, 0.01, 0.01, vp_2); // 设置浅灰色背景
viewer->addText("Normals", 10, 10, "vp2_text", vp_2);
viewer->addPointCloudNormals<pcl::PointXYZ, pcl::Normal>(cloud, normals, 10, 0.05, "normals", vp_2);
// 启动可视化循环
while (!viewer->wasStopped())
{
viewer->spinOnce(100);
boost::this_thread::sleep(boost::posix_time::microseconds(100000));
}
return 0;
}