Open3D是一个开源库,支持快速开发和处理3D数据。Open3D在c++和Python中公开了一组精心选择的数据结构和算法。后端是高度优化的,并且是为并行化而设置的。

本系列学习计划有Blue同学作为发起人,主要以Open3D官方网站的教程为主进行翻译与实践的学习计划。点云PCL公众号作为免费的3D视觉,点云交流社区,期待有使用Open3D或者感兴趣的小伙伴能够加入我们的翻译计划,贡献免费交流社区,为使用Open3D提供中文的使用教程。

ICP配准和彩色点云配准都被称为局部点云配准方法,因为他们都依赖一个粗糙的对齐作为初始化。本篇教程将会展现另一种被称为全局配准的配准方法.这种系列的算法不要求一个初始化的对齐,通常会输出一个没那么精准的对齐结果,并且使用该结果作为局部配准的初始化.

可视化

该辅助函数可以将配准的源点云和目标点云一起可视化。

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])

注意:这里原来的教程里可视化函数都加了初始视角之类的,但是很多人反映这个会报错,并且官方函数里也没给出可接受的参数,所以在这里把初始视角的参数都去掉了

提取几何特征

我们降采样点云,估计法线,之后对每个点计算FPFH特征.FPFH特征是一个描述点的局部几何属性的33维的向量.在33维空间中进行最近邻查询可以返回具有近似几何结构的点.详细细节请查看 [Rasu2009].

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.registration.compute_fpfh_feature(pcd_down,o3d.geometry.KDTreeSearchParamHybrid(radius=radius_feature, max_nn=100))return pcd_down, pcd_fpfh

输入

以下代码从两个文件中读取源点云和目标点云.这一对点云使用单位矩阵作为初始矩阵之后是不对齐的.

def prepare_dataset(voxel_size):print(":: Load two point clouds and disturb initial pose.")source = o3d.io.read_point_cloud("../../TestData/ICP/cloud_bin_0.pcd")target = o3d.io.read_point_cloud("../../TestData/ICP/cloud_bin_1.pcd")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_fpfhvoxel_size = 0.05 # means 5cm for this dataset
source, target, source_down, target_down, source_fpfh, target_fpfh = prepare_dataset(voxel_size)

:: Load two point clouds and disturb initial pose.
:: Downsample with a voxel size 0.050.
:: Estimate normal with search radius 0.100.
:: Compute FPFH feature with search radius 0.250.
:: Downsample with a voxel size 0.050.
:: Estimate normal with search radius 0.100.
:: Compute FPFH feature with search radius 0.250.

RANSAC

我们使用RANSAC进行全局配准.在RANSAC迭代中,我们每次从源点云中选取 ransac_n 个随机点.通过在33维FPFH特征空间中查询最邻近,可以在目标点云中找到他们的对应点.剪枝步骤需要使用快速修剪算法来提早拒绝错误匹配.
Open3d提供以下剪枝算法:

  • CorrespondenceCheckerBasedOnDistance检查对应的点云是否接近(也就是距离是否小于指定阈值)

  • CorrespondenceCheckerBasedOnEdgeLength检查从源点云和目标点云对应中分别画上两条任意边(两个顶点连成的线)是否近似.

  • CorrespondenceCheckerBasedOnNormal考虑的所有的对应的顶点法线的密切关系.他计算了两个法线向量的点积.使用弧度作为阈值.

只有通过剪枝步骤的匹配才用于转换,该转换将在整个点云上进行验证.核心函数是 :

registration_ransac_based_on_feature_matching.

RANSACConvergenceCriteria是里面一个十分重要的超参数.他定义了RANSAC迭代的最大次数和验证的最大次数.这两个值越大,那么结果越准确,但同时也要花费更多的时间.
我们是基于[Choi2015]提供的的经验来设置RANSAC的超参数.

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.registration.registration_ransac_based_on_feature_matching(source_down, target_down, source_fpfh, target_fpfh, distance_threshold,o3d.registration.TransformationEstimationPointToPoint(False), 4, [o3d.registration.CorrespondenceCheckerBasedOnEdgeLength(0.9),o3d.registration.CorrespondenceCheckerBasedOnDistance(distance_threshold)], o3d.registration.RANSACConvergenceCriteria(4000000, 500))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)

