当前位置: 首页 > article >正文

PCL 点云SUAN关键点提取

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

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


一、概述

        SUSAN关键点提取是一种基于几何特征的角点检测算法,通过对点云中局部的几何结构进行分析,识别出在局部几何上具有显著性变化的关键点。该算法常用于物体识别、点云配准以及三维重建等领域,具有较高的鲁棒性。

1.1原理

        SUSAN(Smallest Univalue Segment Assimilating Nucleus)是一种基于区域的角点检测方法,它通过对点的局部区域进行分析,提取具有显著几何特征的关键点。SUSAN关键点提取的基本思想是:通过比较每个点的邻域点的特征(如距离、角度、强度等)来评估该点的局部显著性,进而判断该点是否为关键点。

该方法的关键步骤如下:

  1. 邻域搜索:为每个点找到其局部的邻域点。
  2. 计算响应值:基于邻域点的距离、角度、强度等特征,计算每个点的SUSAN响应值。
  3. 非极大值抑制:对响应值进行处理,保留局部的最大响应值点。
  4. 关键点检测:根据响应值和阈值,提取出局部几何显著的点作为关键点。

1.2实现步骤

  1. 读取点云数据。
  2. 初始化SUSAN关键点提取器,并设置参数(如半径、距离阈值、角度阈值、强度阈值等)。
  3. 计算SUSAN关键点,并将关键点存储为新点云。
  4. 对提取出的关键点与原始点云进行可视化展示。

1.3应用场景

  1. 三维物体识别:通过提取物体的关键点,进行特征匹配和识别。
  2. 点云配准:通过关键点对齐不同视角的点云,提高点云配准的精度。
  3. 三维重建:在三维重建过程中,提取几何特征显著的点用于重建和建模。

二、代码实现

2.1关键函数

2.1.1 SUSAN关键点提取

void extractSUSANKeypoints(pcl::PointCloud<pcl::PointXYZ>::Ptr cloud, pcl::PointCloud<pcl::PointXYZ>::Ptr keypoints)
{
    pcl::SUSANKeypoint<pcl::PointXYZ, pcl::PointXYZI> SUSAN;
    pcl::search::KdTree<pcl::PointXYZ>::Ptr tree(new pcl::search::KdTree<pcl::PointXYZ>());
    
    SUSAN.setInputCloud(cloud);             // 设置输入点云
    SUSAN.setSearchMethod(tree);            // 设置邻域搜索的方式
    SUSAN.setNumberOfThreads(6);            // 设置多线程加速的线程数
    SUSAN.setRadius(3.0f);                  // 设置法向量估计和非极大值抑制的半径
    SUSAN.setDistanceThreshold(0.001f);     // 设置距离阈值
    SUSAN.setAngularThreshold(0.0001f);     // 设置用于角点检测的角度阈值
    SUSAN.setIntensityThreshold(0.1f);      // 设置用于角点检测的强度阈值
    SUSAN.setNonMaxSupression(true);        // 对响应应用非最大值抑制

    pcl::PointCloud<pcl::PointXYZI>::Ptr keypointsI(new pcl::PointCloud<pcl::PointXYZI>());
    SUSAN.compute(*keypointsI); // 提取关键点

    pcl::copyPointCloud(*keypointsI, *keypoints); // 转换为XYZ格式的关键点
}

2.1.2 可视化函数

