本质矩阵的分解会导致错误的旋转和平移



我正在做一些 SfM,但在从基本矩阵中获取 R 和 T 时遇到麻烦。

这是我在源代码中所做的:

Mat fundamental = Calib3d.findFundamentalMat(object_left, object_right);
Mat E = new Mat();
Core.multiply(cameraMatrix.t(), fundamental, E); // cameraMatrix.t()*fundamental*cameraMatrix;
Core.multiply(E, cameraMatrix, E);
Mat R = new Mat();
Mat.zeros(3, 3, CvType.CV_64FC1).copyTo(R);
Mat T = new Mat();
calculateRT(E, R, T);
where `calculateRT` is defined as follows:
private void calculateRT(Mat E, Mat R, Mat T) {
    /*
     * //-- Step 6: calculate Rotation Matrix and Translation Vector
        Matx34d P;
        //decompose E 
        SVD svd(E,SVD::MODIFY_A);
        Mat svd_u = svd.u;
        Mat svd_vt = svd.vt;
        Mat svd_w = svd.w;
        Matx33d W(0,-1,0,1,0,0,0,0,1);//HZ 9.13
        Mat_<double> R = svd_u * Mat(W) * svd_vt; //
        Mat_<double> T = svd_u.col(2); //u3
        if (!CheckCoherentRotation (R)) {
            std::cout<<"resulting rotation is not coherentn";
            return 0;
        }
     */
    Mat w = new Mat();
    Mat u = new Mat();
    Mat vt = new Mat();
    Core.SVDecomp(E, w, u, vt, Core.DECOMP_SVD); // Maybe use flags
    Mat W = new Mat(new Size(3,3), CvType.CV_64FC1);
    W.put(0, 0, W_Values);
    Core.multiply(u, W, R);
    Core.multiply(R, vt, R);
    T = u.col(2);
}

这是计算后和计算期间所有矩阵的结果。

    Number matches: 10299
    Number of good matches: 590
    Number of obj_points left: 590.0

         CameraMatrix: 
                        [1133.601684570312,         0,             639.5;
                               0 ,          1133.601684570312,     383.5;
                               0,                   0,               1]

       DistortionCoeff: [0.06604336202144623; 0.21129509806633; 0; 0; -1.206771731376648]

    Fundamental: 
    [4.209958176688844e-08, -8.477216249742946e-08, 9.132798068178793e-05;
    3.165719895008366e-07, 6.437858397735847e-07, -0.0006976204595236443;
    0.0004532506630569588, -0.0009224427024602799, 1]
    Essential: 
    [0.05410018455525099, 0, 0;
    0, 0.8272987826496967, 0;
    0, 0, 1]
    U: (SVD)
    [0, 0, 1;
     0, 0.9999999999999999, 0;
     1, 0, 0]
    W: (SVD) 
    [1; 0.8272987826496967; 0.05410018455525099]
    vt: (SVD)
    [0, 0, 1;
     0, 1, 0;
     1, 0, 0]

    R: 
    [0, 0, 0;
     0, 0, 0;
     0, 0, 0]
    T: 
    [1; 0; 0]

为了完成,这是我正在使用的图像:左和右。

在计算FeaturePoints等之前,我正在对图像进行解散。

有人可以指出哪里出了问题或我做错了什么吗?

编辑:问题我的基本矩阵是否有可能等于基本矩阵,因为我处于校准的情况下,哈特利和齐瑟曼说:

"11.7.3 经校准的情况:在校准相机的情况下,可以使用归一化图像坐标,并计算基本矩阵E而不是基本矩阵"

我发现了失误。此代码未执行正确的矩阵乘法。

  Mat E = new Mat();
  Core.multiply(cameraMatrix.t(),fundamental, E); 
  Core.multiply(E, cameraMatrix, E);

我把它改成了

  Core.gemm(cameraMatrix.t(), fundamental, 1, cameraMatrix, 1, E);

现在正在做正确的矩阵乘法。据我从文档中得到的,Core.multiply正在为每个元素进行乘法运算。不是行*列的点积。

首先,除非您通过明确考虑相机矩阵的逆数来计算基本矩阵,否则您不在校准的情况下,因此您估计的基本矩阵不是基本矩阵。这也很容易测试:你只需要对基本矩阵进行特征分解,看看两个非零特征值是否相等(参见Hartley&Zisserman书中的§9.6.1)。

其次,基本矩阵

和基本矩阵都是为两个相机定义的,如果只考虑一个相机,则没有意义。如果你有两个相机,分别是K 1和K 2,那么你可以得到基本矩阵E 12,给定基本矩阵F 12(将I1中的点映射到I2中的线),使用以下公式(参见Hartley&Zisserman书中的等式9.12):

E12 = K2T .F12 .K1

在您的情况下,您在两侧都使用了 K2

相关内容

  • 没有找到相关文章