:: RANSAC registration on downsampled point clouds.
Since the downsampling voxel size is 0.050,
we use a liberal distance threshold 0.075.
registration::RegistrationResult with fitness=6.773109e-01, inlier_rmse=3.332039e-02, and correspondence_set size of 3224
Access transformation to get result.

局部优化

由于性能原因,全局配准只能在大规模降采样的点云上执行,配准的结果不够精细,我们使用 Point-to-plane ICP 去进一步优化配准结果.

def refine_registration(source, target, source_fpfh, target_fpfh, voxel_size):distance_threshold = voxel_size * 0.4print(":: Point-to-plane ICP registration is applied on original point")print("   clouds to refine the alignment. This time we use a strict")print("   distance threshold %.3f." % distance_threshold)result = o3d.registration.registration_icp(source, target, distance_threshold, result_ransac.transformation,o3d.registration.TransformationEstimationPointToPlane())return resultresult_icp = refine_registration(source, target, source_fpfh, target_fpfh,voxel_size)
print(result_icp)
draw_registration_result(source, target, result_icp.transformation)

:: Point-to-plane ICP registration is applied on original point
clouds to refine the alignment. This time we use a strict
distance threshold 0.020.
registration::RegistrationResult with fitness=6.210275e-01, inlier_rmse=6.565175e-03, and correspondence_set size of 123482
Access transformation to get result.

快速全局配准

由于无数的模型推荐和评估,导致基于RANSAC的全局配准需要很长的时间.
[Zhou2016] 提出了一种加速的方法,该方法可以快速的优化几乎没有对应关系的线处理权重( [Zhou2016] introduced a faster approach that quickly optimizes line process weights of few correspondences).这样在每次迭代的时候没有模型建议和评估,该方法就在计算的时候节约的大量的时间.(建议看看原论文,这个感觉翻译不好,有更好建议的欢迎留言.)
这篇教程比较了基于RANSAC的全局配准和[Zhou2016]方法的运行时间.

输入

我们使用上面全局配准的输入例子.

voxel_size = 0.05  # means 5cm for the dataset
source, target, source_down, target_down, source_fpfh, target_fpfh = \prepare_dataset(voxel_size)

:: Load two point clouds and disturb initial pose.
:: Downsample with a voxel size 0.050.
:: Estimate normal with search radius 0.100.
:: Compute FPFH feature with search radius 0.250.
:: Downsample with a voxel size 0.050.
:: Estimate normal with search radius 0.100.
:: Compute FPFH feature with search radius 0.250.

基准

在下面代码中,我们将计时全局配准算法.

start = time.time()
result_ransac = execute_global_registration(source_down, target_down,source_fpfh, target_fpfh,voxel_size)
print("Global registration took %.3f sec.\n" % (time.time() - start))
print(result_ransac)
draw_registration_result(source_down, target_down,result_ransac.transformation)

:: RANSAC registration on downsampled point clouds.
Since the downsampling voxel size is 0.050,
we use a liberal distance threshold 0.075.
Global registration took 0.085 sec.
registration::RegistrationResult with fitness=6.760504e-01, inlier_rmse=2.596653e-02, and correspondence_set size of 3218
Access transformation to get result.

快速全局配准

我们采用和基准相同的输入,下面的代码调用了了[Zhou2016]的实现.

def execute_fast_global_registration(source_down, target_down, source_fpfh,target_fpfh, voxel_size):distance_threshold = voxel_size * 0.5print(":: Apply fast global registration with distance threshold %.3f" \% distance_threshold)result = o3d.registration.registration_fast_based_on_feature_matching(source_down, target_down, source_fpfh, target_fpfh,o3d.registration.FastGlobalRegistrationOption(maximum_correspondence_distance=distance_threshold))return result
start = time.time()
result_fast = execute_fast_global_registration(source_down, target_down,source_fpfh, target_fpfh,voxel_size)
print("Fast global registration took %.3f sec.\n" % (time.time() - start))
print(result_fast)
draw_registration_result(source_down, target_down,result_fast.transformation)

