自学内容网 自学内容网

PCL 计算3DSC并可视化

目录

一、概述

1.1原理

1.2实现步骤

1.3应用场景

二、代码实现

2.1关键函数

2.1.1 法线计算

2.1.2 3DSC特征计算

2.1.3 可视化3DSC直方图

2.2完整代码

三、实现效果


PCL点云算法汇总及实战案例汇总的目录地址链接:

PCL点云算法与项目实战案例汇总(长期更新)


一、概述

        3D形状上下文(3D Shape Context, 3DSC)是三维点云描述子的一种,它通过将一个点的局部邻域信息映射到球坐标系,并将空间区域划分为多个区域来描述点的局部几何结构。通过计算每个区域内的点数,可以得到描述点局部形状的特征向量。3DSC可以用于点云配准、匹配、物体识别等任务。

1.1原理

3DSC通过以下步骤计算点云描述子:

  1. 对每个点,建立以该点为中心的局部坐标系,并将其邻域内的点投影到球坐标系中。
  2. 将球坐标系分割为不同的体积单元,统计每个体积单元内的点数,生成描述子。
  3. 形状上下文描述子的关键参数包括:
    • 最小半径Rmin:用于定义搜索球面内的最小球半径。
    • 搜索半径Rmax:用于定义计算特征时考虑的最大邻域范围。
    • 点密度半径:用于估算点的局部密度。

1.2实现步骤

  1. 读取点云数据并计算点云法线。
  2. 利用3D形状上下文方法计算3DSC描述子。
  3. 可视化计算的3DSC直方图。

1.3应用场景

  1. 点云配准:通过比较不同点云的3DSC描述子,可以进行点云配准。
  2. 物体识别:在3D物体识别中,3DSC描述子用于描述物体表面的局部几何特征。
  3. 形状匹配:在点云数据中的局部形状匹配任务中,3DSC可以有效地提取局部特征。

二、代码实现

2.1关键函数

2.1.1 法线计算

void computeNormals(pcl::PointCloud<pcl::PointXYZ>::Ptr cloud, pcl::PointCloud<pcl::Normal>::Ptr normals)
{
    pcl::NormalEstimationOMP<pcl::PointXYZ, pcl::Normal> ne;
    pcl::search::KdTree<pcl::PointXYZ>::Ptr tree(new pcl::search::KdTree<pcl::PointXYZ>());
    ne.setNumberOfThreads(10);  // 使用10线程加速计算
    ne.setInputCloud(cloud);    // 输入点云
    ne.setSearchMethod(tree);   // 搜索方法
    ne.setKSearch(10);          // 设置近邻点数量
    ne.compute(*normals);       // 计算法线
}

2.1.2 3DSC特征计算

void compute3DSCDescriptors(pcl::PointCloud<pcl::PointXYZ>::Ptr cloud, pcl::PointCloud<pcl::Normal>::Ptr normals, pcl::PointCloud<pcl::ShapeContext1980>::Ptr descriptors)
{
    pcl::ShapeContext3DEstimation<pcl::PointXYZ, pcl::Normal, pcl::ShapeContext1980> sc;
    sc.setInputCloud(cloud);         // 输入点云
    sc.setInputNormals(normals);     // 输入法线
    pcl::search::KdTree<pcl::PointXYZ>::Ptr tree(new pcl::search::KdTree<pcl::PointXYZ>());
    sc.setSearchMethod(tree);        // 设置搜索方法
    sc.setMinimalRadius(0.02);       // 设置最小半径
    sc.setRadiusSearch(0.03);        // 设置搜索半径
    sc.setPointDensityRadius(0.02);  // 设置点密度半径
    sc.compute(*descriptors);        // 计算3DSC描述子
}

2.1.3 可视化3DSC直方图

void visualize3DSC(pcl::PointCloud<pcl::ShapeContext1980>::Ptr descriptors)
{
    pcl::visualization::PCLPlotter plotter("3DSC Descriptor Plot");
    plotter.setTitle("3D Shape Context Descriptors");
    plotter.setShowLegend(true);
    plotter.addFeatureHistogram(*descriptors, "shape_context", 5);  // 选取第五个点的特征可视化
    plotter.setWindowSize(800, 600);  // 设置窗口大小
    plotter.plot();
}

