繁体   English   中英

使用 ICP 的 Open3D 注册显示错误 0 并返回输入转换

[英]Open3D registration with ICP shows error of 0 and returns the input transformation

我尝试使用 open3d 的 ICP 算法来找到最小化 2 个点云之间距离的转换,并大致遵循他们的教程页面: http://www.open3d.org/docs/latest/tutorial/pipelines/icp_registration.html (我使用 Ubuntu 20.04)

我尝试使用我的 ouster128 中的点云,但它没有用,因此我决定使用我用 numpy 创建的 2 个“虚拟”点云。icp 注册方法将转换作为输入,在我的例子中,总是返回输入转换(它基本上什么都不做,可能是因为错误为 0)。 这是代码(复制粘贴时应该可以使用):

import numpy as np
import copy
import open3d as o3d

def draw_registration_result(source, target, transformation):
    source_temp = copy.deepcopy(source)
    target_temp = copy.deepcopy(target)
    source_temp.paint_uniform_color([1, 0.206, 0])
    target_temp.paint_uniform_color([0, 0.651, 0.929])
    print("Transformation: " + str(transformation))
    source_temp.transform(transformation)
    coord_frame = o3d.geometry.TriangleMesh.create_coordinate_frame()
    o3d.visualization.draw_geometries([source_temp, target_temp, coord_frame],
                                  zoom=0.5,
                                  front=[0.9288, -0.2951, -0.2242],
                                  lookat=[0, 1, 1],
                                  up=[0, 0, 1])


src_points = np.array([
    [0.0, 0.0, 0.0],
    [1.0, 0.0, 0.0],
    [2.0, 0.0, 0.0],
    [0.0, 1.0, 0.0],
    [1.0, 1.0, 0.0],
    [2.0, 1.0, 0.0],
    [0.0, 2.0, 0.0],
    [1.0, 2.0, 0.0],
    [2.0, 2.0, 0.0],
    [0.0, 3.0, 0.0],
    [1.0, 3.0, 0.0],
    [2.0, 3.0, 0.0],
])
tgt_points = np.array([
    [0.0, 0.0, 0.1], # Due to the 0.1 the clouds do not match perfectly
    [1.0, 0.0, 0.1],
    [2.0, 0.0, 0.1],
    [0.0, 1.0, 0.1],
    [1.0, 1.0, 0.1],
    [2.0, 1.0, 0.1],
    [0.0, 2.0, 0.1],
    [1.0, 2.0, 0.1],
    [2.0, 2.0, 0.1],
    [0.0, 3.0, 0.1],
    [1.0, 3.0, 0.1],
    [2.0, 3.0, 0.1],
]) 
o3d.utility.set_verbosity_level(o3d.utility.VerbosityLevel.Debug)
source = o3d.geometry.PointCloud()
source.points = o3d.utility.Vector3dVector(src_points)

target = o3d.geometry.PointCloud()
target.points = o3d.utility.Vector3dVector(tgt_points)

trans_init = np.asarray([[1.0, 0.0, 0.0, 0.0],
                         [0.0, 1.0, 0.0, 0.0],
                         [0.0, 0.0, 1.0, 0.0],
                         [0.0, 0.0, 0.0, 1.0]])

threshold = 0.02
reg_p2p = o3d.pipelines.registration.registration_icp(
    source, target, threshold, trans_init,
    o3d.pipelines.registration.TransformationEstimationPointToPoint())
print("Post Registration")
print("Inlier Fitness: ", reg_p2p.fitness)
print("Inlier RMSE: ", reg_p2p.inlier_rmse)
draw_registration_result(source, target, reg_p2p.transformation)

sourcetarget是相同的点云。 唯一的区别是,该target在 z 方向上平移了 0.1。 初始变换是单位矩阵。 我期望的矩阵 output 与我相同,只是I[2][4]=0.1 现在, fitnessinlier_rmse为 0。这没有意义(除非我完全误解了某些东西),因为这意味着云完美匹配,而它们显然不会这样做。 有时适应度不为零(例如,当sourcetarget是同一朵云时,除了target的 3 个点平移了 0.1)。

我在发布此线程之前尝试过的操作:

  1. 2 个不同版本的 open3d(0.15.2 和 0.16.0)。
  2. 不同的点云
  3. 不同的初始变换
  4. 一些阈值,2e-10、2e-6、0.2

(可视化 window 是白色的,必须旋转相机才能看到云)那么,我在这里做错了什么? 提前致谢。

好的,我最后修好了。 我会责怪这种情况下的文档,因为它说:“max_correspondence_distance (float) – 最大对应点对距离。” 在他们的教程中,此参数称为“阈值”,我希望算法一直运行,直到误差小于阈值。 但是,如果误差大于阈值,则算法不会启动。 这应该在文档中更准确地表述。 特别是在教程中,这必须得到解决。 如果我使用 50 的阈值,它会按预期工作。

暂无
暂无

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM