open3d ICP 配准

文章目录

  • Three common registration techniques
    • Point-to-point technique
    • Point-to-plane registration
  • ICP registration
    • Helper visualization function
    • Input
    • Global registration
      • Extract geometric feature
      • Input
      • RANSAC
    • Point-to-point ICP
    • Point-to-plane ICP
  • References

Three common registration techniques

假设有一个点集 P \boldsymbol{P} P 在源表面 S P \mathcal{S}_P SP,另一个点集 Q \boldsymbol{Q} Q 在目的表面 S Q \mathcal{S}_Q SQ。如果在每个表面都有 K K K 个点,那么配准问题可以看作一个刚体变换 T = [ R ∣ t ] \boldsymbol{T}=[\boldsymbol{R}|\boldsymbol{t}] T=[Rt],最小化下面的对准误差: ϵ = ∑ k = 1 K ∥ Q k − ( R P k + t ) ∥ 2 \epsilon=\sum_{k=1}^K \| \boldsymbol{Q}_k-(\boldsymbol{R}\boldsymbol{P}_k+\boldsymbol{t})\|^2 ϵ=k=1KQk(RPk+t)2

在这里插入图片描述

Point-to-point technique

从源表面的一点 p \boldsymbol{p} p 出发,p2p 寻找目的表面上最近的点 q \boldsymbol{q} q d s d_s ds 代表两点之间的距离。为了找到最近点,通常会采用 kd-tree 来进行搜索。

Point-to-plane registration

从源点的法向量寻找目的表面的交叉点。如上图 (b) 所示,点 q ′ \boldsymbol{q}' q 是点 p \boldsymbol{p} p 在点 q \boldsymbol{q} q正切平面上的投影。

ICP registration

输入:两个点云及一个初始的可以大致对准两个点云的变换矩阵;

输出:可以准确对准两个点云的变换矩阵。

Helper visualization function

下面的函数可视化目标点云和经过变换后的源点云:

def draw_registration_result(source, target, transformation):source_temp = copy.deepcopy(source)target_temp = copy.deepcopy(target)source_temp.paint_uniform_color([1, 0.706, 0])target_temp.paint_uniform_color([0, 0.651, 0.929])source_temp.transform(transformation)o3d.visualization.draw_geometries([source_temp, target_temp],zoom=0.4459,front=[0.9288, -0.2951, -0.2242],lookat=[1.6784, 2.0612, 1.4451],up=[-0.3402, -0.9189, -0.1996])

因为函数 transformpaint_uniform_color 会改变原始点云,因此这里用深拷贝 copy.deepcopy 来“保护”原始点云。

Input

下面的代码从两个文件中分别读入源点云和目标点云,并给出了一个初始变换矩阵。

demo_icp_pcds = o3d.data.DemoICPPointClouds()
source = o3d.io.read_point_cloud(demo_icp_pcds.paths[0])
target = o3d.io.read_point_cloud(demo_icp_pcds.paths[1])
threshold = 0.02
trans_init = np.asarray([[0.862, 0.011, -0.507, 0.5],[-0.139, 0.967, -0.215, 0.7],[0.487, 0.255, 0.835, -1.4], [0.0, 0.0, 0.0, 1.0]])
draw_registration_result(source, target, trans_init)