2.2完整代码

#include <pcl/point_types.h>
#include <pcl/point_cloud.h>
#include <pcl/io/pcd_io.h>
#include <pcl/features/normal_3d_omp.h>
#include <pcl/features/3dsc.h> // 3D形状描述子
#include <pcl/search/kdtree.h>
#include <pcl/visualization/pcl_plotter.h> // 直方图的可视化 

using namespace std;

// 法线计算
void computeNormals(pcl::PointCloud<pcl::PointXYZ>::Ptr cloud, pcl::PointCloud<pcl::Normal>::Ptr normals)
{
    pcl::NormalEstimationOMP<pcl::PointXYZ, pcl::Normal> ne;
    pcl::search::KdTree<pcl::PointXYZ>::Ptr tree(new pcl::search::KdTree<pcl::PointXYZ>());
    ne.setNumberOfThreads(10);  // 使用10线程加速计算
    ne.setInputCloud(cloud);    // 输入点云
    ne.setSearchMethod(tree);   // 搜索方法
    ne.setKSearch(10);          // 设置近邻点数量
    ne.compute(*normals);       // 计算法线
}

// 计算3DSC描述子
void compute3DSCDescriptors(pcl::PointCloud<pcl::PointXYZ>::Ptr cloud, pcl::PointCloud<pcl::Normal>::Ptr normals, pcl::PointCloud<pcl::ShapeContext1980>::Ptr descriptors)
{
    pcl::ShapeContext3DEstimation<pcl::PointXYZ, pcl::Normal, pcl::ShapeContext1980> sc;
    sc.setInputCloud(cloud);         // 输入点云
    sc.setInputNormals(normals);     // 输入法线
    pcl::search::KdTree<pcl::PointXYZ>::Ptr tree(new pcl::search::KdTree<pcl::PointXYZ>());
    sc.setSearchMethod(tree);        // 设置搜索方法
    sc.setMinimalRadius(0.02);       // 设置最小半径
    sc.setRadiusSearch(0.03);        // 设置搜索半径
    sc.setPointDensityRadius(0.02);  // 设置点密度半径
    sc.compute(*descriptors);        // 计算3DSC描述子
}

// 直方图可视化
void visualize3DSC(pcl::PointCloud<pcl::ShapeContext1980>::Ptr descriptors)
{
    pcl::visualization::PCLPlotter plotter("3DSC Descriptor Plot");
    plotter.setTitle("3D Shape Context Descriptors");
    plotter.setShowLegend(true);
    plotter.addFeatureHistogram(*descriptors, "shape_context", 5);  // 选取第五个点的特征可视化
    plotter.setWindowSize(800, 600);  // 设置窗口大小
    plotter.plot();
}

int main(int argc, char** argv)
{
    // 1. 加载点云数据
    pcl::PointCloud<pcl::PointXYZ>::Ptr cloud(new pcl::PointCloud<pcl::PointXYZ>());
    if (pcl::io::loadPCDFile<pcl::PointXYZ>("person2.pcd", *cloud) == -1)
    {
        PCL_ERROR("Could not read file\n");
        return -1;
    }

    // 2. 计算法线
    pcl::PointCloud<pcl::Normal>::Ptr normals(new pcl::PointCloud<pcl::Normal>());
    computeNormals(cloud, normals);
    cout << "法线计算完毕!" << endl;

    // 3. 计算3DSC描述子
    pcl::PointCloud<pcl::ShapeContext1980>::Ptr descriptors(new pcl::PointCloud<pcl::ShapeContext1980>());
    compute3DSCDescriptors(cloud, normals, descriptors);
    cout << "3DSC特征描述子计算完毕!" << endl;

    // 4. 可视化3DSC直方图
    visualize3DSC(descriptors);

    return 0;
}

三、实现效果


原文地址:https://blog.csdn.net/qq_47947920/article/details/142784431

免责声明:本站文章内容转载自网络资源,如本站内容侵犯了原著者的合法权益,可联系本站删除。更多内容请关注自学内容网(zxcms.com)!