我尝试使用 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)
源
和目标
是相同的点云。唯一的区别是,target
在 z 方向上平移了 0.1。初始变换是单位矩阵。我期望的输出矩阵与 I 相同,只是 I[2][4]=0.1
。现在,fitness
和 inlier_rmse
为 0。这没有任何意义(除非我完全误解了某些内容),因为这意味着云完全匹配,但它们显然不匹配做。有时适应度不为零(例如,当source
和target
是相同的云时,除了target
的3个点平移0.1 )。
在发布此帖子之前我尝试过的操作:
- 2 个不同版本的 open3d(0.15.2 和 0.16.0)。
- 不同的点云
- 不同的初始转换
- 一些阈值,2e-10、2e-6、0.2
(可视化窗口为白色,必须旋转相机才能查看云) 那么,我在这里做错了什么?提前致谢。
最佳答案
好的,最后我解决了。 在这种情况下,我会责怪文档,因为它说: “max_correspondence_distance (float) – 最大对应点对距离。” 在他们的教程中,这个参数称为“阈值”,我希望算法一直运行,直到误差小于阈值。但是,如果误差大于阈值,算法不会启动。这应该在文档中更准确地表述。尤其是在教程中,这个问题必须得到解决。如果我使用阈值 50,它会按预期工作。
关于python - Open3D 向 ICP 注册显示错误为 0 并返回输入转换,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/74878923/