void visualizeSUSANKeypoints(pcl::PointCloud<pcl::PointXYZ>::Ptr cloud, pcl::PointCloud<pcl::PointXYZ>::Ptr keypoints)
{
    boost::shared_ptr<pcl::visualization::PCLVisualizer> viewer(new pcl::visualization::PCLVisualizer("SUSAN 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("SUSAN Keypoints", 10, 10, "v2_text", v2);

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

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

    // 设置点大小
    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/susan.h> // SUSAN关键点提取头文件
#include <pcl/visualization/pcl_visualizer.h>
#include <boost/thread/thread.hpp>

// SUSAN关键点提取函数
void extractSUSANKeypoints(pcl::PointCloud<pcl::PointXYZ>::Ptr cloud, pcl::PointCloud<pcl::PointXYZ>::Ptr keypoints)
{
    pcl::SUSANKeypoint<pcl::PointXYZ, pcl::PointXYZI> SUSAN;
    pcl::search::KdTree<pcl::PointXYZ>::Ptr tree(new pcl::search::KdTree<pcl::PointXYZ>());

    SUSAN.setInputCloud(cloud);             // 设置输入点云
    SUSAN.setSearchMethod(tree);            // 设置邻域搜索的方式
    SUSAN.setNumberOfThreads(6);            // 设置多线程加速的线程数
    SUSAN.setRadius(1.0f);                  // 设置法向量估计和非极大值抑制的半径
    SUSAN.setDistanceThreshold(0.001f);     // 设置距离阈值
    SUSAN.setAngularThreshold(0.0001f);     // 设置用于角点检测的角度阈值
    SUSAN.setIntensityThreshold(0.1f);      // 设置用于角点检测的强度阈值
    SUSAN.setNonMaxSupression(true);        // 对响应应用非最大值抑制

    pcl::PointCloud<pcl::PointXYZI>::Ptr keypointsI(new pcl::PointCloud<pcl::PointXYZI>());
    SUSAN.compute(*keypointsI); // 提取关键点

    pcl::copyPointCloud(*keypointsI, *keypoints); // 转换为XYZ格式的关键点
}

// 可视化SUSAN关键点
void visualizeSUSANKeypoints(pcl::PointCloud<pcl::PointXYZ>::Ptr cloud, pcl::PointCloud<pcl::PointXYZ>::Ptr keypoints)
{
    boost::shared_ptr<pcl::visualization::PCLVisualizer> viewer(new pcl::visualization::PCLVisualizer("SUSAN 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("SUSAN Keypoints", 10, 10, "v2_text", v2);

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

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

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

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

    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("加载点云失败\n");
        return -1;
    }
    cout << "点云点数为:" << cloud->points.size() << endl;
    // 提取SUSAN关键点
    pcl::PointCloud<pcl::PointXYZ>::Ptr keypoints(new pcl::PointCloud<pcl::PointXYZ>());
    extractSUSANKeypoints(cloud, keypoints);
    cout << "关键点提取点数为:" << keypoints->points.size() << endl;
    // 可视化关键点和原始点云
    visualizeSUSANKeypoints(cloud, keypoints);

    return 0;
}

三、实现效果


http://www.kler.cn/news/340225.html

相关文章:

  • ADAS中的安全性功能与舒适性功能总结
  • Python可变映射类型MutableMapping
  • 单细胞转录组 —— Cell Ranger 原始数据处理
  • 【深度学习基础模型】极限学习机(Extreme Learning Machines, ELM)详细理解并附实现代码。
  • 进程的状态的理解(概念+Linux)
  • 手搓一个Eval#Datawhale组队学习大模型任务Task4
  • 问卷的二维码怎么做?教你一招快速在线制作表单二维码
  • 【基于YOLOv5的反光衣检测预警系统】可检测图片、视频、摄像头,支持GPU加速检测以及语音播报预警
  • PHP函数 strstr() 和 stristr() 有什么区别
  • 反应香精市场报告:预计2030年全球市场规模将达到264.3亿美元
  • 遇到 MySQL 中的两个 Root 用户:问题分析与解决
  • fiddler抓包18-2_导出jmeter、postman脚本(带请求头)
  • springboot宿舍管理-计算机毕业设计源码40740
  • Linux安装elasticsearch单机版
  • ai写作,五款软件助你快速写作!
  • 分治算法(6)_归并排序_交易逆序对的总数
  • 灵芝玉叶膏简介
  • 影刀RPA实战:Excel密码与字典功能指令
  • InfoGAN:通过信息最大化生成对抗网络进行可解释的表示学习
  • React 插入不转义的html