PCL 计算3DSC并可视化

news2024/10/9 21:08:07

目录

一、概述

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;
}

三、实现效果

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处:http://www.coloradmin.cn/o/2200020.html

如若内容造成侵权/违法违规/事实不符,请联系多彩编程网进行投诉反馈,一经查实,立即删除!

相关文章

【C++】——继承【上】

P. S.&#xff1a;以下代码均在VS2019环境下测试&#xff0c;不代表所有编译器均可通过。 P. S.&#xff1a;测试代码均未展示头文件stdio.h的声明&#xff0c;使用时请自行添加。 博主主页&#xff1a;Yan. yan.                        …

MPLS解决BGP路由黑洞问题

文章目录 MPLS应用实验实验配置 MPLS应用实验 实验目的&#xff1a;解决BGP中IBGP邻居之间存在的问题 MPLS解决BGP路由黑洞问题实验 配置完基本的MPLS和BGP操作之后&#xff0c;只有R2和R5上面有两个私网的路由&#xff0c;中间的设备没有私网路由&#xff0c;这时候默认还是走…

Linux源码阅读笔记-USB驱动分析

基础层次详解 通用串行总线&#xff08;USB&#xff09;主要用于连接主机和外部设备&#xff08;协调主机和设备之间的通讯&#xff09;&#xff0c;USB 设备不能主动向主机发送数据。USB 总线采用拓扑&#xff08;树形&#xff09;&#xff0c;主机侧和设备侧的 USB 控制器&a…

IT招聘乱象的全面分析

近年来&#xff0c;IT行业的招聘要求似乎越来越苛刻&#xff0c;甚至有些不切实际。许多企业在招聘时&#xff0c;不仅要求前端工程师具备UI设计能力&#xff0c;还希望后端工程师精通K8S服务器运维&#xff0c;更有甚至希望研发经理掌握所有前后端框架和最新开发技术。这种招聘…

RAG测评关键指标

解读RAG测评&#xff1a;关键指标与应用分析 ©作者|CodeDan 来源|神州问学 一、RAG介绍 1.1 简介 RAG&#xff08;Retrieval-Augmented Generation&#xff09;是一种结合信息检索与文本生成的技术&#xff0c;旨在提高大型语言模型&#xff08;LLM&#xff09;在回答复…

ROS理论与实践学习笔记——4 ROS的常用组件之TF坐标变换

tf:TransForm Frame,坐标变换 坐标系:ROS 中是通过坐标系统开标定物体的,确切的将是通过右手坐标系来标定的。 作用:在 ROS 中用于实现不同坐标系之间的点或向量的转换。 说明:在ROS中坐标变换最初对应的是tf,不过在 hydro 版本开始, tf 被弃用,迁移到 tf2,后者…

docker 搭建 vue3 + vite

vue3发布了,今天就分享一下我使用docker 搭建 vue3 vite 开发环境。至于为什么使用docker搭建&#xff0c;因为多版本可以快速切换&#xff0c;和本地环境避免冲突。好了话不多说我们开始吧。 1. 准备资料 Docker Desktop wsl2 ubuntu 下载地址 : https://www.docker.…

实验室认证需要准备哪些文件材料?

实验室认证需要准备的文件材料通常包括以下几类&#xff1a; 一、法律地位文件 实验室成立文件及营业执照&#xff1a;包括实验室的成立证明文件、单位营业执照等&#xff0c;以证明实验室的法律地位和合法性。 人员任命文件&#xff1a;最高管理者&#xff08;如总经理&…

QT 实现QMessageBox::about()信息自定义显示

这是我记录Qt学习过程的第四篇心得文章&#xff0c;主要是方便自己编写的应用程序显示“关于信息”&#xff0c;对QMessageBox::about()输入信息进行规范&#xff0c;可以设置应用程序名称&#xff0c;通过定义宏从pro文件获取应用程序版本号&#xff0c;以及编译程序的QT版本、…

关于C语⾔内存函数 memcpy memmove memset memcmp

memcpy使⽤和模拟实现 void * memcpy ( void * destination, const void * source, size_t num ); 函数memcpy从source的位置开始向后复制num个字节的数据到destination指向的内存位置。 这个函数在遇到 \0 的时候并不会停下来。 如果source和destination有任何的重叠&am…

