简单scipy.spatial.transform.Rotation.align_vectors测试脚本未返回正确的旋转

c8ib6hqw  于 5个月前  发布在  其他
关注(0)|答案(1)|浏览(80)

所以我试着让两个平面在中心在同一个地方的时候旋转,我失败了,所以我想出了这个非常简单的例子,两个矩形相对旋转90°,并写了下面的简短脚本

0.0 0.0 0.0
1.0 0.0 0.0
0.0 2.0 0.0
1.0 2.0 0.0

字符串

0.0 0.0 0.0
2.0 0.0 0.0
2.0 1.0 0.0
0.0 1.0 0.0
import numpy as np
import files
from scipy.spatial.transform import Rotation

from_ = np.genfromtxt(files.FROM)
to = np.genfromtxt(files.TO)

mean_from = np.mean(from_, axis=0)
mean_to = np.mean(to, axis=0)

centered_from = from_ - mean_from
centered_to = to - mean_to

rot,res = Rotation.align_vectors(centered_from,centered_to)
print(res)
sol = rot.as_quat()
print("({}f, {}f, {}f, {}f)".format(sol[0],sol[1],sol[2],sol[3]))

的数据
对于给定的向量集,最佳旋转不是唯一的或定义不好的。rot,res = Rotation.align_vectors(centered_from,centered_to)2.449489742783178(0.0f,0.0f,0.0f,1.0f)
为什么它会在这么简单的例子中失败呢?即使我使用一个更复杂的12点的例子,结果也不会正确对齐这些点。这些点在一个方向旋转90°,然后在另一个方向旋转180°
(复杂示例)* 点在一个方向上旋转90°,然后在另一个方向上旋转180° *

-1.061441 1.029105 0.3137982
-1.058325 0.6978046 0.3261206
-0.5160019 1.044142 0.5801408
-0.5128856 0.7128415 0.5924632
-0.5150666 1.089168 0.5781018
-0.5124189 0.733911 0.5916736
0.09491175 1.098186 0.6951484
0.09755945 0.7429286 0.7087202
-0.4337781 0.6063982 0.2094956
-0.3675401 0.5803195 0.08044138
-0.1081934 0.6057502 0.3767354
-0.04195532 0.5796715 0.2476811

0.6978049 -1.058325 -0.3261207
0.7128419 -0.5128859 -0.5924634
1.029105 -1.061442 -0.3137983
1.044142 -0.5160022 -0.580141
0.7339112 -0.512419 -0.5916737
0.7429286 0.09755942 -0.7087204
1.089168 -0.5150667 -0.5781019
1.098186 0.09491169 -0.6951486
0.5795034 -0.2047889 -0.1641395
0.5804876 -0.2047065 -0.1639829
0.6055822 -0.271027 -0.2931938
0.6065664 -0.2709446 -0.2930371


这就是我所做的一切,我不知道如何进一步解决这个问题

kuarbcqp

kuarbcqp1#

函数Rotation.align_vectors()假设两个矩阵中的向量顺序相同,但点的顺序不同。通过绘制它们可以看出这一点。
简单的例子from/to:
x1c 0d1x的数据



在from的例子中,它从(0,0)开始,移动到(1,0),对角移动到(2,0),然后移动到(1,2)。在to的例子中,它没有对角移动。没有旋转可以解决这个问题-它需要旋转和置换。
如果绘制复杂的示例,您会发现类似的结果。
为了解决这个问题,我尝试扩大搜索范围,以便搜索每个排列的每个旋转。
下面是我使用的代码:

import numpy as np
from scipy.spatial.transform import Rotation
import matplotlib.pyplot as plt
import math
import itertools
from tqdm import tqdm

def array_permutations(array):
    N = array.shape[0]
    for permute in itertools.permutations(range(N)):
        yield array[list(permute)], permute

def find_best_rotation(source, target):
    best_res = None
    best_rot = None
    best_perm = None
    for source_permuted, perm in tqdm(array_permutations(source), total=math.factorial(source.shape[0])):
        rot, res = Rotation.align_vectors(source_permuted, target)
        if best_res is None or res < best_res:
            best_res = res
            best_rot = rot
            best_perm = perm
    return best_rot, best_res, best_perm
    

limit = 8  # Only consider first N points of each dataset
rot, res, perm = find_best_rotation(from_[:limit], to[:limit])
print("({}f, {}f, {}f, {}f)".format(sol[0],sol[1],sol[2],sol[3]))

from_x = rot.apply(from_)[:, 0]
from_y = rot.apply(from_)[:, 1]
plt.figure(figsize=(6,6))
jitter = 0.005 # make points visible
plt.scatter(from_x + jitter, from_y + jitter)
plt.scatter(to[:, 0], to[:, 1])

字符串
这是它产生的结果:



关于此解决方案的一些说明:

  • 这只是搜索前8个点的排列,以保持易于处理。排列的数量随着阶乘而增加,因此这不会扩展到大量的点。搜索所有12个点的排列估计需要14小时。
  • 有些点似乎没有对应的点。在左边,有4个蓝色的点,但只有2个橙子的点。由于数据集中的其他点似乎匹配良好,我认为这是输入数据集的问题。
  • 可能有一种方法可以解决这个问题,而不需要搜索所有的排列。我也考虑过使用scipy.optimize.minimize来优化到最近点的距离,但由于局部最小值而没有这样做。(例如,在某些情况下,一个点可能需要远离它最近的邻居,因为那个邻居不是它真正的邻居。)

相关问题