PCL中的3D特征

PCL中的3D特征

  • PCL中的3D特征
    • 理论入门
    • 如何传递输入
    • 法线估计例子

PCL中的3D特征

理论入门

来自[RusuDissertation]:

在他们原生表示中, 如 3D 映射系统概念中定义的那样,使用它们的笛卡尔坐标 x、y、z 相对于给定原点简单地表示。假设坐标系的原点不随时间变化,则在 t1 和 t2 处获取的两个点 p1 和 p2 可能具有相同的坐标。然而,比较这些点是一个不适定的问题,因为即使它们在某些距离度量(例如欧几里德度量)方面相等,但它们可以在完全不同的表面上进行采样,因此当与其他点放在一起时代表完全不同的信息在他们附近的周围点。那是因为不能保证时间在 t1 和 t2 之间没有改变。一些采集设备可能会提供采样点的额外信息,

由于各种原因需要比较点的应用程序需要更好的特性和度量,以便能够区分几何表面。因此,作为具有笛卡尔坐标的单一实体的 3D 点的概念消失了, 取而代之的是一个新概念,即局部描述符** 。文献中有大量描述相同概念的不同命名方案,例如 形状描述符 几何特征, 但对于本文档的其余部分,它们将被称为 点特征表示。

通过包括周围的邻居,可以在特征公式中推断和捕获底层采样表面几何形状,这有助于解决歧义比较问题。理想情况下,对于位于相同或相似表面上的点,结果特征将非常相似(相对于某些度量),而对于不同表面上的点,结果特征将非常相似,如下图所示。一个 好的 点特征表示与 坏的 点特征表示不同*,它能够在以下情况下捕获相同的局部表面特征:*

  • 刚性变换——即数据中的 3D 旋转和 3D 平移不应影响合成特征向量 F 估计;
  • 变化的采样密度-原则上,一个或多或少密集采样的局部表面补丁应该具有相同的特征向量签名;
  • 噪声-在数据中存在轻微噪声的情况下,点特征表示必须在其特征向量中保留相同或非常相似的值。

在这里插入图片描述

通常,PCL 特征使用近似方法来计算查询点的最近邻居,使用快速 kd 树查询。我们对两种类型的查询感兴趣:

  • 确定查询点的k(用户给定参数)邻居(也称为k-search);
  • 确定一个查询点在半径为r的球体内的所有邻居(也称为radius-search)。

注意:

有关正确的kr值应该是什么的讨论,请参阅pclpy OC-Tree “体素内的邻居搜索”、“K 最近邻搜索”和“半径内的邻居搜索”-CSDN博客。

如何传递输入

由于 PCL 中几乎所有类都继承自基本pcl::PCLBase类,因此pcl::Feature类以两种不同的方式接受输入数据:

  1. 一个完整的点云数据集,通过setInputCloud (PointCloudConstPtr &) -强制

    任何特征估计类都将尝试估计给定输入云中每个点的特征。

  2. 点云数据集的子集,通过setInputCloud (PointCloudConstPtr &)setIndices (IndicesConstPtr &) 给出-可选

    任何特征估计类都将尝试估计给定输入云中每个点的特征,该点在给定索引列表中具有索引。默认情况下,如果没有给出一组索引,则将考虑云中的所有点。

此外,可以通过附加调用**setSearchSurface (PointCloudConstPtr &)**指定要使用的点邻居集。此调用是可选的,当未给出搜索面时,默认使用输入点云数据集。

因为**setInputCloud()*总是需要的,所以我们可以使用<setInputCloud(), setIndices(), setSearchSurface()>*创建最多四种组合。假设我们有两个点云,P={p_1, p_2, …p_n} 和 Q={q_1, q_2, …, q_n}。下图显示了所有四种情况:

在这里插入图片描述

  • setIndices() = false, setSearchSurface() = false - 这无疑是 PCL 中最常用的情况,其中用户只是输入单个 PointCloud 数据集并期望在云中的所有点估计某个特征。

    由于我们不希望根据是否给出一组索引和/或搜索表面来维护不同的实现副本,因此每当索引 = false 时,PCL 都会创建一组内部索引(作为std::vector)基本上指向整个数据集(索引=1…N,其中 N 是云中的点数)。

    在上图中,这对应于最左边的情况。首先,我们估计 p_1 的最近邻居,然后是 p_2 的最近邻居,依此类推,直到我们用尽 P 中的所有点。

  • setIndices() = true, setSearchSurface() = false - 如前所述,特征估计方法只会计算那些在给定索引向量中有索引的点的特征;

    在上图中,这对应于第二种情况。在这里,我们假设 p_2 的索引不是给定的索引向量的一部分,因此不会在 p2 估计邻居或特征。

  • setIndices() = false, setSearchSurface() = true - 与第一种情况一样,将对作为输入给出的所有点的特征进行估计,但是,在setSearchSurface() 中给出的底层相邻表面将用于获取输入的最近邻点,而不是输入云本身;

    在上图中,这对应于第三种情况。如果 Q={q_1, q_2} 是另一个作为输入给出的云,不同于 P,并且 P 是 Q 的搜索表面,那么 q_1 和 q_2 的邻居将从 P 计算。

  • setIndices() = true, setSearchSurface() = true - 这可能是最罕见的情况,其中索引和搜索表面都被给出。在这种情况下,将使用setSearchSurface() 中给出的搜索表面信息,仅为<input,indices> 对中的一个子集估计特征。

    最后,在上图中,这对应于最后一个(最右边)的情况。在这里,我们假设 q_2 的索引不是为 Q 给出的索引向量的一部分,因此不会在 q2 估计邻居或特征。

