Open3D注册ICP显示错误0,返回输入转换



我尝试使用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。初始变换是单位矩阵。我期望的输出矩阵和我一样,只是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

(可视化窗口是白色的,相机必须旋转才能看到云)我哪里做错了?提前谢谢。

好的,最后我把它修好了。在这种情况下,我将指责文档,因为它说:max_correspondence_distance (float) -最大对应点对距离。在他们的教程中,这个参数被称为"阈值"。我希望算法一直运行,直到误差小于阈值。但是,如果错误大于阈值,则算法不会启动。这一点应在文件中更精确地表述。特别是在教程中,这需要修正。如果我使用50的阈值,它会像预期的那样工作。

最新更新