Пример #1
0
void DecomposeProjectionMatrix(const Mat& P, Mat3* K, Mat3* R, Vec3* t)
{
    // This is a modified version of the function "KRt_From_P", found in libmv and openMVG.
    // It is subject to the terms of the Mozilla Public License, v. 2.0, a copy of the MPL
    // can be found under "license.openMVG"

    // Decompose using the RQ decomposition HZ A4.1.1 pag.579.
    Mat3 Kp = P.block(0, 0, 3, 3);
    Mat3 Q; Q.setIdentity();

    // Set K(2, 1) to zero.
    if (Kp(2, 1) != 0)
    {
        double c = -Kp(2, 2);
        double s =  Kp(2, 1);
        double l = sqrt(c * c + s * s);
        c /= l; s /= l;
        Mat3 Qx;
        Qx <<  1,  0,  0,
               0,  c, -s,
               0,  s,  c;
        Kp = Kp * Qx;
        Q = Qx.transpose() * Q;
    }

    // Set K(2, 0) to zero.
    if (Kp(2, 0) != 0)
    {
        double c = Kp(2, 2);
        double s = Kp(2, 0);
        double l = sqrt(c * c + s * s);
        c /= l; s /= l;
        Mat3 Qy;
        Qy <<  c,  0,  s,
               0,  1,  0,
              -s,  0,  c;
        Kp = Kp * Qy;
        Q = Qy.transpose() * Q;
    }

    // Set K(1, 0) to zero.
    if (Kp(1, 0) != 0)
    {
        double c = -Kp(1, 1);
        double s =  Kp(1, 0);
        double l = sqrt(c * c + s * s);
        c /= l; s /= l;
        Mat3 Qz;
        Qz <<  c, -s,  0,
               s,  c,  0,
               0,  0,  1;
        Kp = Kp * Qz;
        Q = Qz.transpose() * Q;
    }

    Mat3 Rp = Q;

    // Ensure that the diagonal is positive and R determinant == 1
    if (Kp(2, 2) < 0)
    {
        Kp = -Kp;
        Rp = -Rp;
    }

    if (Kp(1, 1) < 0)
    {
        Mat3 S;
        S <<  1,  0,  0,
              0, -1,  0,
              0,  0,  1;
        Kp = Kp * S;
        Rp = S  * Rp;
    }

    if (Kp(0, 0) < 0)
    {
        Mat3 S;
        S << -1,  0,  0,
              0,  1,  0,
              0,  0,  1;
        Kp = Kp * S;
        Rp = S  * Rp;
    }

    // Compute translation.
    Vec3 tp = Kp.colPivHouseholderQr().solve(P.col(3));

    if(Rp.determinant() < 0)
    {
        Rp = -Rp;
        tp = -tp;
    }

    // Scale K so that K(2, 2) = 1
    Kp = Kp / Kp(2, 2);

    *K = Kp;
    *R = Rp;
    *t = tp;
}