decomposeProjectionMatrix提供了意外的结果

时间:2019-04-23 15:29:33

标签: opencv

我有以下投影矩阵P

-375   0    2000  262500
-375  2000    0   262500
 -1    0      0    700

此投影矩阵在以像素为单位的检测器上投影以mm为单位的3D点(1px等于0.5mm),并且是根据本征矩阵K和非本征矩阵[R|t](其中{{1 }}是旋转矩阵,R是平移向量),关系为t

P = K [R|t]

由于某些原因,我需要将 2000 0 375 0 0 1 0 K = 0 2000 375 R = 0 1 0 t = 0 0 0 1 -1 0 0 700 分解回这些矩阵。当我使用P时,我将其作为旋转矩阵:

decomposeProjectionMatrix

对我来说,哪个看起来不像是旋转矩阵。

此外,当我从Open CV分解重建投影矩阵时,会得到以下矩阵:

 0   0   0
 0   0   0
-1   0   0

看起来很相似,但并不相同。

我想知道我做错了还是不幸,那是这种功能失败的罕见情况之一。

请注意,我自己进行了分解,得到了一致的结果,但是我宁愿尽可能多地使用Open CV函数。

1 个答案:

答案 0 :(得分:0)

问题似乎出在decomposeProjectionMatrix使用的RQ分解中。 即使矩阵P的第一平方不是奇异的,RQDecomp3x3函数也会给出错误的结果:

    0   0  375              0  0  0
R = 0   0  375         Q =  0  0  0
    0   0   1              -1  0  0

因此,一种解决方法是使用基于section 2.2 of Peter Sturm's lectures的自制函数(此处用Python编写):

def decomposeP(P):
    import numpy as np
    M = P[0:3,0:3]
    Q = np.eye(3)[::-1]
    P_b = Q @ M @ M.T @ Q
    K_h = Q @ np.linalg.cholesky(P_b) @ Q
    K = K_h / K_h[2,2]
    A = np.linalg.inv(K) @ M
    l = (1/np.linalg.det(A)) ** (1/3)
    R = l * A
    t = l * np.linalg.inv(K) @ P[0:3,3]
    return K, R, t

我使用反身份矩阵Q来构建非常规的Cholesky分解U U*,其中U是上三角。 此方法与Peter Sturm的方法略有不同,因为我们使用关系P = K[R|t],而在Peter Sturm的讲座中,使用的关系是P = K[R|-Rt]

仅使用Open CV的C ++实现比较棘手,因为它们并未真正公开用于Cholesky分解的功能...