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

Java 基本矩阵的分解会导致错误的旋转和平移,java,opencv,computer-vision,Java,Opencv,Computer Vision,我正在做一些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, ca

我正在做一些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 coherent\n";
            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);
}
这里是我正在使用的图像:和

在计算特征点等之前,我正在对图像进行无失真处理

有人能指出哪里出了问题或者我做错了什么吗

编辑:问题 我的基本矩阵是否可能等于基本矩阵,因为我处于校准状态,Hartley和zissermann说:

“11.7.3校准后的机箱:
在校准摄像机的情况下,可以使用标准化图像坐标,首先计算基本矩阵E而不是基本矩阵“

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

第二,对于两个摄像机定义基本矩阵和本质矩阵,如果只考虑一个摄像机,则没有意义。如果您有两台摄像机,分别具有矩阵K1和K2,那么您可以使用以下公式(参见Hartley&Zisserman书中的等式9.12)获得基本矩阵E12,给定基本矩阵F12(将I1中的点映射到I2中的线):

E12=K2T。F12。K1


在你的例子中,你在两边都使用了K2。

我发现了错误。此代码没有执行正确的矩阵乘法

  Mat E = new Mat();
  Core.multiply(cameraMatrix.t(),fundamental, E); 
  Core.multiply(E, cameraMatrix, E);
我把这个改成了

  Core.gemm(cameraMatrix.t(), fundamental, 1, cameraMatrix, 1, E);
现在正在做正确的矩阵乘法。就我从文档中得到的ir而言,Core.multiply正在对每个元素进行乘法运算。不是行*列的点积

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