Open3D Ransac点云配准算法(粗配准)

news2024/11/17 3:39:19

目录

一、概述

1.1简介

1.2RANSAC在点云粗配准中的应用步骤

二、代码实现

2.1关键函数

2.2完整代码

2.3代码解析

2.3.1计算FPFH

1. 法线估计

2. 计算FPFH特征

2.3.2 全局配准

1.函数:execute_global_registration

2.距离阈值

3.registration_ransac_based_on_feature_matching函数

三、实现效果

3.1原始点云

3.2配准后点云


一、概述

1.1简介

        RANSAC(Random Sample Consensus)是一种迭代方法,用于从一组包含离群点的数据中估计模型参数。它特别适合处理包含大量噪声或离群点的数据。RANSAC在点云配准、图像拼接、3D重建等领域中广泛应用。

        RANSAC(Random Sample Consensus)在点云粗配准中的应用主要包括以下步骤:特征提取、特征匹配、模型拟合、内点验证和迭代优化。

1.2RANSAC在点云粗配准中的应用步骤

  1. 特征提取:从点云中提取特征点及其特征描述符。常用的特征描述符有FPFH(Fast Point Feature Histograms)等。
  2. 特征匹配:将源点云和目标点云的特征描述符进行匹配,得到初始对应关系。这些匹配关系可能包含很多误匹配。
  3. 随机采样:从匹配的特征对中随机选择一定数量的样本,用于模型拟合。样本的数量应足以确定一个唯一的变换模型。
  4. 模型拟合:使用选定的样本对估计一个变换模型(通常是一个刚体变换,包括旋转和平移)。
  5. 内点验证:使用拟合的模型对所有匹配对进行验证,计算匹配点对之间的距离,判断是否符合模型。符合模型的点对被称为内点。
  6. 评估模型:计算当前模型的内点数量,并与之前的最佳模型进行比较。如果当前模型的内点数量更多,则更新最佳模型。
  7. 迭代优化:重复上述步骤一定次数(迭代次数根据数据中的离群点比例和期望成功概率来确定),最终选择内点数量最多的模型作为最佳模型。

二、代码实现

2.1关键函数

def registration_ransac_based_on_feature_matching(source, target, 
          source_feature, target_feature, 
          max_correspondence_distance,
          estimation_method=None, *args, **kwargs):
  • source:源点云
  • target:目标点云
  • source_feature:源点云的特征描述,目前版本的open3d主要是FPFH特征描述
  • target_feature:目标点云的特征描述,目前版本的open3d主要是FPFH特征描述
  • max_correspondence_distance:对应点之间的最大距离
  • estimation_method:默认采用的是点到点的方法。有如下三种方式:(TransformationEstimationPointToPoint, TransformationEstimationPointToPlane, TransformationEstimationForColoredICP)
  • ransac_n:随机选取匹配点对的个数,也即RANSAC算法随机选取点的个数。默认值是4。
  • checkers:使用快速修剪算法来提早拒绝错误匹配。,有如下3种修剪算法:(CorrespondenceCheckerBasedOnEdgeLength, CorrespondenceCheckerBasedOnDistance, CorrespondenceCheckerBasedOnNormal)
  • criteria:定义RANSAC迭代的最大次数和验证的最大次数。这两个值越大,结果越准确,但要花费更多的时间。默认值是:max_iteration=100000, and max_validation=100。

2.2完整代码

import time
import open3d as o3d
import copy


# -------------传入点云数据,计算FPFH------------
def FPFH_Compute(pcd):
    radius_normal = 0.01  # kdtree参数,用于估计法线的半径,
    print(":: Estimate normal with search radius %.3f." % radius_normal)
    pcd.estimate_normals(
        o3d.geometry.KDTreeSearchParamHybrid(radius=radius_normal, max_nn=30))
