自学内容网 自学内容网

PCL ISS关键点提取

目录

一、概述

1.1原理

1.2实现步骤

1.3应用场景

二、代码实现

2.1关键函数

2.1.1 ISS关键点提取

2.1.2 可视化函数

2.2完整代码

三、实现效果


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

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


一、概述

        ISS(Intrinsic Shape Signatures)关键点提取是一种基于几何特征的方法,能够从点云中提取具有局部显著性的点。ISS算法基于协方差矩阵的特征值来检测局部稳定点。它通过设置显著性半径和非极大值抑制等参数,有效地去除冗余点,从而提取代表性强的关键点。

1.1原理

        ISS算法的基本思想是通过分析局部区域的形状特征,从中提取具有显著性特征的关键点。对于每个点,通过计算协方差矩阵的特征值,得到该点的局部形状描述。具体来说:

  1. 协方差矩阵计算:在给定半径内,计算点云局部邻域的协方差矩阵。
  2. 特征值分析:通过协方差矩阵的特征值来分析局部结构。通常,通过特征值比率(λ2/λ1和λ3/λ2)来筛选出那些局部形状显著的点。
  3. 非极大值抑制:为确保提取出的关键点具有较强的显著性,需要对点云进行非极大值抑制处理,确保最终结果中的关键点彼此距离较远且具有显著性。

1.2实现步骤

  1. 读取点云数据。
  2. 设置ISS算法参数,如协方差矩阵计算半径、非极大值抑制半径等。
  3. 应用ISS关键点提取算法,得到关键点。
  4. 将原始点云与提取的关键点进行可视化对比。

1.3应用场景

  1. 三维形状分析:在物体识别、形状匹配等应用中,提取局部显著性强的关键点。
  2. 点云简化:对点云进行显著性简化,仅保留最具代表性的点。
  3. 特征点匹配:在配准、特征匹配中,提取关键点并进行特征匹配。

二、代码实现

2.1关键函数

2.1.1 ISS关键点提取

void extractISSKeypoints(pcl::PointCloud<pcl::PointXYZ>::Ptr cloud, pcl::PointCloud<pcl::PointXYZ>::Ptr keypoints)
{
    pcl::ISSKeypoint3D<pcl::PointXYZ, pcl::PointXYZ> iss;
    pcl::search::KdTree<pcl::PointXYZ>::Ptr tree(new pcl::search::KdTree<pcl::PointXYZ>());
    iss.setInputCloud(cloud);  // 输入点云
    iss.setSearchMethod(tree); // 设置搜索方法
    iss.setNumberOfThreads(4); // 使用4个线程进行计算
    iss.setSalientRadius(1.0f); // 协方差矩阵计算的半径
    iss.setNonMaxRadius(1.5f);  // 非极大值抑制半径
    iss.setThreshold21(0.65);   // 特征值比率阈值
    iss.setThreshold32(0.5);    // 特征值比率阈值
    iss.setMinNeighbors(10);    // 最少邻居数
    iss.compute(*keypoints);    // 计算关键点
}

2.1.2 可视化函数

void visualizeISSKeypoints(pcl::PointCloud<pcl::PointXYZ>::Ptr cloud, pcl::PointCloud<pcl::PointXYZ>::Ptr keypoints)
{
    boost::shared_ptr<pcl::visualization::PCLVisualizer> viewer(new pcl::visualization::PCLVisualizer("ISS Keypoints Viewer"));

    int v1(0), v2(0);
    viewer->createViewPort(0, 0.0, 0.5, 1.0, v1);
    viewer->setBackgroundColor(1.0, 1.0, 1.0, v1); // 设置白色背景
    viewer->addText("Original Point Cloud", 10, 10, "v1_text", v1);

    viewer->createViewPort(0.5, 0.0, 1.0, 1.0, v2);
    viewer->setBackgroundColor(0.98, 0.98, 0.98, v2); // 设置灰色背景
    viewer->addText("ISS Keypoints", 10, 10, "v2_text", v2);

    // 原始点云显示为红色
    pcl::visualization::PointCloudColorHandlerCustom<pcl::PointXYZ> original_color(cloud, 255, 0, 0);
    viewer->addPointCloud(cloud, original_color, "original_cloud", v1);

    // 关键点显示为绿色
    pcl::visualization::PointCloudColorHandlerCustom<pcl::PointXYZ> keypoints_color(keypoints, 0, 255, 0);
    viewer->addPointCloud(keypoints, keypoints_color, "keypoints_cloud", v2);

    // 设置点大小
    viewer->setPointCloudRenderingProperties(pcl::visualization::PCL_VISUALIZER_POINT_SIZE, 3, "original_cloud");
    viewer->setPointCloudRenderingProperties(pcl::visualization::PCL_VISUALIZER_POINT_SIZE, 5, "keypoints_cloud");

    // 添加坐标系
    viewer->addCoordinateSystem(1.0);

    while (!viewer->wasStopped())
    {
        viewer->spinOnce(100);
        boost::this_thread::sleep(boost::posix_time::microseconds(100000));
    }
}

