变换列表的平均变换矩阵
Posted
技术标签:
【中文标题】变换列表的平均变换矩阵【英文标题】:Average transformation matrix for a list of transformations 【发布时间】:2014-02-10 02:13:49 【问题描述】:我对转换矩阵有多个估计,从通过ICP (Iterative Closest Point) 将两个点云相互映射。
如何为所有这些矩阵生成平均变换矩阵?
每个矩阵只包含一个刚性平移和一个旋转,没有缩放或倾斜。
理想情况下,我还想计算一个加权平均值,但现在可以使用未加权的平均值。
平均平移向量当然是微不足道的,但旋转是有问题的。我发现的一种方法是对旋转的各个基向量进行平均,但我不确定这会产生新的正交基,而且这种方法似乎有点特别。
【问题讨论】:
正交是一组约束;您应该研究受约束的最小二乘求解器。不幸的是,这些约束是非线性的(尽管它们在非线性约束中表现良好)。如果您想要一个最佳解决方案,您可能需要某种迭代过程,以找到最接近您的输入语料库的有效旋转矩阵。 我没有资格回答这个问题。但是,我使用了来自神经科学的 Python 库来获取欧拉旋转方程 (NiPY)。该库对极点等非常小心。然后,要从非线性变换中获取伪 Hermition 矩阵,您可以在两个方向上执行平均并对其进行平均。 【参考方案1】:在平移和旋转中拆分变换是一个好的开始。平均翻译是微不足道的。
平均旋转并不是那么容易。大多数方法将使用四元数。所以需要将旋转矩阵转换为四元数。
近似平均值的最简单方法是线性混合,然后对四元数进行重新归一化:
q* = w1 * q1 + w2 * q2 + ... + w2 * qn
normalize q*
但是,这只是一个近似值。原因是两个旋转的组合不是通过添加四元数来执行的,而是通过将它们相乘来执行的。如果我们将四元数转换为对数空间,我们可以使用简单的线性混合(因为乘法会变成加法)。然后将四元数转换回原始空间。这就是球形平均的概念(Buss 2001)。如果幸运的话,你会发现一个支持四元数的 log 和 exp 的库:
start with q* as above
do until convergence
for each input quaternion i (index)
diff = q[i] * inverse(q*)
u[i] = log(diff, base q*)
//Now perform the linear blend
adapt := zero quaternion
weights := 0
for each input quaternion i
adapt += weight[i] * u[i]
weights += weight[i]
adapt *= 1/weights
adaptInOriginalSpace = q* ^ adapt (^ is the power operator)
q* = adaptInOriginalSpace * q*
您可以为adaptInOriginalSpace
定义一个阈值。如果它是一个非常非常小的旋转,你可以打破循环。该算法已被证明可以保留球体上的测地线距离。
【讨论】:
谢谢,这看起来很有希望。据我了解 (a,b,c,d) 和 (-a,-b,-c,-d) 代表相同的四元数,在添加它们之前有没有办法处理? 好吧,对于两个四元数,您可以检查点积。如果它小于零,则否定一个四元数(否则插值将越过球体的另一侧)。我不确定如何用两个以上的四元数来处理这个问题。如果您可以使所有点积> = 0,那就太好了。但是,在某些情况下这是不可能的。但是插值可能根本不合理。【参考方案2】:http://en.wikipedia.org/wiki/Quaternions_and_spatial_rotation 和http://en.wikipedia.org/wiki/Rotation_matrix#Quaternion 将为您提供一些优雅的数学运算以及将旋转矩阵转换为围绕旋转轴的旋转角度的方法。每次旋转将有两种可能的表示形式,旋转角度和旋转轴的符号不同。
您可以转换所有内容并将它们归一化为具有 +ve 旋转角度,然后计算出平均旋转角度和平均旋转轴,将其重新归一化为单位向量。
OTOH,如果您的意图是计算出最准确的转换估计,您需要写下任何候选转换的拟合优度的一些度量 - 平方误差之和通常在数学上很方便 - 然后求解一个优化问题,用于确定哪种变换使平方误差之和最小。这至少比对容易出错的个体进行平均估计更容易证明,而且可能更准确。
【讨论】:
平均角度和轴似乎是一个简单的解决方案,但您确定它在数学上是合理的吗?如果每个角度都与不同的轴相关,那么平均两个角度似乎很奇怪。 如果单个旋转非常正确,那么它们之间的差异应该非常小,这应该使简单的平均成为您真正需要做的一个很好的近似值。我认为在数学上合理(或统计上有效)要做的事情是写下给定潜在变换的观察的可能性,然后解决优化问题以找到与最高对数似然相关的潜在变换并解决非线性最小二乘问题可能与此非常接近。【参考方案3】:如果你有一个现有的 lerp 方法,那么有一个简单的解决方案:
count = 1
average_transform = Matrix.Identity(4)
for new_transform in list_of_matrices:
factor = 1/count
average_transform = lerp(average_transform, new_transform, factor)
count += 1
这只是有用的,因为更多的数学包具有 lerp 矩阵的能力,而不是平均大量矩阵。
因为我在其他地方没有遇到过这种方法,所以这里是一个非正式的证明:
如果有一个矩阵,只使用那个矩阵(第一个矩阵的因子等于 1) 如果有两个矩阵,我们需要第二个矩阵的 50%(第二个因素是 50%,所以我们会在现有第一个矩阵和新矩阵之间调整到一半) 如果有三个矩阵,我们需要每个矩阵的 33%,即前两个矩阵平均值的 66% 和第三个矩阵的 33%。 0.3333 的 lerp 系数使这种情况发生。等等。
我没有对矩阵进行过广泛的测试,但我已经成功地将其用作其他数据类型的滚动平均值。
【讨论】:
【参考方案4】:这里可以使用奇异值分解(SVD)。
取旋转矩阵和的SVD,然后平均旋转矩阵简单地由Ravg = UV'给出。
【讨论】:
这个答案背后有数学解释吗?这看起来很有趣。【参考方案5】:“sdfgeoff”我无法评论你的答案,因为我是新来的,但我认为你是最正确的。顺便说一句,漂亮而优雅的解决方案。如果您将球面线性插值 (SLERP) 与四元数一起使用,而不是线性插值 (LERP),那将是完美的,因为映射旋转的四元数(范数为 1 的四元数)在 4D 中定义了一个球体,并且在此之间进行插值实际上是在两点之间进行插值在球面上。
根据我在点云注册方面的经验,我想说这行不通。 ICP 不会返回与正确旋转相似的随机旋转。您需要使用更好的算法来注册您的点云(全局注册算法,如 FPFH、4PCS、K4PCS、BSC、FGR 等)。或者对转换进行更好的初始猜测。当使用良好的初始变换进行初始化时,ICP 只会给您完全错误的旋转(当陷入局部最小值时)或几乎完美的旋转。 结论:取平均值是行不通的。
【讨论】:
以上是关于变换列表的平均变换矩阵的主要内容,如果未能解决你的问题,请参考以下文章