[英]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)
source
和target
是相同的点云。 唯一的区别是,该target
在 z 方向上平移了 0.1。 初始变换是单位矩阵。 我期望的矩阵 output 与我相同,只是I[2][4]=0.1
。 现在, fitness
和inlier_rmse
为 0。这没有意义(除非我完全误解了某些东西),因为这意味着云完美匹配,而它们显然不会这样做。 有时适应度不为零(例如,当source
和target
是同一朵云时,除了target
的 3 个点平移了 0.1)。
我在发布此线程之前尝试过的操作:
(可视化 window 是白色的,必须旋转相机才能看到云)那么,我在这里做错了什么? 提前致谢。
好的,我最后修好了。 我会责怪这种情况下的文档,因为它说:“max_correspondence_distance (float) – 最大对应点对距离。” 在他们的教程中,此参数称为“阈值”,我希望算法一直运行,直到误差小于阈值。 但是,如果误差大于阈值,则算法不会启动。 这应该在文档中更准确地表述。 特别是在教程中,这必须得到解决。 如果我使用 50 的阈值,它会按预期工作。
声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.