简体   繁体   English

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

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

I try to use the ICP algorithm of open3d to find a transformation that minimizes the distance between 2 point clouds and loosely followed their tutorial page: http://www.open3d.org/docs/latest/tutorial/pipelines/icp_registration.html (I use Ubuntu 20.04)我尝试使用 open3d 的 ICP 算法来找到最小化 2 个点云之间距离的转换,并大致遵循他们的教程页面: http://www.open3d.org/docs/latest/tutorial/pipelines/icp_registration.html (我使用 Ubuntu 20.04)

I tried to use point clouds from my ouster128, but it didn't work and therefore I decided to use 2 'dummy' point clouds that I create with numpy. The icp registration method gets a transformation as input and, in my case, always returns the input transformation (it basically does nothing, probably because the errors are 0).我尝试使用我的 ouster128 中的点云,但它没有用,因此我决定使用我用 numpy 创建的 2 个“虚拟”点云。icp 注册方法将转换作为输入,在我的例子中,总是返回输入转换(它基本上什么都不做,可能是因为错误为 0)。 Here's the code (should be ready to use when copy pasted):这是代码(复制粘贴时应该可以使用):

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)

source and target are the same point clouds. sourcetarget是相同的点云。 Only difference is, that target is translated by 0.1 in z direction.唯一的区别是,该target在 z 方向上平移了 0.1。 The initial transformation is the identity matrix.初始变换是单位矩阵。 The matrix that I would expect as output is the same as I, just with I[2][4]=0.1 .我期望的矩阵 output 与我相同,只是I[2][4]=0.1 Now, the fitness and inlier_rmse are 0. Which makes no sense (unless I completely misunderstood something) as that would mean that the clouds match perfectly, which they obviously don't do.现在, fitnessinlier_rmse为 0。这没有意义(除非我完全误解了某些东西),因为这意味着云完美匹配,而它们显然不会这样做。 Sometimes the fitness is not zero (for example, when source and target are the same clouds, except that 3 points of target are translated by 0.1).有时适应度不为零(例如,当sourcetarget是同一朵云时,除了target的 3 个点平移了 0.1)。

What I tried before posting this thread:我在发布此线程之前尝试过的操作:

  1. 2 different versions of open3d (0.15.2 and 0.16.0). 2 个不同版本的 open3d(0.15.2 和 0.16.0)。
  2. different point clouds不同的点云
  3. different initial transformations不同的初始变换
  4. some thresholds, 2e-10, 2e-6, 0.2一些阈值,2e-10、2e-6、0.2

(The visualization window is white and the camera has to be rotated to view the clouds) So, what am I doing wrong here? (可视化 window 是白色的,必须旋转相机才能看到云)那么,我在这里做错了什么? Thanks in advance.提前致谢。

Ok, I fixed it in the end.好的,我最后修好了。 I'd blame the documentation in this case as it says: "max_correspondence_distance (float) – Maximum correspondence points-pair distance."我会责怪这种情况下的文档,因为它说:“max_correspondence_distance (float) – 最大对应点对距离。” In their tutorial this parameter is called "threshold" and I would expect the algorithm to run until the error is less than the threshold.在他们的教程中,此参数称为“阈值”,我希望算法一直运行,直到误差小于阈值。 However, the algorithm doesn't start if the error is bigger than the threshold.但是,如果误差大于阈值,则算法不会启动。 This should be formulated more precisely in the documentation.这应该在文档中更准确地表述。 And especially in the tutorial this has to be fixed.特别是在教程中,这必须得到解决。 If I use an threshold of 50 it works as expected.如果我使用 50 的阈值,它会按预期工作。

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

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