下面的函数 evaluate_registration 主要计算两个指标:

  • fitness:衡量重叠区域的大小(# of inlier correspondences / # of points in target),越大越好
  • inlier_rmse:计算所有 inlier correspondences 的 RMSE,越小越好

初始的变换矩阵通常通过一个全局的配准算法得到。

Global registration

Extract geometric feature

下采样点云,估计法向量,然后对每个点计算 FPFH 特征。FPFH 特征是一个 33 维的向量,它可以描述一个点的局部几何性质。

def preprocess_point_cloud(pcd, voxel_size):print(":: Downsample with a voxel size %.3f." % voxel_size)pcd_down = pcd.voxel_down_sample(voxel_size)radius_normal = voxel_size * 2print(":: Estimate normal with search radius %.3f." % radius_normal)pcd_down.estimate_normals(o3d.geometry.KDTreeSearchParamHybrid(radius=radius_normal, max_nn=30))radius_feature = voxel_size * 5print(":: Compute FPFH feature with search radius %.3f." % radius_feature)pcd_fpfh = o3d.pipelines.registration.compute_fpfh_feature(pcd_down,o3d.geometry.KDTreeSearchParamHybrid(radius=radius_feature, max_nn=100))return pcd_down, pcd_fpfh

Input

def prepare_dataset(voxel_size):print(":: Load two point clouds and disturb initial pose.")demo_icp_pcds = o3d.data.DemoICPPointClouds()source = o3d.io.read_point_cloud(demo_icp_pcds.paths[0])target = o3d.io.read_point_cloud(demo_icp_pcds.paths[1])trans_init = np.asarray([[0.0, 0.0, 1.0, 0.0], [1.0, 0.0, 0.0, 0.0],[0.0, 1.0, 0.0, 0.0], [0.0, 0.0, 0.0, 1.0]])source.transform(trans_init)draw_registration_result(source, target, np.identity(4))source_down, source_fpfh = preprocess_point_cloud(source, voxel_size)target_down, target_fpfh = preprocess_point_cloud(target, voxel_size)return source, target, source_down, target_down, source_fpfh, target_fpfh

RANSAC

在每个 RANSAC 的迭代中,ransac_n 个随机点从源点云中被选出。它们在目标点云中的对应点通过查询 33 维的 FPFH 特征空间得到。

def execute_global_registration(source_down, target_down, source_fpfh,target_fpfh, voxel_size):distance_threshold = voxel_size * 1.5print(":: RANSAC registration on downsampled point clouds.")print("   Since the downsampling voxel size is %.3f," % voxel_size)print("   we use a liberal distance threshold %.3f." % distance_threshold)result = o3d.pipelines.registration.registration_ransac_based_on_feature_matching(source_down, target_down, source_fpfh, target_fpfh, True,distance_threshold,o3d.pipelines.registration.TransformationEstimationPointToPoint(False),3, [o3d.pipelines.registration.CorrespondenceCheckerBasedOnEdgeLength(0.9),o3d.pipelines.registration.CorrespondenceCheckerBasedOnDistance(distance_threshold)], o3d.pipelines.registration.RANSACConvergenceCriteria(100000, 0.999))return result
result_ransac = execute_global_registration(source_down, target_down,source_fpfh, target_fpfh,voxel_size)
print(result_ransac)
draw_registration_result(source_down, target_down, result_ransac.transformation)

之后我们就需要用点到点的 ICP 或者点到面的 ICP 来进一步提升配准精度。

Point-to-point ICP

从以下两步骤中进行迭代:

  1. 从目标点云 P \boldsymbol{P} P 中寻找对应点集 K = { ( p , q ) } \mathcal{K}=\{(\boldsymbol{p},\boldsymbol{q})\} K={(p,q)},源点云通过现有的变换矩阵 T \boldsymbol{T} T 进行变换;
  2. 通过最小化目标函数 E ( T ) E(\boldsymbol{T}) E(T) 来更新变换矩阵 T \boldsymbol{T} T。不同的 ICP 变体会采用不同的目标函数 E ( T ) E(\boldsymbol{T}) E(T),这里使用如下的目标函数 E ( T ) = ∑ ( p , q ) ∈ K ∥ p − T q ∥ 2 E(\boldsymbol{T})=\sum_{(\boldsymbol{p},\boldsymbol{q})\in \mathcal{K}} \|\boldsymbol{p}-\boldsymbol{T}\boldsymbol{q} \|^2 E(T)=(p,q)KpTq2
print("Apply point-to-point ICP")
reg_p2p = o3d.pipelines.registration.registration_icp(source, target, threshold, trans_init,o3d.pipelines.registration.TransformationEstimationPointToPoint())
print(reg_p2p)
print("Transformation is:")
print(reg_p2p.transformation)
draw_registration_result(source, target, reg_p2p.transformation)

默认情况下,registration_icp 会运行直到收敛或者达到了默认最大迭代次数(30)。 也可以指定最大的迭代次数:

reg_p2p = o3d.pipelines.registration.registration_icp(source, target, threshold, trans_init,o3d.pipelines.registration.TransformationEstimationPointToPoint(),o3d.pipelines.registration.ICPConvergenceCriteria(max_iteration=2000))
print(reg_p2p)
print("Transformation is:")
print(reg_p2p.transformation)
draw_registration_result(source, target, reg_p2p.transformation)

Point-to-plane ICP

点到面的 ICP 采用下面的目标函数:
E ( T ) = ∑ ( p , q ) ∈ K ( ( p − T q ) ⋅ n p ) 2 E(\boldsymbol{T})=\sum_{(\boldsymbol{p},\boldsymbol{q})\in \mathcal{K}} ((\boldsymbol{p}-\boldsymbol{T}\boldsymbol{q})\cdot \boldsymbol{n}_p)^2 E(T)=(p,q)K((pTq)np)2
n p \boldsymbol{n}_p np 代表每个点 p \boldsymbol{p} p 的法向量。点到面 ICP 比点到点 ICP 有更快的收敛速度。

print("Apply point-to-plane ICP")
reg_p2l = o3d.pipelines.registration.registration_icp(source, target, threshold, trans_init,o3d.pipelines.registration.TransformationEstimationPointToPlane())
print(reg_p2l)
print("Transformation is:")
print(reg_p2l.transformation)
draw_registration_result(source, target, reg_p2l.transformation)

References

[1] open3d 官方文档,http://www.open3d.org/docs/release/tutorial/pipelines/icp_registration.html

[2] Park, S.-Y & Subbarao, M… (2003). A fast Point-to-Tangent Plane technique for multi-view registration. Fourth IEEE International Conference on 3-D Digital Imaging and Modeling. 500. 276- 283. 10.1109/IM.2003.1240260.

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

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

相关文章

【Java 进阶篇】Ajax 入门:打开前端异步交互的大门

欢迎来到前端异步交互的世界!在这篇博客中,我们将深入探讨 Ajax(Asynchronous JavaScript and XML),这是一项能够让你的网页在不刷新的情况下与服务器进行数据交互的技术。无论你是刚刚踏入前端开发的小白,…

pycharm2023 实现鼠标点击某行,调试时代码运行至相应行

按下图取消 Breakpoints Over Line Numbers即可,然后调试时点击某行,代码就会运行至某行

【鸿蒙应用ArkTS开发系列】- 云开发入门简介

目录 概述开发流程工程概览工程模板工程结构 工程创建与配置 概述 HarmonyOS云开发是DevEco Studio新推出的功能,可以让您在一个项目工程中,使用一种语言完成端侧和云侧功能的开发。 基于AppGallery Connect Serverless构建的云侧能力,开发…

windows Oracle Database 19c 卸载教程

目录 打开任务管理器 停止数据库服务 Universal Installer 卸载Oracle数据库程序 使用Oracle Installer卸载 删除注册表项 重新启动系统 打开任务管理器 ctrlShiftEsc可以快速打开任务管理器,找到oracle所有服务然后停止。 停止数据库服务 在开始卸载之前&a…

C++数据结构:并查集

目录 一. 并查集的概念 二. 并查集的模拟实现 2.1 并查集类的声明 2.2 并查集的实现 三. 路径压缩 四. 总结 一. 并查集的概念 在生活中,我们经常需要对某一些事物进行归类处理,即:将N个不同的元素划分为几个互不相交的集合。在初始状态…

镭速,克服UDP传输缺点的百倍提速传输软件工具

在网络传输中,我们经常会面临这样的困难:文件太大,传输速度太慢,浪费时间和流量;文件太小,传输速度太快,容易出现丢包和乱序,损害数据的完整性和正确性。这些困难的根本在于传输层协…

单图像3D重建AI算法综述【2023】

计算机视觉是人工智能的一个快速发展的领域,特别是在 3D 领域。 本概述将考虑一个应用任务:2D 和 3D 环境之间的转换。 在线工具推荐: Three.js AI纹理开发包 - YOLO合成数据生成器 - GLTF/GLB在线编辑 - 3D模型格式在线转换 - 可编程3D场景编…

小红书为什么没人看,小红书爆款标题怎么写?

作为快节奏的社会,人们追求的是不仅仅是高价值更是高性价比,和吸引度。而标题类似于门面,吸引程度自然作为重中之重。今天我们和大家分享下小红书为什么没人看,小红书爆款标题怎么写? 以母婴类型为例子,母婴…

《云计算:云端协同,智慧互联》

《云计算:云端协同,智慧互联》 云计算,这个科技领域中的热门词汇,正在逐渐改变我们的生活方式。它像一座座无形的桥梁,将世界各地的设备、数据、应用紧密连接在一起,实现了云端协同,智慧互联的愿…

网络参考模型与标准协议(二)-TCP/IP对等模型详细介绍

应用层 应用层为应用软件提供接口,使应用程序能够使用网络服务。应用层协议会指定使用相应的传输层协议,以及传输层所使用的端口等。TCP/IP每一层都让数据得以通过网络进行传输,这些层之间使用PDU ( Paket Data Unit,协议数据单元)彼此交换信…

Ubuntu(Linux)的基本操作

基本操作三步走 1、输入vim code.c点击i(出现insert)表示可以编辑代码编辑代码之后按下esc(退出编辑模式)按下shift:(冒号)wq(退出文件)2、输入gcc code.c(进行编译代码…

【知识增强】A Survey of Knowledge-Enhanced Pre-trained LM 论文笔记

A Survey of Knowledge-Enhanced Pre-trained Language Models Linmei Hu, Zeyi Liu, Ziwang Zhao, Lei Hou, Liqiang Nie, Senior Member, IEEE and Juanzi Li 2023年8月的一篇关于知识增强预训练模型的文献综述 论文思维导图 思维导图网页上看不清的话,可以存…

软件测试:测试分类

一. 按照测试对象划分 1.1 界面测试 界面测试(简称UI测试),按照界面的需求(UI设计稿)和界面的设计规则,对我们软件界面所展示的全部内容进行测试和检查,一般包括如下内容: • 验证界面内容的完整性,一致性,准确性,友好性,兼容性.比如页面内容对屏幕大小的自适应,换行,内容是否…

Leetcode—206.反转链表【简单】

2023每日刷题(三十三) Leetcode—206.反转链表 头插法实现代码 /*** Definition for singly-linked list.* struct ListNode {* int val;* struct ListNode *next;* };*/ struct ListNode* reverseList(struct ListNode* head) {if(head NULL…

ajax,axios,fetch

文章目录 ajax工作原理ajax发请求四个步骤创建xmlhttprequest对象设置请求方式设置回调函数发送请求 自封装ajax axiosaxios 特性如何用配置拦截器fetch 三者区别 ajax 工作原理 Ajax的工作原理相当于在用户和服务器之间加了—个中间层(AJAX引擎),使用户操作与服务…

HDD与QLC SSD深度对比:功耗与存储密度的终极较量

在当今数据世界中,存储设备的选择对于整体系统性能和能耗有着至关重要的影响。硬盘HDD和大容量QLC SSD是两种主流的存储设备,而它们在功耗方面的表现是许多用户关注的焦点。 扩展阅读: 1.面对SSD的步步紧逼,HDD依然奋斗不息 2.…

Windows系统中搭建docker (ubuntu,Docker-desktop)

一、docker安装前的准备工作 1. 开启CPU虚拟化,新电脑该默认是开启的,如果没开启可以根据自己电脑型号品牌搜索如克开启CPU虚拟化。当开启成功后可在设备管理器中看到。 2.开通Hyper-V 通过 Windows 控制面板 --> 程序和功能 -->启用或关闭…

Java集合大总结——Set的简单使用

Set的简单介绍 Set接口是Collection的子接口,Set接口相较于Collection接口没有提供额外的方法。Set 集合不允许包含相同的元素,如果试把两个相同的元素加入同一个 Set 集合中,则添加操作失败。Set集合支持的遍历方式和Collection集合一样&am…

[Kettle] 生成记录

在数据统计中,往往要生成固定行数和列数的记录,用于存放统计总数 需求:为方便记录1~12月份商品的销售总额,需要通过生成记录,生成一个月销售总额的数据表,包括商品名称和销售总额两个字段,记录…

使用键盘管理器更改键盘快捷键,让键盘真正迎合你的使用习惯

如果默认快捷键不适合你,你肯定会想知道如何在Windows 11中更改键盘快捷键。 也许你已经习惯了macOS键盘,或者像我一样在Windows和Mac之间切换工作/游戏——如果是这样的话,重新配置默认的Windows快捷方式,使其与Mac上的快捷方式…