自适应点云配准(RANSAC、ICP)

这篇具有很好参考价值的文章主要介绍了自适应点云配准(RANSAC、ICP)。希望对大家有所帮助。如果存在错误或未考虑完全的地方,请大家不吝赐教,您也可以点击"举报违法"按钮提交疑问。

点云配准

完整代码:https://github.com/kang-0909/point-cloud-registration/tree/main,记得给个star~

实验目标

  • 任务一:将两个形状、大小相同的点云进行配准,进而估计两个点云之间的位姿。
  • 任务二:将一些列深度图反向投影得到点云,经过配准后,得到每个深度图之间的位姿变换,并将相应的点云融合到一起。

编译运行环境

项目 Python3 编写,实现 RANSAC 配准和 ICP 配准,用到 open3dnumpy 库。运行 python main.py src.ply tgt.ply save_path.ply ,读取源点云 src.ply,目标点云 tgt.ply,保存路径 save_path.ply。会显示三张图,分别为原始点云(源点云用红色标注,目标点云用绿色标注)、粗配准结果、精配准结果。

算法设计

任务一和任务二的主要思路一致,都是先对点云进行降采样、滤波后计算点云特征信息(包括法向量、特征直方图、以及后续特征匹配需要的若干特征),再利用提取的特征使用 RANSAC 的方法进行粗配准,最后使用 ICP 的方法进行精配准。

特征提取

【PCL学习笔记】之快速点特征直方图FPFH - pcl::FPFHSignature33 - Eba_

使用 FPFH(Fast Point Feature Histogram)算法。PFH(Point Feature Histogram)算法提取没给点邻域内两两点对间几何特征(一些角度信息),绘制直方图。FPFH 保留了 PFH 的大部分信息,但忽略了相邻点之间的计算,而是按照距离的反比将一个邻域内的点的直方图加权得到 33 维向量,效率更高。尝试了使用 PCA 进行降维以提高后续特征匹配速度,发现作用不大,遂舍弃。

粗配准

使用 RANSAC 的方法,总而言之就是对于源点云中的三个点,去“蒙”他们和目标点云中的那几个点相对应,然后计算变换矩阵,检验其优劣。简要流程如下:

  1. 在源点云中随机选择 3 个点。
  2. 分别查找他们在目标点云中特征向量最接近的点。这里的“接近”是欧式距离意义下的,查询数据结构使用 KD 树。
  3. 计算两个三角形之间的变换矩阵。其实就是按照 ICP 精配准的过程,求最小二乘法意义下的最优变换矩阵。
  4. 求出源点云在此变换之后的点云,计算其与目标点云的重合度(定义为源点云中阈值半径内存在目标点的点的个数)。
  5. 回到1,重复若干次,维护并返回重合度最高的变换。

实际编码中,由于 4 中 KD 树查询速度比较慢(33 维空间中接近于 O ( n ) O(n) O(n)),因提高在 1、2 中选择三角形对的质量是一个好的做法。这里三角形对的质量一是指他们匹配的可能性,二是通过他们计算出的变换矩阵是否准确。可以想到的方法有很多,比如三角形的边不能太短、两个三角形的对应边长不能差太多、优先选择特征向量远离均值的点等等。我的实现中采用了前两种。此外,在降采样后的点云上配准也可以提高效率。

精配准

【点云精配准】Iterative Closest Point(ICP)- Forrest Ding

具体推导过程就不赘述了。

深度图融合

上面的算法可以较好地完成对形状、大小相同的点云配准。但是,如果直接应用在深度图上,会出现匹配不上的问题(下面为 single-depth 匹配结果的俯视图):

ransac点云配准,算法,人工智能,图形渲染

这是因为 ICP 为每个源点云中的点,都从目标点云中找到一个距离最近的点和它匹配。但在深度图中,两个点云存在很多点本来就是不匹配的。如果强行令他们匹配,那么在最小二乘法的意义下最优解就是上图这样,一个点云被移动到了另一个的“中央”位置。

改进方法就是,对于源点云中的一个点,如果在目标点云中不存在和它的距离小于某个阈值的点,那么在此次迭代中就不考虑该点。同时,这个阈值随着迭代的进行不断减小的(有下限),这样就使得配准越来越精细。

关键代码

RANSAC

实现中还涉及两个细节。

一是匹配阈值设为多大合适?由于不同的数据具有不同的尺寸,我们想要得到点云(在某个表面上的)平均距离。这里使用了一种非常暴力的方法,考虑体素下采样 oldPcd.voxel_down_sample(voxel_size),采样到一定程度后,点云密集处的平均距离就是 voxel_size。因此将 RANSAC 的匹配阈值设置为 2.5 * voxel_size

二是如何判断两个三角形的差距?代码中如果对应边长度之差大于 lengthThreshold * 长度平均值。

