我有两组3D点,每组最多10个点。它们的平移和缩放使得对于两个集合,每个点和原点之间的距离为1。一组点应仅通过平移Map到另一组点。但是,我不知道哪个点Map到哪个点。
我尝试了两件事:Kabsch和ICP。
Kabsch要求:
- 生成两组点之间所有匹配的集合
- 找到一个Map到另一个的R
- 返回点间距离最小的匹配和旋转R
也就是说,对于pts1
和pts2
,两个Nx3 numpy数组:
indices = list(len(pts1))
min_dist = np.inf
best_rot = None
for matching in itertools.permutations(indices, len(pts1)):
idx = list(matching)
pts2_p = pts2[idx,:]
# Kabsch to find best fit rotation with SVD
R = best_fit_rotation(pts1, pts2_p)
pts1p = R.dot(pts1.T).T
# calculate distances between each pair of points
d = distance(pts1p, pts2_p)
rmsd = np.sqrt(np.mean(d**2))
if rmsd < min_dist:
min_dist = rmsd
best_rot = R
字符串
这是可行的,但是对于超过N=6
的点来说,速度非常慢。这主要是因为需要考虑N!
排列,即~5000
对N=7
。
对于ICP,通常需要:
- 在另一个集合中找到每个点的最近邻居
- 查找最佳拟合变换(如Kabsch)
- 计算两组点之间的平均距离
- 重复,直到平均距离低于阈值
这样做的问题是,默认情况下,第一个集合中的两个点可以在第二个集合中具有相同的点作为其最近的邻居。我仍然需要迭代所有的匹配(尽管这样更快,因为我不必计算旋转矩阵,并重新计算每个匹配的距离)。然而,这种方法提供的旋转矩阵在数值上是不正确的。因此,我想知道:
1.我修改ICP的逻辑是否有缺陷?
1.无论如何,有没有更好的方法来解决这个问题?
1条答案
按热度按时间xtupzzrd1#
你真的很想在不测试所有设置的情况下正确地找到正确的成对对齐。一种方法是为集合中的点找到一个旋转和平移不变的顺序。例如,可以按点到集合质心的距离对点进行排序。如果这两个集合是1对1的Map,那么应该会给予你正确的配对。
如果有多个点到质心的距离相同,那么你需要生成多个配对并测试它们,但希望这个数字远远小于N!。在最坏的情况下,所有的点都是等距的质心,但我认为在这种情况下,你有多个正确的解决方案。
说到多个解决方案,您不一定需要检查所有N!(或最佳生成的)配对,以便最小化距离。一旦发现距离为零或小于可接受的阈值,您就可以立即返回。