# 估计法线的1个参数,使用混合型的kdtree,半径内取最多30个邻居
    radius_feature = 0.02  # kdtree参数,用于估计FPFH特征的半径
    print(":: Compute FPFH feature with search radius %.3f." % radius_feature)
    pcd_fpfh = o3d.pipelines.registration.compute_fpfh_feature(pcd,
    o3d.geometry.KDTreeSearchParamHybrid(radius=radius_feature, max_nn=100))  # 计算FPFH特征,搜索方法kdtree
    return pcd_fpfh  # 返回FPFH特征


# ----------------RANSAC配准--------------------
def execute_global_registration(source, target, source_fpfh,
                                target_fpfh):  # 传入两个点云和点云的特征
    distance_threshold = 10  # 设定距离阈值
    print("we use a liberal distance threshold %.3f." % distance_threshold)
# 2个点云,两个点云的特征,距离阈值,一个函数,4,
# 一个list[0.9的两个对应点的线段长度阈值,两个点的距离阈值],
# 一个函数设定最大迭代次数和最大验证次数
    result = o3d.pipelines.registration.registration_ransac_based_on_feature_matching(
        source, target, source_fpfh, target_fpfh, True, distance_threshold,
        o3d.pipelines.registration.TransformationEstimationPointToPoint(False),
        4, [
            o3d.pipelines.registration.CorrespondenceCheckerBasedOnEdgeLength(
                0.9),
            o3d.pipelines.registration.CorrespondenceCheckerBasedOnDistance(
                distance_threshold)
        ], o3d.pipelines.registration.RANSACConvergenceCriteria(4000000, 500))
    return result


# ---------------可视化配准结果----------------
def draw_registration_result(source, target, transformation):
    source_temp = copy.deepcopy(source)         # 由于函数transformand paint_uniform_color会更改点云,
    target_temp = copy.deepcopy(target)         # 因此调用copy.deepcoy进行复制并保护原始点云。
    source_temp.paint_uniform_color([1, 0, 0])  # 点云着色
    target_temp.paint_uniform_color([0, 1, 0])
    source_temp.transform(transformation)
    # o3d.io.write_point_cloud("trans_of_source.pcd", source_temp)#保存点云
    o3d.visualization.draw_geometries([source_temp, target_temp],width=1200, height=900)


# ----------------读取点云数据--------------
source = o3d.io.read_point_cloud("..//..//standford_cloud_data//hand_trans.pcd")
target = o3d.io.read_point_cloud("..//..//standford_cloud_data//hand.pcd")

source=source.uniform_down_sample(every_k_points=10)
target=target.uniform_down_sample(every_k_points=10)
# -----------------计算的FPFH---------------
source_fpfh=FPFH_Compute(source)
target_fpfh=FPFH_Compute(target)
# ---------------调用RANSAC执行配准------------
start = time.time()
result_ransac = execute_global_registration(source, target,
                                            source_fpfh, target_fpfh)
print("Global registration took %.3f sec.\n" % (time.time() - start))
print(result_ransac)  # 输出RANSAC配准信息
Tr = result_ransac.transformation
draw_registration_result(source, target, Tr) 

2.3代码解析

2.3.1计算FPFH

        这段代码的主要作用是为输入的点云(pcd对象)进行法线估计和FPFH特征计算。法线估计通过指定半径和最大最近邻点数来计算每个点的法向量,而FPFH特征计算则基于这些法向量和局部邻域信息,生成描述点云局部几何特征的特征向量。这些特征在点云处理中常用于配准、识别和分割等任务,有助于捕捉点云的几何结构和局部特征信息

# -------------传入点云数据,计算FPFH------------
def FPFH_Compute(pcd):
    radius_normal = 0.01  # kdtree参数,用于估计法线的半径,
    print(":: Estimate normal with search radius %.3f." % radius_normal)
    pcd.estimate_normals(
        o3d.geometry.KDTreeSearchParamHybrid(radius=radius_normal, max_nn=30))