Linux环境通过APT 仓库安装版PostgreSQL 数据库实战

Linux环境通过APT 仓库安装版PostgreSQL 数据库是运维人员常见的需求之一&#xff0c;今天我们一步一步演示一下&#xff1a; 1、添加 PostgreSQL APT 仓库 确保你的系统更新&#xff0c;然后添加 PostgreSQL 的官方 APT 仓库。 sudo apt update sudo apt install -y wget w…

原来机器学习那么简单——决策树回归

引言&#xff1a; 在正文开始之前&#xff0c;首先给大家介绍一个不错的人工智能学习教程&#xff1a;https://www.captainbed.cn/bbs。其中包含了机器学习、深度学习、强化学习等系列教程&#xff0c;感兴趣的读者可以自行查阅。 一、算法介绍 回归树是决策树的一种&#xff…

[已完结] Authentication Lab —— 靶场笔记合集

Authentication Labhttps://authlab.digi.ninja/ 0x01&#xff1a;Authentication Lab 靶场简介 Authentication Lab 是由 DigiNinja 提供的&#xff0c;一个专注于身份验证和授权漏洞的实验平台。该网站旨在提供一个可以让用户探索和实践各种常见与不常见的身份验证与授权漏…

带你深入浅出设计模式:十、责任链模式:设计模式中的多米诺骨牌效应

此为设计模式第十谈&#xff01; 用总-分-总的结构和生活化的例子给你讲解设计模式&#xff01; 码农不易&#xff0c;各位学者学到东西请点赞收藏支持支持&#xff01; 开始部分&#xff1a; 总&#xff1a;责任链的本质是使多个对象都有机会处理请求&#xff0c;将这些对象…

指针和引用区别

目录 指针 指针类型 野指针 二级指针 Const修饰指针 引用 引用的作用 常引用 引用和指针的对比 引用能够完全替换指针吗&#xff1f; 指针 指针是C语言中的概念&#xff0c;它是指计算机储存内容的地址。指针它的值指向存在电脑储存器中另一个地方的值。通过地址能找…

玩机搞机基本常识-----如何在 Android 中实现默认开启某个功能 修改方法列举

我们有时候需要对安卓系统进行修改。实现其中的某些功能。让用户使用得心应手。节约时间。那么如果要实现系统中的有些功能选项开启或者关闭。就需要对系统有一定的了解。那么在 Android 中实现默认开启某个功能可以通过以下几种方式&#xff1a; 一、在应用的设置中添加选项 …

Chromium 中js Fetch API接口c++代码实现(二)

Chromium 中JavaScript Fetch API接口c代码实现&#xff08;一&#xff09;-CSDN博客 接着上一篇继续介绍调用&#xff0c;上函数堆栈。 1、打开http://192.168.8.1/chfs/shared/test/test02.html 此标签进程ID12484&#xff0c; 2、打开vs附加上此进程ID12484 3、点击页面测…

uni-app 开发的应用快速构建成鸿蒙原生应用

uni-app 是一个使用 Vue.js 开发所有前端应用的框架&#xff0c;它支持编译到 iOS、Android、小程序等多个平台。对于 HarmonyOS&#xff08;鸿蒙系统&#xff09;&#xff0c;uni-app 提供了特定的支持&#xff0c;允许开发者构建鸿蒙原生应用。 一、uni-app 对 HarmonyOS 的支…

分治算法(7)_归并排序_计算右侧小于当前元素的个数

个人主页&#xff1a;C忠实粉丝 欢迎 点赞&#x1f44d; 收藏✨ 留言✉ 加关注&#x1f493;本文由 C忠实粉丝 原创 分治算法(7)_归并排序_计算右侧小于当前元素的个数 收录于专栏【经典算法练习】 本专栏旨在分享学习算法的一点学习笔记&#xff0c;欢迎大家在评论区交流讨论&…

公司防泄密软件哪个好?6款公司内部文件防泄密软件,2024超好用推荐!

企业的核心机密就如同生命之源&#xff0c;然而&#xff0c;数据泄露的风险也随之而来&#xff0c;让不少企业头疼不已。 面对这一挑战&#xff0c;选择一款高效、可靠的防泄密软件显得尤为重要。 那么&#xff0c;公司防泄密软件哪个好&#xff1f; 接下来&#xff0c;就让我…