如何为未知矩阵求解矩阵方程?

时间:2020-06-30 09:09:29

标签: python numpy opencv matrix camera

Camera Calibration and 3D reconstruction using opencv

我正在尝试求解equation,s m'= A [R | t] M'

m = K。 。 M ,其中 m,K,M T [R | t]

我想获取3 * 3旋转矩阵的每个元素的值。我有。

这个问题也得到了回答here

但是当我们每次为新的方程组设置 m M 。

m 包含以像素为单位的投影点的坐标,我在图像上有16个不同的点,用于相机捕获的图案,每个u和v都有16组值。

m=np.array([u,v,1])

K 是我的相机固有参数矩阵/相机矩阵/固有参数矩阵,我具有fx,fy(焦距)和cx,cy(主要点)的值作为相机固有值矩阵

K=np.matrix([ [fx, 0, cx, 0], 
              [ 0, fy, cy, 0], 
              [ 0, 0, 1, 0]])

T 是要传递到“世界”坐标系到摄像机坐标系(外部矩阵,[R | t])的转换,我也有Tx,Ty和Tz的值。

T= np.matrix([[x00, x01, x02, Tx], 
              [x10, x11, x12, Ty], 
              [x20, x21, x22, Tz], 
              [0 , 0 , 0 , 1 ]])

M 是笛卡尔坐标系“世界”中某个点的齐次坐标,即世界坐标空间中一个3D点的坐标。我有16个点,因此每个X,Y,Z都有16个不同的值。

M=np.array([X,Y,Z,1])

我的目标是获取矩阵 T 的元素x00,x01,x02,x10,x11,x12,x20,x21,x22的值。有人可以帮忙吗?

更多说明

假设对于 m 矩阵(以像素为单位的投影点坐标),u和v的值为:

u = [337,337,316,317,317,302,302,291,292,338,...]

v = [487,572,477,547,470,528,465,516,598,...]

即第一个投影点的像素为 337 (行号)和 487 (列号)

因此,

对于第一组方程,矩阵 m 将具有值,

import sympy as sy            
import numpy as np


# m = sy.Matrix([u, v, 1]
m = sy.Matrix([337, 487, 1])

第二组方程矩阵 m 将具有值,

# m = sy.Matrix([u, v, 1]
m = sy.Matrix([337, 572, 1])

很快...

对于 K 矩阵(内在参数矩阵)的值:

K = sy.Matrix([[711.629,  0, 496.220, 0],
               [0,  712.682, 350.535, 0],
               [0,   0,  0, 1]])

对于 M 矩阵(世界坐标空间中3D点的坐标),X,Y和Z的值是:

X = [4.25, 4.25, 5.32, 5.32, 6.27, 6.27, 7.28, 7.28, 4.20, ...] 
Y = 0
Z =  [0.63, 1.63, 0.63, 1.63, 0.59, 1.59, 0.60, 1.92, 2.92, ...]  

对于第一组方程,矩阵 M

# M=np.array([X,Y,Z,1])
M = sy.Matrix([0.63, 0, 4.25, 1])

对于第二组方程,矩阵 M 将具有值,

# M=np.array([X,Y,Z,1])
M = sy.Matrix([1.63, 0, 4.25, 1])

很快...