# 估计法线的1个参数,使用混合型的kdtree,半径内取最多30个邻居
    radius_feature = 0.02  # kdtree参数,用于估计FPFH特征的半径
    print(":: Compute FPFH feature with search radius %.3f." % radius_feature)
    pcd_fpfh = o3d.pipelines.registration.compute_fpfh_feature(pcd,
    o3d.geometry.KDTreeSearchParamHybrid(radius=radius_feature, max_nn=100))  # 计算FPFH特征,搜索方法kdtree
    return pcd_fpfh  # 返回FPFH特征
1. 法线估计
radius_normal = 0.01
pcd.estimate_normals(
    o3d.geometry.KDTreeSearchParamHybrid(radius=radius_normal, max_nn=30))

作用:

  • 法线估计是指在点云中为每个点计算法向量,法向量在计算机视觉和几何处理中很重要,用于描述点云表面的方向和曲率。
  • KD树是一种数据结构,用于快速查询最近邻的点。KDTreeSearchParamHybrid参数指定了法线估计算法中的搜索半径和最大最近邻点数。
2. 计算FPFH特征
radius_feature = 0.02
pcd_fpfh = o3d.pipelines.registration.compute_fpfh_feature(
    pcd, o3d.geometry.KDTreeSearchParamHybrid(radius=radius_feature, max_nn=100))

作用:

  • FPFH特征(Fast Point Feature Histograms)是一种用于描述点云局部几何结构的特征描述符。它对点云中每个点的邻域进行建模,捕捉了点云的表面形状和曲率信息。
  • compute_fpfh_feature函数计算点云的FPFH特征,需要指定点云对象和用于搜索的KD树参数(搜索半径和最大最近邻点数)。

2.3.2 全局配准

        这段代码实现了全局点云配准的过程,使用了RANSAC(Random Sample Consensus)算法基于特征匹配来寻找最优的刚体变换(旋转和平移),使得源点云与目标点云尽可能对齐。

# ----------------RANSAC配准--------------------
def execute_global_registration(source, target, source_fpfh,
                                target_fpfh):  # 传入两个点云和点云的特征
    distance_threshold = 10  # 设定距离阈值
    print("we use a liberal distance threshold %.3f." % distance_threshold)
# 2个点云,两个点云的特征,距离阈值,一个函数,4,
# 一个list[0.9的两个对应点的线段长度阈值,两个点的距离阈值],
# 一个函数设定最大迭代次数和最大验证次数
    result = o3d.pipelines.registration.registration_ransac_based_on_feature_matching(
        source, target, source_fpfh, target_fpfh, True, distance_threshold,
        o3d.pipelines.registration.TransformationEstimationPointToPoint(False),
        4, [
            o3d.pipelines.registration.CorrespondenceCheckerBasedOnEdgeLength(
                0.9),
            o3d.pipelines.registration.CorrespondenceCheckerBasedOnDistance(
                distance_threshold)
        ], o3d.pipelines.registration.RANSACConvergenceCriteria(4000000, 500))
    return result
1.函数:execute_global_registration
def execute_global_registration(source, target, source_fpfh, target_fpfh):

参数:

  • source:源点云对象。
  • target:目标点云对象。
  • source_fpfh:源点云的FPFH特征。
  • target_fpfh:目标点云的FPFH特征。
2.距离阈值
distance_threshold = 10
print("we use a liberal distance threshold %.3f." % distance_threshold)

距离阈值:

  • distance_threshold:设定的距离阈值,用于判断匹配点对的有效性。
3.registration_ransac_based_on_feature_matching函数
result = o3d.pipelines.registration.registration_ransac_based_on_feature_matching(
    source, target, source_fpfh, target_fpfh, True, distance_threshold,
    o3d.pipelines.registration.TransformationEstimationPointToPoint(False),
    4, [
        o3d.pipelines.registration.CorrespondenceCheckerBasedOnEdgeLength(0.9),
        o3d.pipelines.registration.CorrespondenceCheckerBasedOnDistance(
            distance_threshold)
    ], o3d.pipelines.registration.RANSACConvergenceCriteria(4000000, 500))

