目录
一、概述
1.1原理
1.2实现步骤
1.3应用场景
二、代码实现
2.1关键函数
2.2完整代码
三、实现效果
3.1原始点云
3.2处理后点云
PCL点云算法汇总及实战案例汇总的目录地址链接:
PCL点云算法与项目实战案例汇总(长期更新)
一、概述
1.1原理
曲率是衡量点云中某一点周围表面弯曲程度的指标。通过计算每个点的曲率,可以将曲率值映射为颜色,从而在点云中更直观地表现表面特征。曲率值越大,表面越尖锐或复杂。PCL 提供了计算曲率和将曲率值映射为颜色的功能,允许我们根据曲率值对点云进行可视化渲染。
具体地,曲率 𝐶 的计算公式如下:
其中,𝜆0≤𝜆1≤𝜆2是协方差矩阵的特征值。通过将计算得到的曲率值映射为颜色,可以在点云的可视化中突出显示表面的不同特征。
1.2实现步骤
- 计算点云的法向量和曲率。
- 创建并设置颜色映射,将曲率值映射为颜色。
- 使用设置的颜色显示点云。
1.3应用场景
- 表面特征分析:通过渲染曲率,可以识别和分析点云中的边缘、角点等表面特征。
- 物体分类与识别:在三维重建中,通过曲率渲染可以帮助更好地识别物体的形状和类型。
- 质量控制与检测:在工业检测中,通过曲率分析和渲染,可以识别产品表面的缺陷,如刮痕或凸起。
二、代码实现
2.1关键函数
1.计算法向量和曲率:
- pcl::NormalEstimation<pcl::PointXYZ, pcl::Normal>:用于估算点云中每个点的法向量和曲率。
- pcl::search::KdTree<pcl::PointXYZ>:用于支持法向量估算的近邻搜索。
2.颜色映射:
- pcl::PointCloud<pcl::PointXYZRGB>:用于存储带颜色信息的点云。
- pcl::visualization::PCLVisualizer 和 addPointCloud:用于将颜色映射后的点云添加到可视化窗口中进行显示。
2.2完整代码
#include <pcl/io/pcd_io.h>
#include <pcl/features/normal_3d.h>
#include <pcl/point_types.h>
#include <pcl/visualization/pcl_visualizer.h>
#include <pcl/point_cloud.h>
#include <pcl/common/common.h>int main(int argc, char** argv)
{// 1. 创建一个用于存储点云数据的PointCloud智能指针对象pcl::PointCloud<pcl::PointXYZ>::Ptr cloud(new pcl::PointCloud<pcl::PointXYZ>);// 2. 读取PCD格式的点云文件到cloud对象中if (pcl::io::loadPCDFile<pcl::PointXYZ>("bunny.pcd", *cloud) == -1){PCL_ERROR("Couldn't read the PCD file \n");return (-1);}// 3. 创建法向量估计对象,并设置输入点云pcl::NormalEstimation<pcl::PointXYZ, pcl::Normal> ne;ne.setInputCloud(cloud);// 4. 创建一个KdTree对象用于近邻搜索,这在计算法向量时会用到pcl::search::KdTree<pcl::PointXYZ>::Ptr tree(new pcl::search::KdTree<pcl::PointXYZ>());ne.setSearchMethod(tree);// 5. 创建一个用于存储法向量和曲率的PointCloud对象pcl::PointCloud<pcl::Normal>::Ptr cloud_normals(new pcl::PointCloud<pcl::Normal>);// 6. 设置估算法向量时的搜索半径,这个半径决定了在计算法向量和曲率时考虑的邻域范围ne.setRadiusSearch(0.03);// 7. 计算法向量和曲率,并将结果存储在cloud_normals中ne.compute(*cloud_normals);// 8. 创建一个带颜色信息的点云对象,用于存储根据曲率设置颜色后的点云数据pcl::PointCloud<pcl::PointXYZRGB>::Ptr colored_cloud(new pcl::PointCloud<pcl::PointXYZRGB>);colored_cloud->width = cloud->width;colored_cloud->height = cloud->height;colored_cloud->points.resize(cloud->points.size());// 9. 遍历每个点,将曲率值映射为颜色,并赋值给colored_cloudfor (size_t i = 0; i < cloud->points.size(); ++i){// 将原始点云中的坐标信息复制到有颜色的点云对象中colored_cloud->points[i].x = cloud->points[i].x;colored_cloud->points[i].y = cloud->points[i].y;colored_cloud->points[i].z = cloud->points[i].z;// 获取当前点的曲率值float curvature = cloud_normals->points[i].curvature;// 根据曲率值设置颜色,曲率大的点用红色表示,曲率小的点用蓝色表示uint8_t r = static_cast<uint8_t>(255 * curvature); // 红色分量uint8_t g = 0; // 绿色分量uint8_t b = static_cast<uint8_t>(255 * (1.0 - curvature)); // 蓝色分量// 将颜色值组合成一个32位整数,并赋给点的rgb字段uint32_t rgb = (static_cast<uint32_t>(r) << 16 |static_cast<uint32_t>(g) << 8 | static_cast<uint32_t>(b));colored_cloud->points[i].rgb = *reinterpret_cast<float*>(&rgb);}// 10. 创建一个PCLVisualizer对象,用于可视化点云数据pcl::visualization::PCLVisualizer::Ptr viewer(new pcl::visualization::PCLVisualizer("Curvature Viewer"));// 11. 设置可视化窗口的背景色为黑色viewer->setBackgroundColor(0, 0, 0);// 12. 将带颜色信息的点云添加到可视化窗口中,并设置显示属性viewer->addPointCloud<pcl::PointXYZRGB>(colored_cloud, "colored cloud");viewer->setPointCloudRenderingProperties(pcl::visualization::PCL_VISUALIZER_POINT_SIZE, 2, "colored cloud");// 13. 进入可视化循环,直到用户关闭窗口while (!viewer->wasStopped()){viewer->spinOnce(100);}return 0;
}