『OPEN3D』1.8 点云的配准理论

点云的配准是将不同的3D点云对齐成一个完成的点云模型;配准的目标是找到两帧点云之间的相对旋转(rotation)与平移(translation),使得两份点云中有重叠的区域能够完好拼接。

点云配准示例图(来自PCL) 

上图为初始的5份点云数据,需要将着几份点云数据拼接成如下图中完整的模型

点云动态配准示例

常见的点云配准方式主要包含ICP配准以及NDT配准以及他们的配准,当然还包括神经网络的点云配准方式。

1、点云配准理论

点云配准需要找到两份点云数据之间点的对应估计,也就是找到两份点云中重叠的部分才可以进行配准,这类配准,对于有确定对应点的配准拥有闭式解(closed form solution)不需要迭代求解即可获取最优值。

       对应点的寻找方式:

1 若为深度相机,则可以借助图像信息来寻找对应的匹配点并投影回3d空间

2 若为两帧点云信息,则可以借助点云特征点来进行确立

不过上诉方法都会出现误匹配,一般会借助RANSAC(随机采样一致性)来得到更为robust的估计。

1 ICP主要为point2point ICP和point2plane两种ICP方式

ICP配准点云时需要有较为准确的初始位姿后再使用该方法进行精配准;ICP的点云配准大体步骤分为如下几步:

1 点的匹配(可以从图像中来或者点云中来)

        1.1 在两帧点云中找到对应的关键点,点云中的关键点一般为特定的几何结构,比如书本的边角,与图像类似;点云中的关键点包括NARF;SIFT;FAST;当然也可以不适用关键点;使用每一个点或者点云中的一部分点来进行配准;不过那样的话会导致计算量过大。

        1.2 特征的描述子;与图像类似,再找到点云的关键点后,需要提取该关键点的描述子信息;通过组合该结构的信息来生成对应的向量用于比对;点云的中描述子包括NARF;FPFH;BRIEF;SIFT等。

2 匹配点估计;给定两帧点云的特征向量集合;通过关键点与描述子来找到重叠区域中相互对应的关键点:对于关键点或特征的匹配,可以使用暴力搜索;kd-tree(FLANN)等方式来进行匹配

3 匹配点对估计;类似与图像中关键点匹配;点云中的关键点匹配也存在许多误匹配;误匹配会影响最终的配准结果;因此此处可以使用ransac或者根据匹配点对的百分位进行截取等方式来进行优化;如果一帧中的某个关键点与另一帧中的多个关键点匹配;则会取最小距离来确定匹配点

4  变换矩阵计算;再得到准确的相互匹配的点云后;则可以计算变换矩阵;

        其中point2point的评估误差为

        point2plane的评估误差为(其中np为点P的法线信息)

        

估计两个点集的R和t可以使用使用SVD或者非线性优化求解; 

1 SVD方法

        给定两对匹配点的点集p{}p{}',对其中第i对匹配点的误差项为:

e{_i} = p{_i} - (R p{_i}'+t)

因此可以对所有点构建最小二乘问题,求得使误差平方和达到极小的R和t:

min{(_R,_t)}\frac{1}{2}\sum_{i=1}^{n}\left \| (p{_i} - (Rp{_i}'+t) ) ) \right \|{_2^2}

分别定义两组点的质心为(此处使用不带下标的项来代表质心):

p = \frac{1}{n}\sum_{i=1}^{n}(p{_i})

p' = \frac{1}{n}\sum_{i=1}^{n}(p{_i}')

在误差函数中进行展开

展开后最后一项元素求和为0(所有p{_i}元素相加减去n个p{_i}的质心p为0),因此优化的结果仅与前两项相关,即

min_{(R,t)}J = \frac{1}{2} \sum_{i=1}^{n}\left | \left | p{_i} - R(p{_i}'-p') \right | \right |^2 + \left \| p -Rp'-t \right \|^2

上式中,只有左边和旋转矩阵R相关,右侧同时R与t。因此只要求得R后令右式为0即可求出t。

ICP的SVD方法流程如下

        1、计算两组匹配点的质心pp',  然后将每个点减去质心得到去质心的坐标:

q{_i} = p{_i} - p

   q{_i}' = p{_i}' - p'

        2、根据上述阐述的优化,计算旋转矩阵:

R{*} =argmin{_R} (\frac{1}{2} \sum_{i=1}^{n}\left | \left | q{_i} - R(q{_i}') \right | \right |^2)

        3、根据计算得到的旋转矩阵计算平移向量t

                t* = p-Rp'        

因此,按照上面的步骤,要先求取两组点集之间的旋转矩阵,所以下面说重点一下R的计算:

\frac{1}{2} \sum_{i=1}^{n}\left | \left | q{_i} - R(q{_i}') \right | \right |^2 = \frac{1}{2} \sum_{i=1}^{n} (q{i}^Tq{_i} + q{_i}'^T R^T R q{_i}' - 2q{_i}^T R q{_i}')

其中第一项q{i}^Tq{_i}与R无关;第二项q{_i}'^T R^T R q{_i}'中因为R为正交矩阵因此R^T R = I,也与R无关;只有最后一项的-2q{_i}^T R q{_i}'与R有关,因此有如下推导:

\sum_{i=1}^{n}(-q{_i}^T R q{_i}') = \sum_{i=1}^{n}-tr(q{_i}^T R q{_i}')=-tr(R\sum_{i=1}^{n}q{_i}'q{_i}'^T)        

               注: 其中tr为trace(迹),有a^Tb = tr(ba^T)

        然后可以使用SVD分解得出最优的旋转矩阵R。

W=\sum_{i=1}^{n}q{_i}'q{_i}'^T

        可知W是一个n*n的矩阵,n为点集的维度,若是点云数据则n=3则W是3*3的矩阵,

若此时W是可逆矩阵,则可以直接通过公式获得最优的旋转矩阵

R = (W^T W)^\frac{1}{2} H^{-1}

但考虑到所有情况,直接对W进行SVD分解也是可以的:

        W = U\sum V^T        

其中\sum为奇异值组成的对角矩阵,对角线元素从大到小排列,UV则为正交矩阵;当W满秩时,R为

        R = UV^T

若R的行列式为负数,则去-R为最优数值。

对这块刚兴趣的同学可以参考Kabsch算法的实现

https://en.wikipedia.org/wiki/Kabsch_algorithmicon-default.png?t=N7T8https://en.wikipedia.org/wiki/Kabsch_algorithm

2 非线性优化

2 open3d中使用ICP

更新中

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

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

相关文章

JPA 方式实现 RESTful API

除了常见的方式实现 RESTful API,还有一种简单的方式实现 RESTful API,那就是用 JPA 方式。首先介绍一下 JPA,它是 Sun 公司推荐的 JAVA 持久化规范,为了简化 ORM 技术而产生。需要注意的是,他只是一套规范&#xff0c…

HarmonyOS4.0系列——02、汉化插件、声明式开发范式ArkTS和类web开发范式

编辑器调整 我们在每次退出编辑器后再次打开会直接进入项目文件中,这样在新建项目用起来很是不方便,所以这里跟着设置一下就好 这样下次进入就不会直接跳转到当时的文件项目中!! 关于汉化 settings → plugins → installe…

什么是 Jest ? Vue2 如何使用 Jest 进行单元测试?Vue2 使用 Jest 开发单元测试实例

什么是Jest? Jest 是一个流行的 JavaScript 测试框架,由 Facebook 开发并维护,专注于简单性和速度。它通常用于编写 JavaScript 和 TypeScript 应用程序的单元测试、集成测试和端到端测试。 特点: 简单易用: Jest 提供简洁的 API 和易于理解的语法,使得编写测试用例变得…

【数据结构】什么是队列?

🦄个人主页:修修修也 🎏所属专栏:数据结构 ⚙️操作环境:Visual Studio 2022 目录 📌队列的定义 📌队列的抽象数据类型 📌队列的顺序存储结构 📌队列的链式存储结构 结语 人生,是一个又一个小小的队列…

探索网络模型与协议:从OSI到HTTPs的原理解析

一、OSI网络模型 OSI(Open Systems Interconnection)七层网络参考模型和TCP/IP四层模型都是用于理解和设计计算机网络的框架,但它们之间存在一些差异。 1、七层 vs 四层 OSI七层网络参考模型: 物理层(Physical Laye…

人力资源管理后台 === 权限应用

目录 1.权限应用-拆分静态路由-动态路由 2.权限应用-根据用户权限添加动态路由 3.权限应用-根据权限显示左侧菜单 4.权限应用-退出登录重置路由 5.权限应用-功能权限-按钮权限标识 6.权限应用-自定义指令应用功能权限 7.其他模块-集成 8.首页-基本结构和数字滚动 9.首页…

17.找出1000之内的所有完数。

文章目录 前言一、题目描述 二、题目分析 三、解题 程序运行代码 前言 本系列为循环结构编程题,点滴成长,一起逆袭。 一、题目描述 一个数如果恰好等于它的因子之和,这个数就称为“完数”。例如,⑥的因子为1、2、3,而…

vue3+ts mitt的使用

安装mitt :npm i mitt -Smain.ts: import mitt from mittconst Mit mitt();declare module vue {export interface ComponentCustomProperties{$Bus:typeof Mit} } app.config.globalProperties.$BusMit在A组件中使用 <template><div><h1>我是A<…

【深度学习】如何找到最优学习率

经过了大量炼丹的同学都知道&#xff0c;超参数是一个非常玄乎的东西&#xff0c;比如batch size&#xff0c;学习率等&#xff0c;这些东西的设定并没有什么规律和原因&#xff0c;论文中设定的超参数一般都是靠经验决定的。但是超参数往往又特别重要&#xff0c;比如学习率&a…

建造者模式-C语言实现

UML类图&#xff1a; 代码实现&#xff1a; #include <stdio.h> #include <stdlib.h>// 产品类 typedef struct {char* part1;char* part2;char* part3; } Product;// 抽象建造者类 typedef struct {void (*buildPart1)(void*, const char*);void (*buildPart2)(v…

RabbitMQ之延迟消息实战

RabbitMQ之延迟消息实战 使用死信交换机实现延迟消息 使用死信交换机的过期时间以及没有消费者进行消费&#xff0c;时间到了就会到死信队列中&#xff0c;由此可以实现延迟消息使用延迟消息插件 前提&#xff1a;需要mq配置插件 延时信息案例实战 把一个30分钟的延迟消息可以…

前端review

关于实时预览vs code中的颜色代码需要安装的插件&#xff0c;包括html文件格式中的颜色代码安装Flutter Color插件 VSCode 前端常用插件集合 1.Auto Close Tag自动闭合HTML/XML标签 2.Auto Rename Tag自动完成另一侧标签的同步修改 3.Beautify格式化代码&#xff0c;值得注…

【高可用架构】Haproxy 和 Keepalived 的区别

Haproxy 和 Keepalived 的区别 1.负载均衡器介绍2.Haproxy 和 Keepalived 的基本概念和特点2.1 Haproxy2.2 Keepalived 3.Haproxy 和 Keepalived 的区别3.1 功能上的区别3.2 架构上的区别3.3 配置上的区别 4.总结 1.负载均衡器介绍 负载均衡器是一种解决高并发和高可用的常用的…

【开源】基于Vue和SpringBoot的农家乐订餐系统

项目编号&#xff1a; S 043 &#xff0c;文末获取源码。 \color{red}{项目编号&#xff1a;S043&#xff0c;文末获取源码。} 项目编号&#xff1a;S043&#xff0c;文末获取源码。 目录 一、摘要1.1 项目介绍1.2 项目录屏 二、功能模块2.1 用户2.2 管理员 三、系统展示四、核…

C/C++内存管理,malloc,realloc,calloc,new,delete详解!!!

1.初步了解内存中各个区间存储的数据特征 1.栈区&#xff1a;存储一些局部变量、函数参数、返回值等&#xff0c;跟函数栈振有关&#xff0c;出了作用域&#xff0c;生命周期结束。 2.堆区&#xff1a;用于动态开辟空间&#xff0c;如果不主动销毁空间&#xff0c;则程序运行结…

因式分解的几何意义

本来准备和女儿一起玩一道几何题&#xff0c;想想还是算了&#xff0c;不如讲点更有趣的。 任何因式分解都是在堆积木&#xff0c;不信你看&#xff1a; 二项式定理&#xff0c;洋灰三角&#xff0c;都是面积&#xff0c;体积&#xff0c;超维体积的拼接&#xff0c;一个大超…

Python 安装django-cors-headers解决跨域问题

一、PythonCorsHeaders概念 PythonCorsHeaders是一个轻量级的Python工具&#xff0c;用于解决跨域HTTP请求的问题。它允许你指定哪些网站或IP地址可以访问你的站点&#xff0c;并控制这些站点可以访问哪些内容。 现代网站越来越多地使用Ajax技术&#xff0c;使得浏览器能够从不…

【人工智能】Chatgpt的训练原理

前言 前不久&#xff0c;在学习C语言的我写了一段三子棋的代码&#xff0c;但是与我对抗的电脑是没有任何思考的&#xff0c;你看了这段代码就理解为什么了&#xff1a; void computerMove(char Board[ROW][COL], int row, int col) {while (1){unsigned int i rand() % ROW, …

设计模式之十二:复合模式

模式通常被一起使用&#xff0c;并被组合在同一个解决方案中。 复合模式在一个解决方案中结合两个或多个模式&#xff0c;以解决一般或重复发生的问题。 首先重新构建鸭子模拟器&#xff1a; package headfirst.designpatterns.combining.ducks;public interface Quackable …

【网络】传输层 --- 详解TCP协议

目录 一、协议段格式及其策略确认应答(ACK)机制6个标志位超时重传流量控制滑动窗口1、先谈滑动窗口一般情况2、再谈特殊窗口 拥塞控制拥塞窗口 延迟应答&&捎带应答面向字节流粘包问题 二、三次握手和四次挥手三次握手为什么是3次&#xff1f;不是2、4、5、6次呢 四次挥…