:: Apply fast global registration with distance threshold 0.025
Fast global registration took 0.128 sec.
registration::RegistrationResult with fitness=5.054622e-01, inlier_rmse=1.743545e-02, and correspondence_set size of 2406
Access transformation to get result.

经过适当的配置,快速全局配准的精度甚至可以和ICP相媲美.更多实验结果请参阅[Zhou2016].

资源

三维点云论文及相关应用分享

【点云论文速读】基于激光雷达的里程计及3D点云地图中的定位方法

3D目标检测:MV3D-Net

三维点云分割综述(上)

3D-MiniNet: 从点云中学习2D表示以实现快速有效的3D LIDAR语义分割(2020)

win下使用QT添加VTK插件实现点云可视化GUI

JSNet:3D点云的联合实例和语义分割

大场景三维点云的语义分割综述

PCL中outofcore模块---基于核外八叉树的大规模点云的显示

基于局部凹凸性进行目标分割

基于三维卷积神经网络的点云标记

点云的超体素(SuperVoxel)

基于超点图的大规模点云分割

更多文章可查看:点云学习历史文章大汇总

SLAM及AR相关分享

【开源方案共享】ORB-SLAM3开源啦!

【论文速读】AVP-SLAM:自动泊车系统中的语义SLAM

【点云论文速读】StructSLAM:结构化线特征SLAM

SLAM和AR综述

常用的3D深度相机

AR设备单目视觉惯导SLAM算法综述与评价

SLAM综述(4)激光与视觉融合SLAM

Kimera实时重建的语义SLAM系统

SLAM综述(3)-视觉与惯导,视觉与深度学习SLAM

易扩展的SLAM框架-OpenVSLAM

高翔:非结构化道路激光SLAM中的挑战

SLAM综述之Lidar SLAM

基于鱼眼相机的SLAM方法介绍

往期线上分享录播汇总

第一期B站录播之三维模型检索技术

第二期B站录播之深度学习在3D场景中的应用

第三期B站录播之CMake进阶学习

第四期B站录播之点云物体及六自由度姿态估计

第五期B站录播之点云深度学习语义分割拓展

第六期B站录播之Pointnetlk解读

[线上分享录播]点云配准概述及其在激光SLAM中的应用

[线上分享录播]cloudcompare插件开发

[线上分享录播]基于点云数据的 Mesh重建与处理

[线上分享录播]机器人力反馈遥操作技术及机器人视觉分享

[线上分享录播]地面点云配准与机载点云航带平差

点云PCL更多活动请查看:点云PCL活动之应届生校招群

扫描下方微信视频号二维码可查看最新研究成果及相关开源方案的演示:

如果你对Open3D感兴趣,或者正在使用该开源方案,就请加入我们,一起翻译,一起学习,贡献自己的力量,目前阶段主要以微信群为主,有意者发送“Open3D学习计划”到公众号后台,和更多热爱分享的小伙伴一起交流吧!如果翻译的有什么问题或者您有更好的意见,请评论交流!!!!

以上内容如有错误请留言评论,欢迎指正交流。如有侵权,请联系删除

扫描二维码

关注我们

让我们一起分享一起学习吧!期待有想法,乐于分享的小伙伴加入免费星球注入爱分享的新鲜活力。分享的主题包含但不限于三维视觉,点云,高精地图,自动驾驶,以及机器人等相关的领域。

分享及合作方式:微信“920177957”(需要按要求备注) 联系邮箱:dianyunpcl@163.com,欢迎企业来联系公众号展开合作。

点一下“在看”你会更好看耶

