我试图通过跟踪球体上的表面特征来跟踪球体的旋转。
TL; DR :对四元数求平均是否错误?
让我们跳过功能检测和匹配,只是OpenCV的ORB + FLANN。这给了我两个连续帧的两组(匹配的)关键点。
我根据关键点到球体中心1的距离,将关键点放置在球体上,从而将关键点投影到3d中。这为我提供了球坐标系中的关键点。
从匹配的关键点作为矢量,我计算出一组四元数,它们代表自上一帧(algorithm used)以来的旋转。
a = np.cross(v1,v2)
w = np.sqrt(np.linalg.norm(v1)**2 * np.linalg.norm(v2)**2) + np.dot(v1,v2)
return quaternion(w, a[0], a[1], a[2]).normalized()
因此,在这一点上,我的想法是所有这些四元数表示相同的旋转(正负噪声)。因此,从理论上讲,我应该能够计算四元数集的平均四元数,并且对自最后一帧(algorithm used)以来我的球体如何运动有了一个很好的认识。
np.linalg.eig(np.mean(np.array([np.outer(q,q) for q in quats]), axis=0))[0]
事实是,这将导致所有帧(或接近,如e ^ -06 close)的单元四元数:
quaternion(0.999999999865224, -4.24742027709118e-06, 1.4799762763963e-05, 5.69900765792268e-06)
(对所有四元数进行平均的“天真”实际上产生的结果看起来可能与原始旋转匹配,但我宁愿使用一种经过验证的方法)
所以,我有两种理论:
有想法吗?
1我知道我必须处理相机的投影,但是出于概念验证的目的,我选择忽略了这一点。
答案 0 :(得分:1)
您的问题是什么?目前尚不清楚您要查找什么。
但是,无论它是什么,您的算法显然都是错误的。球体上1点的移动并不能唯一地定义球体旋转。
我的想法是所有这些四元数都表示相同的旋转
不是。您可以使用公式从单个点的运动中查找四元数。通过该公式得出的旋转假定该点沿一个大圆移动。
旋转球体时,只有赤道上的点(由旋转轴定义)沿大圆运动,其余点沿其他更有趣的曲线运动。
更新:据我了解,您有噪音,跟踪伪影和其他恶作剧。一种方法可能是使用数值方法直接从这些点中找到欧拉角(不是四元数,需要对四元数进行归一化,即它们对于求解器而言不需要自由度)。简历中的DownhillSolver
或ConjGradSolver
可能对您有用。可能需要运行两次,找到旋转,然后用最差的预测降低10-20%的点,然后再次求解80-90%的好点。
更新2 参见图片。 绿线是作为球体旋转一部分的两点的实际运动。显然,它们绕相同的轴旋转,但不沿大圆圈旋转。红线是这对点之间沿大圆圈的旋转,这是由您错误应用的公式得出的。蓝色虚线是红色旋转的轴。希望您现在了解为什么无法应用该公式。