这样,50 次有效采样就能计算出很好的转移矩阵。从下面的效果可以看出,即使是粗配准的效果就很好了。

def RANSAC():
    maxCount = 0
    jisuan=0
    j = 0
    print("RANSACing...")
    while True:
        j += 1
        // 随机选取三个点
        srcCorr = random.sample(range(srcNum), 3)
        // 如果某两个点距离太近,舍弃
        if not notTooClose3([srcPoints[x] for x in srcCorr]):
            continue
            
        // KD 树特征匹配
        tgtCorr = []
        for id in srcCorr:
            k, idx, dis2 = tgtFpfhKDT.search_knn_vector_xd(srcFpfh[id], knn=1)
            tgtCorr.append(random.choice(idx[0]))
            
        // 如果两个三角形差距太大,也舍弃
        if True in [farAway(srcPoints[i[0]] - srcPoints[j[0]], 
                            tgtPoints[i[1]] - tgtPoints[j[1]]) 
                    for i in zip(srcCorr, tgtCorr) 
                    for j in zip(srcCorr, tgtCorr)]:
            continue
        jisuan += 1
        
        // 得到变换矩阵
        R, T = calculateTrans(np.array([srcPoints[i] for i in srcCorr]), 
                              np.array([tgtPoints[i] for i in tgtCorr]))
        A = np.transpose((R @ srcPoints.T) + np.tile(T, (1, srcNum)))
        
        //计算匹配数
        count = 0
        for point in range(0, srcNum, 1):
            k, idx, dis2 = tgtKDT.search_hybrid_vector_3d(A[point], 
                                                          radius=fitThreshold, max_nn=1)
            count += k
        
        // 更新最大匹配
        if count > maxCount:
            maxCount = count
            bestR, bestT = R, T
        if jisuan > 50 and j > 1000:
            break
        
    print("RANSAC calculated %d times, maximum matches: %d" % (jisuan, maxCount))
    return bestR, bestT

ICP

def ICP(src, tgt):
    limit = fitThreshold
    retR = np.array([[1, 0, 0], [0, 1, 0], [0, 0, 1]])
    retT = np.array([[0], [0], [0]])
    trace = []
    for _ in range(400):
        tgtCorr = []
        srcCorr = []
        // 筛选距离近的点对
        for point in src:
            k, idx, dis2 = tgtKDT.search_knn_vector_3d(point, knn=1)
            if dis2[0] < (limit)**2:
                srcCorr.append(point)
                tgtCorr.append(tgt[idx[0]])
        trace.append([limit, len(srcCorr)])
        R, T = calculateTrans(np.array(srcCorr), np.array(tgtCorr))
        retR = R @ retR
        retT = R @ retT + T
        src = np.transpose((R @ src.T) + np.tile(T, (1, srcNum)))
        // 阈值的衰减
        limit = (limit - fitThreshold/1.5) * 0.95 + fitThreshold/1.5
        // 自适应过程,如果匹配点对不变化说明算法收敛,退出迭代
        if len(trace) > 50 and len(set([x[1] for x in trace[-20:]])) == 1:	
            break
    print("ICP trace is:", trace)
    return retR, retT

效果

在所有的测试数据中,算法都能够取得令人满意的结果,这里选择 airplane、person 以及 single-depth 三组数据进行展示。另外,如果直接对原始数据进行配准,会导致源点云和目标点云完全重合,只会显示单一的颜色,不利于观察效果。因此算法对每组数据都做了适量的下采样之后进行配准,因此能够看出是两个点云匹配的结果。

airplane:

配准前:
ransac点云配准,算法,人工智能,图形渲染

粗配准:

ransac点云配准,算法,人工智能,图形渲染

精配准:

ransac点云配准,算法,人工智能,图形渲染

person:

配准前:

ransac点云配准,算法,人工智能,图形渲染

粗配准:

ransac点云配准,算法,人工智能,图形渲染

精配准:

ransac点云配准,算法,人工智能,图形渲染

single-depth:

配准前(降采样后):

ransac点云配准,算法,人工智能,图形渲染

粗配准(降采样后):

ransac点云配准,算法,人工智能,图形渲染

精配准:

ransac点云配准,算法,人工智能,图形渲染

ransac点云配准,算法,人工智能,图形渲染文章来源地址https://www.toymoban.com/news/detail-784261.html

到了这里,关于自适应点云配准(RANSAC、ICP)的文章就介绍完了。如果您还想了解更多内容,请在右上角搜索TOY模板网以前的文章或继续浏览下面的相关文章,希望大家以后多多支持TOY模板网!

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处: 如若内容造成侵权/违法违规/事实不符,请点击违法举报进行投诉反馈,一经查实,立即删除!

领支付宝红包 赞助服务器费用