参数解释:

  • source 和 target:待配准的源点云和目标点云。
  • source_fpfh 和 target_fpfh:源点云和目标点云的FPFH特征。
  • True:表示进行全局配准。
  • distance_threshold:距离阈值,用于判断匹配点对的有效性。
  • TransformationEstimationPointToPoint(False):使用点到点的变换估计方法。
  • 4:RANSAC算法的迭代次数。
  • [...]:用于检查对应关系的有效性的列表,包括基于边长和距离的检查器。
  • RANSACConvergenceCriteria(4000000, 500):设定RANSAC的最大迭代次数和最大验证次数。

三、实现效果

3.1原始点云

3.2配准后点云

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

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

相关文章

为什么企业应用开发,c++干不过java?

在开始前刚好我有一些资料,是我根据网友给的问题精心整理了一份「c的资料从专业入门到高级教程」, 点个关注在评论区回复“888”之后私信回复“888”,全部无偿共享给大家!!! C/C这种东西,根本…

面向阿克曼移动机器人(自行车模型)的LQR(最优二次型调节器)的路径跟踪方法

线性二次调节器(Linear Quadratic Regulator,LQR)是针对线性系统的最优控制方法。LQR 方法标准的求解体系是在考虑到损耗尽可能小的情况下, 以尽量小的代价平衡其他状态分量。一般情况下,线性系统在LQR 控制方法中用状态空间方程描…

Docker 一篇到位

目录 01. Docker使用导航 02. Build Share Run 样例 03. 理解容器 04. 安装 Docker 05. Docker 样例(常见命令使用) 下载镜像 启动容器 修改页面 保存镜像 docker commit docker save docker load 分享社区 docker login docker tag do…

浅聊JavaScript中的栈(stack)

前言 这篇文章结合leetcode题目讲解一下栈这种结构 第20题:20. 有效的括号 - 力扣(LeetCode) 第LCR-147题LCR 147. 最小栈 - 力扣(LeetCode) 栈(stack) 在讲解题目之前,我们先来…

天池大赛Higress插件官方demo详细部署+调试

天池大赛Higress插件官方demo详细部署调试 契机 ⚙ 使用Higress AI网关优化AI调用成本。就是基于向量召回相似问题的缓存,降低LLM API调用成本。就是开发一个网关插件做QA缓存嘛。前文已经成功复现了hello-world插件,这次结合官方提供的AI-Cache插件自…

二叉树遍历练习题

2.已知某二叉树的前序遍历序列为5 7 4 9 6 2 1,中序遍历序列为4 7 5 6 9 1 2,则其后序遍历序列为( ) A.4 2 5 7 6 9 1 B.4 2 7 5 6 9 1 C.4 7 6 1 2 9 5 D.4 7 2 9 5 6 1 答案:C 解析: 通过前序遍历找…

失眠焦虑植物神经紊乱应该怎么改善饮食?

在快节奏的现代社会中,越来越多的人受到植物神经紊乱的困扰,尤其是失眠、焦虑、胸闷气短等症状频发。这些症状不仅影响日常生活和工作效率,还可能引发一系列健康问题。今天,我们就来谈谈如何通过调整饮食来改善这些症状。 饮食调整…

Java [ 基础 ] 方法引用 ✨

✨探索Java基础✨ Java基础:方法引用 方法引用是Java 8中引入的一种新特性,它使得代码更加简洁和易读。方法引用提供了一种可以直接引用已有方法作为Lambda表达式的替代方案。本文将深入介绍方法引用的基本概念、使用方法、具体实例及其在实际开发中的…

HCIA4.26-5.10

OSPF ——开放式最短路径优先协议 无类别链路状态IGP动态路由协议 距离矢量协议 运行距离矢量协议的路由器会周期性的泛洪自己的路由表,通过路由之间的交互,每台路由器都从相邻的路由器学习到路由条目,随后加载进自己的路由表中。对于网络…