应该使用**setSearchSurface()**时最有用的例子是,当我们有一个非常密集的输入数据集,但我们不想估计其中所有点的特征,而是估计使用pcl_keypoints 中的方法发现的某些关键点=时,或者在云的下采样版本(例如,使用pcl::VoxelGrid过滤器获得)。在这种情况下,我们通过setInputCloud()传递下采样/关键点输入,并将原始数据作为setSearchSurface() 传递

法线估计例子

输入一旦确定,就可使用查询点的相邻点来估计局部特征表示,这表示捕获查询点周围的底层采样表面的几何形状。描述表面几何形状的一个重要问题是首先推断其在坐标系中的方向,即估计其法线。表面法线是表面的重要属性,在许多领域(例如计算机图形应用程序)中大量使用,以应用生成阴影和其他视觉效果的正确光源(有关更多信息,请参阅[RusuDissertation])。

from pclpy import pcldef multiCloudShow(cloud1, cloud2):"""Args:多点云可视化在同一个窗口cloud1:  点云数据cloud2:  点云数据"""viewer = pcl.visualization.PCLVisualizer("viewer")  # 建立可刷窗口对象 窗口名 viewersingle_color = pcl.visualization.PointCloudColorHandlerCustom.PointXYZ(cloud1, 255.0, 0, 0.0)  # 将点云设置为红色viewer.addPointCloud(cloud1,  # 要添加到窗口的点云数据。single_color,  # 指定点云的颜色"sample cloud1",  # 添加的点云命名)  # 点云添加到的视图single_color = pcl.visualization.PointCloudColorHandlerCustom.PointXYZ(cloud2, 0.0, 255.0, 0.0)  # 将点云设置为绿色viewer.addPointCloud(cloud2,  # 要添加到窗口的点云数据。single_color,  # 指定点云的颜色"sample cloud2",  # 添加的点云命名)  # 点云添加到的视图# 窗口建立while not viewer.wasStopped():viewer.spinOnce(10)if __name__ == '__main__':# 加载点云cloud = pcl.PointCloud.PointXYZ()reader = pcl.io.PCDReader()reader.read("res/table_scene_lms400.pcd", cloud)# 估计法线# 为输入数据集中的所有点估计一组表面法线ne = pcl.features.NormalEstimation.PointXYZ_Normal()ne.setInputCloud(cloud)tree = pcl.search.KdTree.PointXYZ()   # 建立kd树ne.setSearchMethod(tree)cloud_normals = pcl.PointCloud.Normal()  # 法线对象ne.setRadiusSearch(0.003)  # 搜索半径为 0.0003ne.compute(cloud_normals)  # 计算法线print(cloud_normals.size())# 为输入数据集中的点子集估计一组表面法线。ne = pcl.features.NormalEstimation.PointXYZ_Normal()ne.setInputCloud(cloud)tree = pcl.search.KdTree.PointXYZ()ne.setSearchMethod(tree)ind = pcl.PointIndices()[ind.indices.append(i) for i in range(0, cloud.size() // 2)]  # 去点云的下标ne.setIndices(ind)  # 将下标进行提取得的点云cloud_normals = pcl.PointCloud.Normal()ne.setRadiusSearch(0.003)ne.compute(cloud_normals)print(cloud_normals.size())# 为输入数据集中的所有点估计一组表面法线,但使用另一个数据集估计它们的最近邻ne = pcl.features.NormalEstimation.PointXYZ_Normal()cloud_downsampled = pcl.PointCloud.PointXYZ()  # 获取一个降采样的点云 方法比较多,这里使用voxelized方法vox = pcl.filters.VoxelGrid.PointXYZ()vox.setInputCloud(cloud)vox.setLeafSize(0.005, 0.005, 0.005)  # 0.005*0.005*0.005 内保存一个点云vox.filter(cloud_downsampled)ne.setInputCloud(cloud_downsampled)ne.setSearchSurface(cloud)tree = pcl.search.KdTree.PointXYZ()ne.setSearchMethod(tree)cloud_normals = pcl.PointCloud.Normal()ne.setRadiusSearch(0.003)ne.compute(cloud_normals)print(cloud_normals.size())

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