2.2完整代码

#include <iostream>
#include <pcl/io/pcd_io.h>
#include <pcl/point_types.h>
#include <pcl/keypoints/iss_3d.h>
#include <pcl/visualization/pcl_visualizer.h>
#include <boost/thread/thread.hpp>

// ISS关键点提取函数
void extractISSKeypoints(pcl::PointCloud<pcl::PointXYZ>::Ptr cloud, pcl::PointCloud<pcl::PointXYZ>::Ptr keypoints)
{
    pcl::ISSKeypoint3D<pcl::PointXYZ, pcl::PointXYZ> iss;
    pcl::search::KdTree<pcl::PointXYZ>::Ptr tree(new pcl::search::KdTree<pcl::PointXYZ>());
    iss.setInputCloud(cloud);  // 设置输入点云
    iss.setSearchMethod(tree); // 设置搜索方法
    iss.setNumberOfThreads(4); // 使用4个线程进行计算
    iss.setSalientRadius(1.0f); // 设置显著性半径
    iss.setNonMaxRadius(1.5f);  // 非极大值抑制半径
    iss.setThreshold21(0.65);   // 第二个和第一个特征值比的上限
    iss.setThreshold32(0.5);    // 第三个和第二个特征值比的上限
    iss.setMinNeighbors(10);    // 设置最小邻居数
    iss.compute(*keypoints);    // 计算关键点
}

// 可视化函数
void visualizeISSKeypoints(pcl::PointCloud<pcl::PointXYZ>::Ptr cloud, pcl::PointCloud<pcl::PointXYZ>::Ptr keypoints)
{
    boost::shared_ptr<pcl::visualization::PCLVisualizer> viewer(new pcl::visualization::PCLVisualizer("ISS Keypoints Viewer"));

    int v1(0), v2(0);
    viewer->createViewPort(0, 0.0, 0.5, 1.0, v1);
    viewer->setBackgroundColor(1.0, 1.0, 1.0, v1); // 设置白色背景
    viewer->addText("Original Point Cloud", 10, 10, "v1_text", v1);

    viewer->createViewPort(0.5, 0.0, 1.0, 1.0, v2);
    viewer->setBackgroundColor(0.98, 0.98, 0.98, v2); // 设置灰色背景
    viewer->addText("ISS Keypoints", 10, 10, "v2_text", v2);

    // 原始点云显示为红色
    pcl::visualization::PointCloudColorHandlerCustom<pcl::PointXYZ> original_color(cloud, 255, 0, 0);
    viewer->addPointCloud(cloud, original_color, "original_cloud", v1);

    // 关键点显示为绿色
    pcl::visualization::PointCloudColorHandlerCustom<pcl::PointXYZ> keypoints_color(keypoints, 0, 255, 0);
    viewer->addPointCloud(keypoints, keypoints_color, "keypoints_cloud", v2);

    // 设置点大小
    viewer->setPointCloudRenderingProperties(pcl::visualization::PCL_VISUALIZER_POINT_SIZE, 3, "original_cloud");
    viewer->setPointCloudRenderingProperties(pcl::visualization::PCL_VISUALIZER_POINT_SIZE, 3, "keypoints_cloud");

    // 添加坐标系
    viewer->addCoordinateSystem(1.0);

    while (!viewer->wasStopped())
    {
        viewer->spinOnce(100);
        boost::this_thread::sleep(boost::posix_time::microseconds(100000));
    }
}

int main(int, char** argv)
{
    // 读取点云
    pcl::PointCloud<pcl::PointXYZ>::Ptr cloud(new pcl::PointCloud<pcl::PointXYZ>);
    if (pcl::io::loadPCDFile<pcl::PointXYZ>("Armadillo.pcd", *cloud) == -1)
    {
        PCL_ERROR("Could not read file\n");
        return -1;
    }
    std::cout << "读取点云个数: " << cloud->points.size() << std::endl;

    // 提取ISS关键点
    pcl::PointCloud<pcl::PointXYZ>::Ptr keypoints(new pcl::PointCloud<pcl::PointXYZ>());
    extractISSKeypoints(cloud, keypoints);

    std::cout << "ISS关键点提取结果: " << keypoints->points.size() << std::endl;

    // 可视化
    visualizeISSKeypoints(cloud, keypoints);

    return 0;
}

三、实现效果


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

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