简单分享下python封装

目录: 一、简介,什么是封装 二、封装的优点与好处 三、封装的示例 四、可封装的场景 一、简介,什么是封装 通俗理解:封装,简而言之,就是把数据(变量)和操作这些数据的方法&#xff0…

全球AI新闻速递7.1

全球AI新闻速递 1.科大讯飞发布讯飞星火 V4.0。 2.成都人形机器人创新中心:基于视觉扩散架构的人形机器人任务生成式模型 R-DDPRM。 3.安徽省人形机器人产业创新中心获批,将打造国内首创、世界领先研究基地。 4.亳州牵手华为打造华佗中医药大模型。 …

系统安全及应用(命令)

目录 一、账号安全控制 1.1 系统账号清理 1.2 密码安全控制 1.3 历史记录控制 1.4 终端自动注销 二、系统引导和登陆控制 2.1 限制su命令用户 2.2 PAM安全认证 示例一:通过pam 模块来防止暴力破解ssh 2.3 sudo机制提升权限 2.3.1 sudo命令(ro…

SRS流媒体服务器安装与推拉流测试

一、首先打开SRS Github https://github.com/ossrs/srs二、在Linux系统下安装SRS 1. git clone https://github.com/ossrs/srs2、克隆完后进入trunk文件夹 cd srs/trunk3.进行环境配置 ./configure 检测当前环境是否满足 4.进行编译 make 5.编译完成后运行 ./objs/srs …

统计学期末名词解释说明

基本名词解释P值、显著性、显著水平、样本量、三大分布等 20基本名词详细解释: √P值: 相关名词:显著性、显著性差异、0.01水平显著、0.05水平显著。 P值,也称显著性值或者Sig.值,用于描述某件事情发生的概率情况&a…

器件频频更换为哪桩

曾想象,在一家大型研发型企业里有如下案例: 硬件工程师设计电路选择了器件库中的某器件,在批量试产产品时,却发现没有库存,即时申请采购,却发现货期相当长,一时难以采购,甚至根本不…

【ElementPlus源码】Scrollbar 滚动条

文章目录 thumbclickThumbHandlerstartDragmouseMoveDocumentHandlermouseUpDocumentHandlerclickTrackHandler其他 barScrollbar导出的方法noresize更新滚动条相关属性 utilsruntime.tsbuildProps 看源码时候做的笔记。若有问题,请指出! 路径相关格式请…

什么是协程?协程和线程的区别

文章目录 前置知识应用程序和内核阻塞和非阻塞同步和异步并发和并行IO 发展历史同步编程异步多线程/进程异步消息 回调函数(响应式编程) 协程协程基本概念go 示例代码协程和线程的区别 个人简介 前置知识 在了解协程前,我们先理解一些相关的…

VBA数据库解决方案第十二讲:如何判断数据库中数据表是否存在

《VBA数据库解决方案》教程(版权10090845)是我推出的第二套教程,目前已经是第二版修订了。这套教程定位于中级,是学完字典后的另一个专题讲解。数据库是数据处理的利器,教程中详细介绍了利用ADO连接ACCDB和EXCEL的方法…

平安养老险陕西分公司参加2024上半年省级单位驻富平帮扶团联席会

6月28日,平安养老险陕西分公司工会副主席武媛携驻村工作队赴富平县庄里镇永安村参加2024上半年度省级单位驻富平帮扶团联席会议。 会议由省委金融办副主任、省委金融工委委员李嘉辉及省委金融办选派挂职干部、富平县副县长席玮共同主持。 会上,席玮县长带…

全球AI新闻速递6.28

全球AI新闻速递 1.首款 Transformer 专用 AI 芯片 Sohu 登场。 2.钉钉:宣布对所有AI大模型厂商开放,首批7家接入。 3.华为联合清华大学发布《AI 终端白皮书》。 4.国家卫生健康委:推动AI技术在制定个性化营养、运动干预方案中的应用。 …