查找相机矩阵的平移

时间:2012-10-20 22:59:48

标签: python camera computer-vision translation linear-algebra

关于计算机视觉的另一个问题。

相机矩阵(也称为投影矩阵)将3D点 X (例如在现实世界中)映射到图像点 x (在照片中,用于例子)通过以下关系:

l **x** = P **X**

P描述了相机的一些外部和内部特征(其方向,位置和投影属性)。当我们参考投影属性时,我们使用校准矩阵K.同样,R表示摄像机的旋转及其平移,因此我们可以将P写为:

P = K [ R | t ]

[R | t]表示矩阵R和t的串联。

R  is a matrix 3 X 3
t is a vector 3 X 1 
K is a matrix 3 X 3
[R | t ] is a matrix 3 X 4
As a consequence, P is a matrix 3 X 4

嗯,足够的介绍。我想找到相机矩阵P的翻译。根据Computer Vision with Python一书中的代码,可以这样找到:

def rotation_matrix(a):
    """ Creates a 3D rotation matrix for rotation
    around the axis of the vector a. """
    a = array(a).astype('float')
    R = eye(4)
    R[:3,:3] = linalg.expm([[0,-a[2],a[1]],[a[2],0,-a[0]],[-a[1],a[0],0]])
    return R

tmp = rotation_matrix([0,0,1])[:3,:3]
Rt = hstack((tmp,array([[50],[40],[30]])))
P = dot(K, Rt)
K, R = linalg.rq(P[:,:3])

# This part gets rid of some ambiguity in the solutions of K and R
T = diag(sign(diag(K)))
if linalg.det(T) < 0:
    T[1,1] *= -1
    K = dot(K, T)
    R = dot(T, R) # T is its own inverse

t = dot(linalg.inv(K), P[:,3])

代码是自包含的。我们有Rt矩阵[R | t]。像往常一样计算P并执行RQ因子分解。但是,我不明白那一部分。为什么我们只采用前3列?然后我们得到翻译向量作为K^{-1}的点积和P.的前3列。为什么?我没有找到理由,但也许这是显而易见的我错过了。

顺便说一下,代码似乎有些偏差。当我运行它时,我得到了一个翻译向量[ 50. -40. 30.],而不是我们用作输入的array([[50],[40],[30]])。我们应该完全一样。我不知道这是否是由于旋转矩阵造成的。我也很感激你的任何帮助。

谢谢!

1 个答案:

答案 0 :(得分:3)

您将翻译向量计算为inv(K) P 的第4列的乘法。请注意,在您的代码中,它说

t = dot(linalg.inv(K), P[:,3])

其中P[:,3]是投影矩阵的第四列,因为索引从0开始。这意味着从t开始需要返回P = [KR | Kt],因此Kt是第四栏。 inv(K) * Kt = t

您可以将P[:,:3]再次分解为校准矩阵K和旋转矩阵R,因为P = [KR | Kt]因为校准矩阵是上三角形而旋转矩阵是正交的。

至于为什么你得到的翻译载体与你预期的不同,我认为这可能是由于QR decompositions一般不是唯一的。根据维基百科,当我们要求R的所有对角元素都是正数时,它们才是唯一的。此处R是上三角矩阵,在您的情况下为K

如果矩阵K在对角线的任何位置都有负元素,则可能会从QR分解中找回不同的K(可能只在一个符号中有所不同)。这意味着您无法获得预期的t