当前位置: 首页 > news >正文

Python实现点云随机一致性(RANSAC)配准——粗配准

        今天我们来介绍精配准前的重要步骤——粗配准。大家使用前面ICP和各种变式时,有一个使用单位矩阵代替的部分。对于姿态一致,距离较近的两点云,使用单位矩阵一点问题都没有,可是姿态不对应,哪怕离的很近也会出现配准问题。那么今天我们就来解决这个问题。

        RANSAC(Random Sample Consensus)是一种迭代式鲁棒估计算法,专门用于在强噪声或高离群点比例的数据中估计模型参数。它在点云粗配准、图像拼接、3D 重建等任务中扮演着关键角色。RANSAC算法共可以分为七步(难道是七步诗?),表示如下:

1. 特征提取  
分别在源点云和目标点云中检测关键点,并计算每个点的局部特征描述符(常用 FPFH、SHOT 等)。

2. 初始匹配  
基于特征距离(如欧氏距离或余弦距离)建立两组特征之间的初始对应关系,结果往往包含大量误匹配。

3. 随机采样  
在全部匹配对中随机抽取最小子集,该子集的大小需恰好能唯一确定一个刚体变换(通常 3 对匹配点即可求解 3D 刚体变换)。

4. 模型估计  
利用当前子集计算刚体变换矩阵(旋转 R 与平移 t)。

5. 内点检验  
将剩余所有匹配对按此变换投影,计算投影误差。误差小于给定阈值的匹配被视为内点。

6. 模型评估  
统计当前模型的内点数目,并与历史最优模型比较。若内点更多,则更新最优模型及其参数。

7. 迭代收敛  
重复步骤 3–6,直至达到预设迭代次数或找到满足置信度的模型。迭代次数可根据离群点比例与期望成功率自适应确定。最终输出内点最多的刚体变换,即为源点云到目标点云的配准结果。

        本次实验为了和前面的ICP对应上,依旧使用的是我们的老朋友——兔砸,显示如下:

一、RANSAC算法程序

import copy
import open3d as o3d
import numpy as np# -------------传入点云数据,计算FPFH------------
def FPFH_Compute(pcd):radius_normal = 0.01  # kdtree参数,用于估计法线的半径,pcd.estimate_normals(o3d.geometry.KDTreeSearchParamHybrid(radius=radius_normal, max_nn=30))# 估计法线的1个参数,使用混合型的kdtree,半径内取最多30个邻居radius_feature = 0.02  # kdtree参数,用于估计FPFH特征的半径pcd_fpfh = o3d.pipelines.registration.compute_fpfh_feature(pcd,o3d.geometry.KDTreeSearchParamHybrid(radius=radius_feature,max_nn=100))  # 计算FPFH特征,搜索方法kdtreereturn pcd_fpfh  # 返回FPFH特征# ----------------RANSAC配准--------------------
def execute_global_registration(source, target, source_fpfh,target_fpfh):  # 传入两个点云和点云的特征distance_threshold = 10  # 设定距离阈值# 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 resultif __name__ == "__main__":# -------------------读取点云数据--------------------source = o3d.io.read_point_cloud("E:/CSDN/规则点云/bunny.pcd")# 原始点云x轴平移0.1,y轴平移0.15,z轴平移0.2,然后加上噪声,最后新的点云作为目标点云# 平移target = copy.deepcopy(source)points = np.asarray(target.points)t = np.array([0.1, 0.15, 0.2])target = target.translate(t, relative=True)  # relative=True 表示“增量”平移# 加噪声mu, sigma = 0, 0.001  # 均值和标准差根据密度调节random_numbers = np.random.normal(mu, sigma, size=(points.shape[0], 3))points += random_numberstarget.points = o3d.utility.Vector3dVector(points)target.paint_uniform_color([0, 1, 0])  # 给目标点云赋予单色# --------------------计算法向量---------------------source.estimate_normals(search_param=o3d.geometry.KDTreeSearchParamHybrid(radius=0.01, max_nn=30))target.estimate_normals(search_param=o3d.geometry.KDTreeSearchParamHybrid(radius=0.01, max_nn=30))# 复制点云,防止更改source1 = copy.deepcopy(source)target1 = copy.deepcopy(target)# -----------------计算的FPFH---------------source_fpfh = FPFH_Compute(source1)target_fpfh = FPFH_Compute(target1)# ---------------调用RANSAC执行配准------------result_ransac = execute_global_registration(source1, target1,source_fpfh, target_fpfh)print("配准后信息:", result_ransac)  # 输出RANSAC配准信息print("两块点云之间的配准矩阵:", result_ransac.transformation)source2 = copy.deepcopy(source1)source2.transform(result_ransac.transformation)o3d.visualization.draw_geometries([source1, target1],window_name="两点云初始位置",width=1200, height=800,left=50, top=50)o3d.visualization.draw_geometries([source2, target1],window_name="配准后两点云初始位置",width=1200, height=800,left=50, top=50)

二、RANSAC算法结果

        从上面可以看出,经过RANSAC粗配准以后,点云可以很好的对齐。所以说明什么,有时候精配准和粗配准是相对的,不一定需要精配准!

        还有一点,上面的程序运行起来不快,因为是全局寻找特征点并且配准,所以速度就下来了。如果同学们想加快速度,可以使用前面咱们介绍的点云各种滤波,最好使用减少点云个数的。

就酱,下次见^-^

http://www.lryc.cn/news/612985.html

相关文章:

  • (Python)Python爬虫入门教程:从零开始学习网页抓取(爬虫教学)(Python教学)
  • 利用vue.js2X写前端搜索页面,express写后端API接口展现搜索数据
  • python数据结构与算法(基础)
  • DrissionPage自动化:高效Web操作新选择
  • 怎么在本地引入字体
  • 深入解析嵌套事务:原理与应用
  • 基于langchain的两个实际应用:[MCP多服务器聊天系统]和[解析PDF文档的RAG问答]
  • HTTP 协议升级(HTTP Upgrade)机制
  • 自动驾驶控制算法——滑模控制(SMC)原理与建模
  • TCP 如何保证可靠性
  • FluentUI-main的详解
  • 多账号管理方案:解析一款免Root的App分身工具
  • B-树与B+树
  • 动力电池点焊机:效率质量双提升,驱动新能源制造升级
  • Dify 从入门到精通(第 20/100 篇):Dify 的自动化测试与 CI/CD
  • Oracle exp imp expdp impdp 命令详解
  • PCB制造中压接孔、插接孔、沉头孔、台阶孔的区别及生产流程
  • 《C语言》函数练习题--1
  • 基于大数据的美食视频播放数据可视化系统 Python+Django+Vue.js
  • Vscode Data Wrangler 数据查看和处理工具
  • GitHub 上 Star 数量前 20 的开源 AI 项目
  • 中国MCP市场:腾讯、阿里、百度的本土化实践
  • 医疗人效管理新标杆:盖雅工场如何赋能健康服务企业提质增效
  • Java 大视界 -- Java 大数据在智能教育在线课程互动优化与学习体验提升中的应用(386)
  • 一篇文章用大白话带初学者搞清训练集、测试集及验证集关系及场景逻辑(包清楚)
  • LLMs api价格对比平台
  • --- Eureka 服务注册发现 ---
  • 【第7话:相机模型3】自动驾驶IPM图像投影拼接技术详解及代码示例
  • TikTok Shop冷启动破局战:亚矩阵云手机打造爆款账号矩阵
  • AWS RDS自定义终端节点深度分析工具:Python脚本详解