Open3d学习计划—高级篇 3(点云全局配准)相关推荐

  1. Open3d学习计划——高级篇 9(表面重建)

    Open3d学习计划--高级篇 9(表面重建) 在许多场景下我们希望生成密集的3D几何形状,比如三角网格.然而从多视图立体算法和深度传感器中我们只能够获得非结构化的点云数据.我们需要使用表面重建算法来 ...

  2. Open3d学习计划——高级篇 6(体素化)

    Open3d学习计划--高级篇 6(体素化) 点云和三角网格是一种十分灵活的,但是不规则的几何类型.体素网格是通过规则的3D网格来表示的另一种3D几何类型,并且它可以看作是2D像素在3D上的对照物.O ...

  3. Open3d学习计划—高级篇 2(彩色点云配准)

    Open3D是一个开源库,支持快速开发和处理3D数据.Open3D在c++和Python中公开了一组精心选择的数据结构和算法.后端是高度优化的,并且是为并行化而设置的. 本系列学习计划有Blue同学作 ...

  4. Open3d学习计划—高级篇 4(多视角点云配准)

    本文为转载文章,原创作者为blue同学,可关注他的博客:https://blog.csdn.net/io569417668 Open3D是一个开源库,支持快速开发和处理3D数据.Open3D在c++和 ...

  5. Open3d学习计划—高级篇 8(网格变形)

    Open3D是一个开源库,支持快速开发和处理3D数据.Open3D在c++和Python中公开了一组精心选择的数据结构和算法.后端是高度优化的,并且是为并行化而设置的. 本系列学习计划有Blue同学作 ...

  6. Open3d学习计划—高级篇 7(颜色映射)

    Open3D是一个开源库,支持快速开发和处理3D数据.Open3D在c++和Python中公开了一组精心选择的数据结构和算法.后端是高度优化的,并且是为并行化而设置的. 本系列学习计划有Blue同学作 ...

  7. Open3d学习计划—高级篇 6(体素化)

    Open3D是一个开源库,支持快速开发和处理3D数据.Open3D在c++和Python中公开了一组精心选择的数据结构和算法.后端是高度优化的,并且是为并行化而设置的. 本系列学习计划有Blue同学作 ...

  8. Open3d学习计划—高级篇 5(RGBD融合)

    Open3D是一个开源库,支持快速开发和处理3D数据.Open3D在c++和Python中公开了一组精心选择的数据结构和算法.后端是高度优化的,并且是为并行化而设置的. 本系列学习计划有Blue同学作 ...

  9. Open3d学习计划——2(使用帮助与IO)

    Open3d学习计划--2 在上篇文章,我们介绍了Open3D是什么,和Python版本的如何安装.本篇文章将介绍原文档中Open3D得基础用法,本文翻译文档为0.10.0版本open3d文档,更多之 ...

最新文章

  1. Django 1.6 最佳实践: 如何设置django项目的设置(settings.py)和部署文件(requirements.txt)...
  2. 神经网络 | 基于脉冲耦合神经网络(PCNN)的图像特征提取(Matlab源代码)
  3. wamp php imagick,如何在wamp for Windows中安装和启用Imagick扩展 php psd 生成缩略图
  4. c语言十六进制转换加H,c语言十六进制和十进制间的转换.docx
  5. [css] 检测sass中错误的指令是哪个?
  6. 从 VC7 的 CHtmlView 不能正常退出谈 CComPtr 使用中的一个误区
  7. vue-drag-resize实线页面的拖拽与缩放
  8. EMC -- Windows下卸载 Content Server
  9. 剑指offer——面试题55:字符流中第一个不重复的字符
  10. Nginx日志和http模块相关变量
  11. a better git log
  12. 利用 Global Mapper 软件下载 Google 影像(中英文对照)
  13. [总结]国家电网计算机类备考总结
  14. java 批量下载小说天堂的小说
  15. cad修改快捷键_人手一份的绘图命令,CAD绘图必备,学会工资上万不是梦
  16. 人力资源管理理论与实务第三章
  17. Jeecg-Boot前端部署
  18. OpenGL-入门-BMP像素图glDrawPixels
  19. 香橙派 lite 2 使用OV5640
  20. 任正非、俞敏洪告诫有赞的老板白鸦:你错的离谱

热门文章

  1. 根据进程名杀死进程 -kill进程名
  2. ActiveMQ—消息特性(延迟和定时消息投递)
  3. 直接在sublime中运行php
  4. Linux驱动框架之framebuffer驱动框架
  5. 薏米红豆粥的功效和实践演示
  6. 机房收费系统系列一:运行时错误‘-2147217843(80040e4d)’;用户‘sa’登陆失败...
  7. 一些linux下的性能监测工具
  8. Linux下getsockopt/setsockopt 函数说明
  9. linux 脚本的作用,shell export 作用
  10. java订单实现的_java订单系统的开发