Java 使用两幅图像查找摄影机旋转 更新

Java 使用两幅图像查找摄影机旋转 更新,java,opencv,computer-vision,Java,Opencv,Computer Vision,我有一个黑色的GoPro Hero4安装在无人机上,接收无人机的遥测数据,有时往往不准确。我需要通过从两个不同的帧计算相机的旋转和平移来验证遥测 我已经使用我从相机矩阵中提取的内在参数计算了基本矩阵,这是我通过OpenCV棋盘校准得到的 问题 现在我得到的结果都是垃圾,除非我把同一张照片和它本身进行比较。根据我使用的特征检测器或者我使用的是RANSAC还是LMEDS,它们也会有所不同,但我非常确定关键点匹配本身工作得很好。所以我相信我 或者分解基本矩阵并错误地检索其对应的角度 或即使重投影误差为

我有一个黑色的GoPro Hero4安装在无人机上,接收无人机的遥测数据,有时往往不准确。我需要通过从两个不同的帧计算相机的旋转和平移来验证遥测

我已经使用我从相机矩阵中提取的内在参数计算了基本矩阵,这是我通过OpenCV棋盘校准得到的

问题 现在我得到的结果都是垃圾,除非我把同一张照片和它本身进行比较。根据我使用的特征检测器或者我使用的是RANSAC还是LMEDS,它们也会有所不同,但我非常确定关键点匹配本身工作得很好。所以我相信我

或者分解基本矩阵并错误地检索其对应的角度

即使重投影误差为0.23,我的相机也没有很好地校准

一、 但是,我不知道如何验证哪一个是正确的(或者如果有的话)。我已经找到了基本矩阵分解的其他方法,比如这个方法,我不知道这种方法和我的方法有什么区别——使用org.opencv.calib3d.calib3d.decomposeEssentialMat(…)。有人想澄清一下吗

问题1:有人能检查我的角度检索是否正确吗

问题2:我不确定如何检查我的相机校准是否正确,但我将其与Calib3d.calibrationMatrixValues(..)检索到的参数一起发布在下面。我想这不是因为取回的视野与我相机的规格不同。你能确认一下吗

我正在使用Java和OpenCV 3.1

我感谢你的帮助

主要功能 分解本质 打印旋转矩阵 校准3D.校准矩阵值(cameraMatrix,新尺寸(1280720),6.17,4.55,输出参数…)
findHomography仅在两个平面之间查找透视变换。如果您正在拍摄的点不是平面的一部分,那么您的计算值将是虚假的。基本矩阵更符合您的要求。你可以把它分解为旋转和平移。好吧,我尝试了一种新的方法,但有些事情我还不完全清楚。我相应地编辑了上面的问题。焦距和主点偏移是内在参数。你通常通过摄像机校准得到它们:我想我有它们,尽管我对其他一些事情不确定。我再次编辑了我的问题。findHomography只能在两个平面之间找到透视变换。如果您正在拍摄的点不是平面的一部分,那么您的计算值将是虚假的。基本矩阵更符合您的要求。你可以把它分解为旋转和平移。好吧,我尝试了一种新的方法,但有些事情我还不完全清楚。我相应地编辑了上面的问题。焦距和主点偏移是内在参数。你通常通过摄像机校准得到它们:我想我有它们,尽管我对其他一些事情不确定。我再次编辑了我的问题。
        // Match keypoints
        // ....
        MatOfPoint2f firstImageMop2f = new MatOfPoint2f();
        firstImageMop2f.fromList(firstImageList);

        MatOfPoint2f secondImageMop2f = new MatOfPoint2f();
        secondImageMop2f.fromList(secondImageList);

        Mat essentialMat = org.opencv.calib3d.Calib3d.findEssentialMat(firstImageMop2f, secondImageMop2f,
                3.5714310113232735, new Point(3.1427346523449033, 2.383214663142159),
                org.opencv.calib3d.Calib3d.RANSAC, 0.999, 3);
        decomposeEssential(essentialMat);
private void decomposeEssential(Mat essentialMat) {
    Mat firstRotation = new Mat();
    Mat secondRotation = new Mat();
    Mat translation = new Mat();
    org.opencv.calib3d.Calib3d.decomposeEssentialMat(essentialMat, firstRotation, secondRotation, translation);
    printRotationMatrix(firstRotation, "Rotation matrix");
    printRotationMatrix(secondRotation, "Rotation matrix");
    printGeneralMatrix(translation, "Translation");
}
private void printRotationMatrix(Mat matrix, String description) {
    double x, y, z;
    double sy = Math.sqrt(matrix.get(0, 0)[0] * matrix.get(0, 0)[0]
                            + matrix.get(1, 0)[0] * matrix.get(1, 0)[0]);
    boolean singular = sy < 1e-6;

    if (!singular) {
        System.out.println(" as a non singular matrix");
        x = Math.atan2(matrix.get(2, 1)[0], matrix.get(2, 2)[0]); //roll
        y = Math.atan2(-matrix.get(2, 0)[0], sy); // pitch
        z = Math.atan2(matrix.get(1, 0)[0], matrix.get(0, 0)[0]); // yaw
    } else {
        System.out.println(" as a singular matrix");
        x = Math.atan2(-matrix.get(2, 1)[0], matrix.get(2, 2)[0]);
        y = Math.atan2(-matrix.get(2, 0)[0], sy);
        z = 0;
    }

    System.out.println("Axes angles: ");
    System.out.println("x (roll): " + Math.toDegrees(x));
    System.out.println("y (pitch): " + Math.toDegrees(y));
    System.out.println("z (yaw): " + Math.toDegrees(z));
}
    740.9127543750064 0.0 651.9773670991048 
    0.0 736.5104868078901 377.12407856315485 
    0.0 0.0 1.0 
    FoVx: 81.64086856941297
    FoVy: 52.09797490556325
    Focal length: 3.5714310113232735
    Principal point of view; x: 3.1427346523449033, y: 2.383214663142159
    Aspect ratio: 0.9940583185521892