对于 T 矩阵(外部矩阵[[R | t]),我们将 Tx,Ty,Tz 的值设置为0,-1.35、0。因此,T矩阵将是:

T = sy.Matrix([[x11, x12, x13, 0],
               [x21, x22, x23, -1.32],
               [x31, x32, x33, 0],
               [0,     0,   0,  1]])

我需要制作九组这些矩阵方程式: m = K * T * M m M 使用不同的值,因此我可以从这些方程组中计算 T 矩阵中9个未知数的值。

1 个答案:

答案 0 :(得分:2)

基本上,您具有矩阵方程式(使用OpenCV文档的符号):

A @ (R @ w + t) == m

其中A.shape == (3, 3)R.shape == (3, 3)w.shape == (3, n)t.shape == (3, 1)m.shape == (3, n)代表世界坐标n中的w个点,并且图片坐标m

此等式可以重新排列为

w.T @ R.T == (inv(A) @ m - t).T

其中inv(A)A的倒数。左侧和右侧的形状为(n, 3)。它具有矩阵方程式的格式,具有9个未知数(在R.T中)和n个方程式。在这种形式下,您可以输入np.linalg.lstsq以获得最小二乘解-假设您拥有n >= 3且具有足够独立的点。

这是一个带有随机数的演示:

import numpy as np

# Setup test case
np.random.seed(1)
R = np.random.randint(-9, 9, size=(3, 3)).astype(np.float64)
t = np.array([1, 1.5, 2]).reshape(3, 1) # column vector
Rt = np.hstack([R, t]) # shape (3, 4)
A = np.diag([0.5, 0.5, 1.0]) # shape (3, 3)

n = 20 # number of points
# M: shape (4, n)
M = np.vstack([np.random.uniform(size=(3, n)), np.ones((1, n))])
m = A @ Rt @ M # m.shape == (3, n)

# Now try to reconstruct R, given A, M, t, and m.

w = M[:3, :] # world XYZ coordinates, shape (3, n)

# Matrix equation: A @ (R @ w + t) == m
# Equivalent to w.T @ R.T == (inv(A) @ m - t).T
RTfit, _, _, _ = np.linalg.lstsq(w.T, (np.linalg.inv(A) @ m - t).T, rcond=None)

Rfit = np.around(RTfit.T, 6)
print(f'Original R:\n{R}\nReconstructed R:\n{Rfit}')

输出:

Original R:
[[-4.  2.  3.]
 [-1.  0.  2.]
 [-4.  6. -9.]]
Reconstructed R:
[[-4.  2.  3.]
 [-1. -0.  2.]
 [-4.  6. -9.]]

请注意,您还可以使用三个数据点(n=3)进行精确求解:

Rsolve = np.linalg.solve(w.T[:3], (np.linalg.inv(A) @ m[:, :3] - t).T).T

但是在这种情况下,您需要仔细选择三个要点,否则将不起作用。

以下是您的数据尝试:

t = np.array([[0, -1.32, 0]]).T
w = np.array([
    [4.25, 4.25, 5.32, 5.32, 6.27, 6.27, 7.28, 7.28, 4.20],
    np.zeros(9),
    [0.63, 1.63, 0.63, 1.63, 0.59, 1.59, 0.60, 1.92, 2.92]
    ])
m = np.array([
    [337, 337, 316, 317, 302, 302, 291, 292, 338],
    [487, 572, 477, 547, 470, 528, 465, 516, 598],
    np.ones(9)
    ])
A = np.array([
    [711.629,  0, 496.220],
    [712.682, 350.535, 0],
    [0, 0, 1]
    ])
RTfit, _, _, _ = np.linalg.lstsq(w.T, (np.linalg.inv(A) @ m - t).T, rcond=None)
Rfit = np.around(RTfit.T, 6)
print(Rfit)

输出:

array([[-0.040938,  0.      , -0.016044],
       [ 0.448038,  0.      ,  0.52933 ],
       [ 0.14251 ,  0.      ,  0.127464]])

由于输入的所有Y值均为零,因此无法有意义地求解R矩阵的中间列。 (如果您使用np.linalg.solve进行此操作,则会出现奇异矩阵错误。)

拟合度不是特别好,如绘制mA @ (R @ w + t)所示:

xy coordinates of m: input versus fit

不匹配意味着不可能存在与数据一致的R矩阵。在您的评论中,您询问R矩阵是否是最佳解决方案。这是匹配等式(w.T @ Rfit.T(inv(A) @ m - t).T)的LHS和RHS的最佳解决方案。

鉴于上图中的巨大失配,推测产生的R矩阵的准确性没有多大意义。输入数据可能有问题;点(m,w),t向量或A矩阵。