两个点云的稳健配准

2024-02-22

我需要找到两个 3D 点云之间的变换和旋转差异。为此,我正在寻找点云库,因为它看起来很理想。

在干净的测试数据上,我有迭代最近点(ICP)工作,但得到奇怪的结果(尽管我可能错误地实现了它)。 我有pcl::estimateRigidTransformation工作,而且看起来更好,尽管我认为处理噪声数据会更糟。

我的问题是:

两朵云会有噪音,虽然它们应该包含相同的点,但也会有一些差异。处理这个问题的最佳方法是什么?

我应该首先在两个云中找到相应的功能然后使用estimateTransform?或者我应该看看RANSAC去除异常值的函数?是ICP比这更好的方法estimateRigidTransform?


设置强大的点云配准算法可能是一项具有挑战性的任务,需要正确设置各种不同的选项、超参数和技术才能获得强大的结果。

但是,那点云库 https://pointclouds.org/documentation/group__registration.html附带了一整套预实现的函数来解决此类任务。剩下要做的唯一一件事就是了解每个块正在做什么,然后建立一个由这些块相互堆叠组成的所谓 ICP 管道。

ICP 管道可以遵循两种不同的路径:

1. 迭代配准算法

更简单的路径立即开始,在输入云 (IC) 上应用迭代最近点算法,通过始终使用最近点方法,使用固定参考云 (RC) 对其进行数学计算。 ICP 乐观地假设两个点云足够接近(旋转 R 和平移 T 的先验良好)并且配准将收敛,无需进一步初始对齐。

当然,这条路径可能会陷入局部最小值,因此性能非常差,因为它很容易被给定输入数据中的任何类型的不准确所愚弄。

2. 基于特征的配准算法

为了克服这个问题,人们致力于开发各种方法和想法来克服表现不佳的注册。与单纯的迭代配准算法相比,基于特征的配准首先致力于寻找两个点云之间更高级别的对应关系,以加快处理速度并提高准确性。这些方法被封装起来,然后嵌入到配准管道中,形成完整的配准模型。

下面的图片来自于PCL文档 https://pcl.readthedocs.io/projects/tutorials/en/latest/registration_api.html显示了这样的注册管道:

正如您所看到的,成对配准应该通过不同的计算步骤来运行才能获得最佳性能。单个步骤是:

  1. 数据采集​​:输入云和参考云被输入到算法中。

  2. 估计关键点:一个关键点(兴趣点 https://en.wikipedia.org/wiki/Interest_point_detection) 是点云中的一个点,具有以下特征:

    1. 它有一个清晰的、最好是数学上有充分根据的定义,
    2. 它在图像空间中有明确的位置,
    3. 兴趣点周围的局部图像结构局部信息内容丰富

    点云中的这些显着点非常有用,因为它们的总和表征了点云,并有助于区分点云的不同部分。

    pcl::NarfKeypoint
    pcl::ISSKeypoint3D< PointInT, PointOutT, NormalT >
    pcl::HarrisKeypoint3D< PointInT, PointOutT, NormalT >
    pcl::HarrisKeypoint6D< PointInT, PointOutT, NormalT >
    pcl::SIFTKeypoint< PointInT, PointOutT >
    pcl::SUSANKeypoint< PointInT, PointOutT, NormalT, IntensityT >
    

    详细资料:PCL 关键点 - 文档 https://pointclouds.org/documentation/group__keypoints.html

  3. 描述关键点 - 特征描述符:检测到关键点后,我们继续为每个关键点计算一个描述符。 “局部描述符是点的局部邻域的紧凑表示。与描述完整对象或点云的全局描述符相反,局部描述符尝试仅在点周围的局部邻域中相似形状和外观,因此非常适合表示它从匹配上来说。”(德克·霍尔兹等人) https://www.ais.uni-bonn.de/papers/RAM_2015_Holz_PCL_Registration_Tutorial.pdf

    pcl::FPFHEstimation< PointInT, PointNT, PointOutT >
    pcl::NormalEstimation< PointInT, PointOutT >
    pcl::NormalEstimationOMP< PointInT, PointOutT >
    pcl::OURCVFHEstimation< PointInT, PointNT, PointOutT >
    pcl::PrincipalCurvaturesEstimation< PointInT, PointNT, PointOutT >
    pcl::IntensitySpinEstimation< PointInT, PointOutT >
    

    详细资料:PCL 功能 - 文档 https://pointclouds.org/documentation/group__features.html

  4. 对应估计:下一个任务是找到点云中找到的关键点之间的对应关系。通常,人们会利用计算出的局部特征描述符,并将它们中的每一个与另一点云中相应的对应部分进行匹配。然而,由于来自相似场景的两次扫描不一定具有相同数量的特征描述符,因为一个云可以比另一个云拥有更多的数据,因此我们需要运行单独的对应拒绝过程。

    pcl::registration::CorrespondenceEstimation< PointSource, PointTarget, Scalar >
    pcl::registration::CorrespondenceEstimationBackProjection< PointSource, PointTarget, NormalT, Scalar >
    pcl::registration::CorrespondenceEstimationNormalShooting< PointSource, PointTarget, NormalT, Scalar >
    
  5. 信件拒绝:执行信件拒绝的最常见方法之一是使用RANSAC https://en.wikipedia.org/wiki/RANSAC(随机样本共识)。但 PCL 附带了更多拒绝算法,值得仔细研究一下:

    pcl::registration::CorrespondenceRejectorSampleConsensus< PointT >
    pcl::registration::CorrespondenceRejectorDistance
    pcl::registration::CorrespondenceRejectorFeatures::FeatureContainer< FeatureT >
    pcl::registration::CorrespondenceRejectorPoly< SourceT, TargetT >
    

    详细资料:PCL 模块注册 - 文档 https://pointclouds.org/documentation/group__registration.html

  6. 变换估计:计算两个点云之间的鲁棒对应关系后,使用绝对方向算法来计算 6DOF(6 个自由度)变换,该变换应用于输入云以匹配参考点云。有许多不同的算法方法可以做到这一点,但是 PCL 包括基于奇异值分解 https://en.wikipedia.org/wiki/Singular_value_decomposition(奇异值分解)。计算 4x4 矩阵来描述匹配点云所需的旋转和平移。

    pcl::registration::TransformationEstimationSVD< PointSource, PointTarget, Scalar >
    

    详细资料:PCL 模块注册 - 文档 https://pointclouds.org/documentation/group__registration.html

进一步阅读:

  • PCL点云注册 https://pcl.readthedocs.io/projects/tutorials/en/latest/registration_api.html
  • 点云库注册 https://www.ais.uni-bonn.de/papers/RAM_2015_Holz_PCL_Registration_Tutorial.pdf
  • PCL - 功能如何工作 https://pcl.readthedocs.io/projects/tutorials/en/latest/how_features_work.html
本文内容由网友自发贡献,版权归原作者所有,本站不承担相应法律责任。如您发现有涉嫌抄袭侵权的内容,请联系:hwhale#tublm.com(使用前将#替换为@)

两个点云的稳健配准 的相关文章

  • C++ 维护子类对象的混合集合

    如果我在这里错过了一个相当基本的概念 我很抱歉 但我正在尝试弄清楚如何维护多个类类型的集合 所有类类型都派生自同一个父类 并且在检索它们时仍然可以访问它们的特定于子类的方法从集合中 作为上下文 我有一个基类 BaseClass 和许多类 例
  • 静态只读字符串数组

    我在我的 Web 应用程序中使用静态只读字符串数组 基本上数组有错误代码 我将所有类似的错误代码保存在一个数组中并检查该数组 而不是检查不同常量字符串中的每个错误代码 like public static readonly string m
  • CLR 2.0 与 4.0 性能比较?

    如果在 CLR 4 0 下运行 为 CLR 2 0 编译的 NET 程序会运行得更快吗 应用程序配置
  • 使用 lambda 表达式注册类型

    我想知道如何在 UnityContainer 中实现这样的功能 container RegisterType
  • 适合初学者的良好调试器教程[关闭]

    Closed 这个问题不符合堆栈溢出指南 help closed questions 目前不接受答案 有谁知道一个好的初学者教程 在 C 中使用调试器 我感觉自己好像错过了很多 我知道怎么做 单步执行代码并查看局部变量 虽然这常常给我带来问
  • 以编程方式读取 SQL Server 查询计划建议的 SQL 特定执行的索引?

    如果我在 SSMS 中运行此命令 set showplan xml on GO exec some procedure arg1 arg2 arg3 GO set showplan xml off GO 我获得查询执行中涉及的完整调用堆栈的
  • GetType() 在 Type 实例上返回什么?

    我在一些调试过程中遇到了这段代码 private bool HasBaseType Type type out Type baseType Type originalType type GetType baseType GetBaseTyp
  • IdentityServer 4 对它的工作原理感到困惑

    我阅读和观看了很多有关 Identity Server 4 的内容 但我仍然对它有点困惑 因为似乎有很多移动部件 我现在明白这是一个单独的项目 它处理用户身份验证 我仍然不明白的是用户如何注册它 谁存储用户名 密码 我打算进行此设置 Rea
  • 如何在C(Linux)中的while循环中准确地睡眠?

    在 C 代码 Linux 操作系统 中 我需要在 while 循环内准确地休眠 比如说 10000 微秒 1000 次 我尝试过usleep nanosleep select pselect和其他一些方法 但没有成功 一旦大约 50 次 它
  • 如何填充 ToolStripComboBox?

    我发现它很难将数据绑定到ToolStripComboBox 好像没有这个ValueMember and DisplayMember特性 怎么绑定呢 访问toolstripcombobox中包装的组合框并访问其ValueMember Disp
  • 如何使用 Castle Windsor 将对象注入到 WCF IErrorHandler 实现中?

    我正在使用 WCF 开发一组服务 该应用程序正在使用 Castle Windsor 进行依赖注入 我添加了一个IErrorHandler通过属性添加到服务的实现 到目前为止一切正常 这IErrorHandler对象 一个名为FaultHan
  • 函数参数的默认参数是否被视为该参数的初始值设定项?

    假设我有这样的函数声明 static const int R 0 static const int I 0 void f const int r R void g int i I 根据 dcl fct default 1 如果在参数声明中指
  • Python 属性和 Swig

    我正在尝试使用 swig 为一些 C 代码创建 python 绑定 我似乎遇到了一个问题 试图从我拥有的一些访问器函数创建 python 属性 方法如下 class Player public void entity Entity enti
  • 类型约束

    我有以下类层次结构 class Header IEnumerable
  • 在视口中查找 WPF 控件

    Updated 这可能是一个简单或复杂的问题 但在 wpf 中 我有一个列表框 我用一个填充数据模板从列表中 有没有办法找出特定的数据模板项位于视口中 即我已滚动到其位置并且可以查看 目前我连接到了 listbox ScrollChange
  • 为什么这个二维指针表示法有效,而另一个则无效[重复]

    这个问题在这里已经有答案了 这里我编写了一段代码来打印 3x3 矩阵的对角线值之和 这里我必须将矩阵传递给函数 矩阵被传递给指针数组 代码可以工作 但问题是我必须编写参数的方式如下 int mat 3 以下导致程序崩溃 int mat 3
  • 在mysql连接字符串中添加应用程序名称/程序名称[关闭]

    Closed 这个问题需要细节或清晰度 help closed questions 目前不接受答案 我正在寻找一种解决方案 在连接字符串中添加应用程序名称或程序名称 以便它在 MySQL Workbench 中的 客户端连接 下可见 SQL
  • C++ new * char 不为空

    我有一个问题 我在 ASIO 中开发服务器 数据包采用尖头字符 当我创建新字符时 例如char buffer new char 128 我必须手动将其清理为空 By for int i 0 i lt 128 i buffer i 0x00
  • 灵气序列解析问题

    我在使用 Spirit Qi 2 4 编写解析器时遇到一些问题 我有一系列键值对以以下格式解析
  • 如何将十六进制字符串转换为无符号长整型?

    我有以下十六进制值 CString str str T FFF000 如何将其转换为unsigned long 您可以使用strtol作用于常规 C 字符串的函数 它使用指定的基数将字符串转换为 long long l strtol str

随机推荐

  • 使用Output0Buffer类时SSIS脚本转换错误

    我试图通过提供用 c 编写的脚本来帮助我们的 dba 以便他可以在他的 ScriptComponent 中使用它 我有一个输入文件 逐行处理它并在 Output0Buffer 中创建一行 如中所述 我已经编写了测试方法并且工作正常 但是在将
  • 如何使用邮递员发布对象和列表

    我在用邮递员打包的应用程序 https chrome google com webstore detail postman fhbjgbiflinjbdggehcddcbncdddomop hl en发送帖子请求 我想请求以下控制器 如何使
  • 给定的 ColumnMapping 与源或目标中的任何列都不匹配

    我不知道为什么我会遇到上述异常 请有人看看 DataTable DataTable Time new DataTable Star Schema Dimension Time DataColumn Sowing Day new DataCo
  • 在选项卡栏控制器 -> 导航控制器 -> 视图控制器的层次结构中旋转视图控制器

    我的应用程序的视图控制器层次结构设置如下 UITabBarController UINavigationController UIViewController UINavigationController UIViewController
  • 有没有 SMTP 转 HTTP 的免费服务(Email 转 POST)?

    有人向我指出了该服务smtp2web http www smtp2web com 不久前 但我一直在尝试 但似乎不起作用 还有其他人吗 有什么方法可以在红宝石中实现这一点吗 我写一封电子邮件并发送给lanceJpollard smtp2we
  • 如何在没有 SSL 的情况下接受 Web API 上的身份验证?

    我正在构建一个与以下内容非常相似的 Web API堆栈溢出 http api stackoverflow com提供 然而 就我而言 安全很重要 因为数据是私有的 我必须使用 HTTP 我无法使用 SSL 您向我推荐什么解决方案 EDIT
  • 如何根据某些正则表达式模式提取字符串的“部分”?

    在 JavaScript 中 给定一个正则表达式模式和一个字符串 var pattern this 0 9a zA Z that 0 9a zA Z var str this 12 that 34 如何返回包含以下内容的数组 12 34 以
  • 如何将 .scss 文件作为全局导入到 app.js 父文件中?

    我正在启动一个 Angular 项目 并按照以下步骤导入 scss 文件 https github com AngularClass angular starter wiki How to include SCSS in component
  • 为什么使用 ARC + NSZombieEnabled 时对象未释放

    我将我的应用程序转换为 ARC 并注意到当视图控制器被释放时 在我的视图控制器之一中分配的对象没有被释放 我花了一段时间才弄清楚原因 我在调试时为我的项目启用了 启用僵尸对象 结果证明这就是原因 考虑以下应用程序逻辑 1 用户调用actio
  • 在 3D 空间中旋转图像的一部分

    设置如下 这是一个电子商务艺术网站 其中一些绘画是画布转移 这幅画环绕画布的侧面 顶部和底部 我们拥有整幅画的高分辨率图像 但我们想要显示的是图像的准 3D 表示 您可以在其中看到画作的侧面如何环绕画布 这是我正在谈论的内容的粗略草图 我的
  • 尝试在 openSUSE 上安装 pip 时出错

    我正在尝试部署pip在我的生产服务器上 但有一个不合逻辑的错误 它尝试安装已安装的组件但没有成功 gt sudo zypper in python pip Loading repository data Reading installed
  • iText:使用 LocationTextExtractionStrategy 从 pdf 文件中提取的文本顺序错误

    我正在使用 iText 从特定位置的 pdf 文件中提取一些文本 为此 我使用 LocationTextExtractionStrategy public static void main String args throws Except
  • 实施“more”Unix实用程序命令

    我正在努力实施more命令 我想知道如果有管道我该如何理解 例如 如果我从 shell 中输入 cat file1 file2 more 我怎样才能在 more 的实现中处理这个问题 并且是实施more可以开源吗 实际上 我无法成功读取 s
  • 使用 Selenium Webdriver 测试某个元素是否获得焦点

    我真的很惊讶我在互联网上找不到使用 Selenium Webdriver 测试元素焦点的参考资料 我想检查当尝试提交表单但缺少必填字段时 焦点何时移至空字段 但我看不到任何使用 WebDriver API 执行此操作的方法 我将能够使用找到
  • 如何获取给定 ascii 值的字符

    如何获取给定 ascii 代码的 ascii 字符 例如我正在寻找一种方法 给定代码 65 将返回 A Thanks 您的意思是 A astring 或 A 一个char int unicode 65 char character char
  • 在 Python 中搜索对象列表

    假设我正在创建一个简单的类 其工作方式与 C 风格结构类似 仅保存数据元素 我试图弄清楚如何在对象列表中搜索属性等于特定值的对象 下面是一个简单的例子来说明我正在尝试做的事情 例如 class Data pass myList for i
  • Vue mousemove仅在mousedown之后

    如何仅在首先单击元素时触发鼠标移动 我正在尝试将其用于音频播放器时间线 player time bar mousedown setNewCurrentPosition event slider role slider aria valuem
  • 许可 .Net 网站 [关闭]

    Closed 这个问题需要多问focused help closed questions 目前不接受答案 我想知道获得网站许可的首选方法是什么 我使用可编辑的 APSX 文件分发网站的预编译版本 后面的代码被编译到每个页面的单独 DLL 中
  • Shell 脚本从日志中获取过去一小时的异常

    我正在开发脚本 该脚本将 grep 最近一小时的日志并检查任何异常并向Solaris 平台发送电子邮件 我做了以下步骤 grep n h date Y m d H M test logs 上面的命令给了我行号 然后我执行以下操作 tail
  • 两个点云的稳健配准

    我需要找到两个 3D 点云之间的变换和旋转差异 为此 我正在寻找点云库 因为它看起来很理想 在干净的测试数据上 我有迭代最近点 ICP 工作 但得到奇怪的结果 尽管我可能错误地实现了它 我有pcl estimateRigidTransfor