如若内容造成侵权/违法违规/事实不符,请联系编程知识网进行投诉反馈email:809451989@qq.com,一经查实,立即删除!

相关文章

pyqt教程

一、组件安装配置 1.安装组件 在Anaconda Prompt下进入自己的python环境 pip install PyQt5 pip install PyQt5-tools 2.vscode安装插件 3.配置路径 配置Pyuic:Cmd与Qtdesigner:Path路径 1.Pyuic:Cmd路径 一般是在你安装的python环境下的 \Scripts\pyuic5.exe 2.Qtdesigner:P…

蓝桥杯Java B组历年真题(2013年-2019年)

一、2013年真题 1、世纪末的星期 使用日期类判断就行&#xff0c;这里使用LocalDate&#xff0c;也可以使用Calendar类 答案 2099 使用LocalDate import java.time.LocalDate; import java.time.format.DateTimeFormatter; // 1:无需package // 2: 类名必须Main, 不可修改p…

if语句用法

if语句是单条件分支语句 定义&#xff1a;根据一个条件来控制程序执行流程(如图3.2)。 语法格式&#xff1a; if&#xff08;表达式&#xff09;{ 若干语句 } ★注意★&#xff1a; ① 表达式的值必须是boolean 型&#xff1b; ② 不能用0代表false&#xff1b;用1代表 true&am…

简单数据类型和复杂数据类型

1. 简单数据类型 null是个特例: 2. 复杂数据类型 3. 堆和栈 注意&#xff1a; JavaScript 中是没有堆和栈的概念的&#xff0c;通过堆栈的概念可以更好的理解代码的一些执行方式&#xff0c;便于将来学习其他语言。 4. 简单数据类型传参 总结&#xff1a;简单数据类型传参传…

JAVA对象内存模型

Java对象内存模型 > 一个Java对象在内存中包括3个部分&#xff1a;对象头、实例数据和对齐填充 > > 数据 内存 – CPU 寄存器 -127 补码 10000001 - 11111111 32位的处理器 一次能够去处理32个二进制位 4字节的数据 64位操作系统 8字节 2的64次方的寻址空间 指针压…

机器学习 -- 梯度下降算法加深

梯度下降算法 在机器学习中&#xff0c;梯度下降算法常用于最小化代价函数&#xff08;或损失函数&#xff09;&#xff0c;以此来优化模型的参数。代价函数衡量的是模型预测值与实际值之间的差异。通过最小化这个函数&#xff0c;我们可以找到模型预测最准确的参数。 代价函…

【数据结构与算法】动态规划法解题20240302

这里写目录标题 一、198. 打家劫舍1、动态规划五部曲 二、213. 打家劫舍 II 一、198. 打家劫舍 你是一个专业的小偷&#xff0c;计划偷窃沿街的房屋。每间房内都藏有一定的现金&#xff0c;影响你偷窃的唯一制约因素就是相邻的房屋装有相互连通的防盗系统&#xff0c;如果两间…

读人工不智能:计算机如何误解世界笔记07_自动驾驶

1. 认知能力 1.1. 认知能力是人工智能从一开始就面临的核心挑战 1.2. 卡雷尔机器人 1.2.1. 解决卡雷尔问题的关键在于提前了解障碍物的位置&#xff0c;并让卡雷尔绕过它们 1.2.2. 人类程序员可以看到网格&#xff0c;即卡雷尔世…

Docker中使用Tomcat并部署war工程

系列文章目录 文章目录 系列文章目录前言一、构建镜像二、运行镜像三、列出正在运行的容器四、停止正在运行的容器 前言 前些天发现了一个巨牛的人工智能学习网站&#xff0c;通俗易懂&#xff0c;风趣幽默&#xff0c;忍不住分享一下给大家。点击跳转到网站&#xff0c;这篇文…

网域图片的访问下载路径

网域图片的本身内容资源在网络空间中的访问下载路径

java 正则表达式介绍

Java正则表达式是一种强大的文本处理工具&#xff0c;它允许你进行模式匹配、搜索和文本操作。正则表达式提供了一种简洁、灵活的方式来处理字符串&#xff0c;可以用于各种应用场景&#xff0c;如数据验证、文本解析、搜索和替换等。 正则表达式的基础知识 正则表达式…

分类问题经典算法 | 多分类问题 | Softmax回归:梯度下降

目录 一. 多分类问题解决策略1. 一对一策略 OVO (One-vs-One)2. 一对剩余策略 OVR&#xff08;One-vs-Rest&#xff09; 二. Softmax回归算法 【前景回顾】 这里我们先来总结Logistic回归算法&#xff1a; 模型函数 p s i g m o i d ( w x b ) p sigmoid(wxb) psigmoid(wx…