基本矩阵的分解:验证 R 和 T 的四种可能解决方案

2023-12-11

我想使用 OpenCV 进行一些运动结构。 到目前为止,我已经有了基本矩阵和基本矩阵。 有了基本矩阵,我正在做 SVD 来获得 R 和 T。

我的问题是,我有 2 个可能的 R 解决方案和 2 个可能的 T 解决方案,这导致整体姿势有 4 个解决方案,其中 4 个解决方案中只有一个是正确的。 我怎样才能找到正确的解决方案?

这是我的代码:

private void calculateRT(Mat E, Mat R, Mat T){

    Mat w = new Mat();
    Mat u = new Mat();
    Mat vt = new Mat();

    Mat diag = new Mat(3,3,CvType.CV_64FC1);
    double[] diagVal = {1,0,0,0,1,0,0,0,1};
    diag.put(0, 0, diagVal);

    Mat newE = new Mat(3,3,CvType.CV_64FC1);

    Core.SVDecomp(E, w, u, vt, Core.DECOMP_SVD); 

    Core.gemm(u, diag, 1, vt, 1, newE);

    Core.SVDecomp(newE, w, u, vt, Core.DECOMP_SVD);

    publishProgress("U: " + u.dump());
    publishProgress("W: " + w.dump());
    publishProgress("vt:" + vt.dump());

    double[] W_Values = {0,-1,0,1,0,0,0,0,1};
    Mat W = new Mat(new Size(3,3), CvType.CV_64FC1);
    W.put(0, 0, W_Values);

    double[] Wt_values = {0,1,0-1,0,0,0,0,1};
    Mat Wt = new Mat(new Size(3,3), CvType.CV_64FC1);
    Wt.put(0,0,Wt_values);


    Mat R1 = new Mat();
    Mat R2 = new Mat();

    // u * W * vt = R 
    Core.gemm(u, Wt, 1, vt, 1, R2);
    Core.gemm(u, W, 1, vt, 1, R1);

    publishProgress("R: " + R.dump());


    // +- T (2 possible solutions for T)
    Mat T1 = new Mat();
    Mat T2 = new Mat();
    // T = u.t
    u.col(2).copyTo(T1);

    publishProgress("T : " + T.dump());

    Core.multiply(T, new Scalar(-1.0, -1.0, -1.0), T2);

    // TODO Here I have to find the correct combination for R1 R2 and T1 T2

}

从两个相机的基本矩阵重建它们的相对欧几里得姿态时,存在理论上的模糊性。这种模糊性与以下事实有关:给定图像中的 2D 点,经典的针孔相机模型无法判断相应的 3D 点是在相机前面还是在相机后面。为了消除这种歧义,您需要知道图像中的一个点对应关系:因为这两个 2D 点被假定为位于两个摄像机前面的单个 3D 点的投影(因为它在两个图像中都可见),这将有助于选择正确的 R 和 T。

为此,以下博士论文的第 6.1.4 (p47) 节中解释了一种方法:“三焦点张量的几何、约束和计算”,作者:C.Ressl(PDF)。下面给出该方法的概要。我将用 x1 和 x2 表示两个相应的 2D 点,用 K1 和 K2 表示两个相机矩阵,用 E12 表示基本矩阵。

我。计算基本矩阵的 SVDE12 = U * S * V'. If det(U) < 0 set U = -U. If det(V) < 0 set V = -V.

二.定义W = [0,-1,0; 1,0,0; 0,0,1], R2 = U * W * V' and T2 = third column of U

三.定义M = [ R2'*T2 ]x, X1 = M * inv(K1) * x1 and X2 = M * R2' * inv(K2) * x2

iv. If X1(3) * X2(3) < 0, set R2 = U * W' * V'并重新计算M and X1

v. If X1(3) < 0 set T2 = -T2

六.定义P1_E = K1 * [ I | 0 ] and P2_E = K2 * [ R2 | T2 ]

符号'表示转置和符号[.]x在步骤 iii 中使用。对应于斜对称算子。在 3x1 向量上应用斜对称运算符e = [e_1; e_2; e_3]结果如下(参见维基百科关于交叉产品的文章):

[e]x = [0,-e_3,e_2; e_3,0,-e_1; -e_2,e_1,0]

最后,请注意,范数T2将始终为 1,因为它是正交矩阵的列之一。这意味着您将无法恢复两个摄像机之间的真实距离。为此,您需要知道场景中两点之间的真实距离,并考虑到该距离来计算摄像机之间的真实距离。

本文内容由网友自发贡献,版权归原作者所有,本站不承担相应法律责任。如您发现有涉嫌抄袭侵权的内容,请联系:hwhale#tublm.com(使用前将#替换为@)

基本矩阵的分解:验证 R 和 T 的四种可能解决方案 的相关文章

随机推荐