相关文章

  • KSS-ICP: 基于形状分析技术的点云配准方法

    目录 1. 概述 2. 算法实现 3. 实验结果 总结 Reference 三维点云配准是三维视觉领域一个经典问题,涉及三维重建,定位,SLAM等具体应用问题。传统的配准可以被分为两条技术路线,即基于全局姿态匹配的方法以及基于特征点对应的方法。全局姿态匹配通过在全局范围查找变换矩

    2023年04月08日
    浏览(88)
  • open3d点云配准函数registration_icp

    open3d快速上手 ICP, 即Iterative Closest Point, 迭代点算法。 ICP算法有多种形式,其中最简单的思路就是比较点与点之间的距离,对于点云 P = { p i } , Q = { q i } P={p_i}, Q={q_i} P = { p i ​ } , Q = { q i ​ } 而言,如果二者是同一目标,通过旋转、平移等操作可以实现重合的话,那么只需

    2023年04月19日
    浏览(47)
  • 点云配准(三) 传统点云配准算法概述

             图像配准是图像处理研究领域中的一个典型问题和技术难点,其目的在于比较或融合针对同一对象在不同条件下获取的图像,例如图像会来自不同的采集设备,取自不同的时间,不同的拍摄视角等等,有时也需要用到针对不同对象的图像配准问题。具体地说,对

    2024年02月02日
    浏览(50)
  • 点云配准——经典配准算法及配准效果对比

    目录 点云配准基础知识 什么是点云配准? 点云配准的步骤 粗配准 精配准  点云配准的经典算法 ICP算法 NDT算法 3DSC算法 PFH FPFH 完全配准效果对比         点云配准技术即是通过寻找不同视角下不同点云之间的映射关系,利用一定的算法将同一目标场景的不同点云转换到

    2024年02月02日
    浏览(42)
  • 多视图点云配准算法综述

    作者:杨佳琪,张世坤,范世超等 转载自:华中科技大学学报(自然科学版) 编辑:东岸因为@一点人工一点智能 原文:​​多视图点云配准算法综述​​ 摘要: 以多视图点云配准为研究对象,对近二十余年的多视图点云配准相关研究工作进行了全面的分类归纳及总结。首先

    2024年02月05日
    浏览(48)
  • 激光雷达点云基础-点云滤波算法与点云配准算法

    激光雷达点云处理在五年前就做了较多的工作,最近有一些新的接触发现激光雷达代码原理五年前未见重大更新,或许C++与激光雷达结合本身就是比较高的技术门槛。深度学习调包侠在硬核激光雷达技术面前可以说是完全的自愧不如啊。 1、点云滤波 在获取点云数据时,由于

    2024年03月19日
    浏览(49)
  • 基于深度学习方法的点云算法1——PointNetLK(点云配准)

    请点点赞,会持续更新!!! 基于深度学习方法的点云算法2——PointNet(点云分类分割) 基于深度学习方法的点云算法3——PointNet++(点云分类分割) 基于深度学习方法的点云算法4——PCT: Point Cloud Transformer(点云分类分割) 作者将PointNet看成一个可学习的成像函数(learn

    2024年02月10日
    浏览(44)
  • [点云配准]LCD(2D-3D特征配准算法)例程align_point_cloud.py解析

    跨域描述符LCD可以实现二维图片特征点到三维点云特征点的配准,是个具有通用性的深度学习特征描述子。(图片来源于论文 LCD: Learned Cross-Domain Descriptors for 2D-3D Matching ) 在Github开源的源码里面给出了利用LCD进行 三维点云配准 的例程。align_point_cloud.py,这里对例程如何使用

    2024年02月08日
    浏览(45)
  • 大盘点!汇总点云分割算法,涉及RANSAC、欧式聚类、区域增长等

    作者:PCIPG-zzl | 来源:计算机视觉工坊 添加微信:dddvisiona,备注:3D点云,拉你入群。文末附行业细分群。 点云分割的目标是将点云数据中的点分成不同的组或类别,使每个组中的点都属于同一种物体或区域。根据空间,几何和纹理等特征对点云进行划分,使同一划分内的

    2024年02月04日
    浏览(42)
  • 随机采样一致性(RANSAC)三维点云的平面拟合算法(含C++代码)

            随机采样一致性(Random sample consensus,RANSAC) :RANSAC是一种鲁棒的模型拟合方法,它可以处理存在大量噪声和异常值的数据。在进行平面拟合时,RANSAC会随机选择三个点,然后计算这三个点确定的平面模型。然后,RANSAC会计算其他所有点到这个平面的距离,并根据

    2024年02月07日
    浏览(42)

觉得文章有用就打赏一下文章作者

支付宝扫一扫打赏

博客赞助

微信扫一扫打赏

请作者喝杯咖啡吧~博客赞助

支付宝扫一扫领取红包,优惠每天领

二维码1

领取红包

二维码2

领红包