gpt4 book ai didi

python - python 上的迭代最近点 (ICP) 实现

转载 作者:太空狗 更新时间:2023-10-29 16:54:31 24 4
gpt4 key购买 nike

我最近一直在寻找 ICP 算法在 python 中的实现,但没有结果。

根据维基百科文章http://en.wikipedia.org/wiki/Iterative_closest_point ,算法步骤为:

  • 按最近邻标准关联点(对于一个点云中的每个点,找到第二个点云中的最近点)。

  • 使用均方成本函数估计转换参数(旋转和平移)(转换会将每个点与其在上一步中找到的匹配项最佳对齐)。

  • 使用估计的参数转换点。

  • 迭代(重新关联点等)。

好吧,我知道 ICP 是一种非常有用的算法,它被用于各种应用程序。但是我找不到任何内置的 Python 解决方案。我在这里遗漏了什么吗?

最佳答案

最后,我设法使用 sklearn 和 opencv 库在 Python 中编写了自己的 ICP 实现。

该函数采用两个数据集,一个初始相对姿态估计和所需的迭代次数。它返回将第一个数据集转换为第二个数据集的转换矩阵。

尽情享受吧!

 import cv2
import numpy as np
import matplotlib.pyplot as plt
from sklearn.neighbors import NearestNeighbors


def icp(a, b, init_pose=(0,0,0), no_iterations = 13):
'''
The Iterative Closest Point estimator.
Takes two cloudpoints a[x,y], b[x,y], an initial estimation of
their relative pose and the number of iterations
Returns the affine transform that transforms
the cloudpoint a to the cloudpoint b.
Note:
(1) This method works for cloudpoints with minor
transformations. Thus, the result depents greatly on
the initial pose estimation.
(2) A large number of iterations does not necessarily
ensure convergence. Contrarily, most of the time it
produces worse results.
'''

src = np.array([a.T], copy=True).astype(np.float32)
dst = np.array([b.T], copy=True).astype(np.float32)

#Initialise with the initial pose estimation
Tr = np.array([[np.cos(init_pose[2]),-np.sin(init_pose[2]),init_pose[0]],
[np.sin(init_pose[2]), np.cos(init_pose[2]),init_pose[1]],
[0, 0, 1 ]])

src = cv2.transform(src, Tr[0:2])

for i in range(no_iterations):
#Find the nearest neighbours between the current source and the
#destination cloudpoint
nbrs = NearestNeighbors(n_neighbors=1, algorithm='auto',
warn_on_equidistant=False).fit(dst[0])
distances, indices = nbrs.kneighbors(src[0])

#Compute the transformation between the current source
#and destination cloudpoint
T = cv2.estimateRigidTransform(src, dst[0, indices.T], False)
#Transform the previous source and update the
#current source cloudpoint
src = cv2.transform(src, T)
#Save the transformation from the actual source cloudpoint
#to the destination
Tr = np.dot(Tr, np.vstack((T,[0,0,1])))
return Tr[0:2]

这样调用它:

#Create the datasets
ang = np.linspace(-np.pi/2, np.pi/2, 320)
a = np.array([ang, np.sin(ang)])
th = np.pi/2
rot = np.array([[np.cos(th), -np.sin(th)],[np.sin(th), np.cos(th)]])
b = np.dot(rot, a) + np.array([[0.2], [0.3]])

#Run the icp
M2 = icp(a, b, [0.1, 0.33, np.pi/2.2], 30)

#Plot the result
src = np.array([a.T]).astype(np.float32)
res = cv2.transform(src, M2)
plt.figure()
plt.plot(b[0],b[1])
plt.plot(res[0].T[0], res[0].T[1], 'r.')
plt.plot(a[0], a[1])
plt.show()

关于python - python 上的迭代最近点 (ICP) 实现,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/20120384/

24 4 0
Copyright 2021 - 2024 cfsdn All Rights Reserved 蜀ICP备2022000587号
广告合作:1813099741@qq.com 6ren.com