Opencv 单应矩阵分解为旋转矩阵和平移向量

Opencv 单应矩阵分解为旋转矩阵和平移向量,opencv,matrix,rotation,homography,decomposition,Opencv,Matrix,Rotation,Homography,Decomposition,我正在使用opencv 2.4.4为android开发一个增强现实应用程序,在单应分解方面遇到了一些问题。 我们知道,单应矩阵定义为H=A[rt],其中A是固有的摄像机矩阵,R是旋转矩阵,t是平移向量。 我想用图片估计摄像机的视角,以及摄像机在3d房间中的方位 我可以用opencv函数估计单应矩阵:findHomography,我认为它是有效的!!! 以下是我的做法: static Mat mFindHomography(MatOfKeyPoint keypoints1, MatOfKeyPoi

我正在使用opencv 2.4.4为android开发一个增强现实应用程序,在单应分解方面遇到了一些问题。 我们知道,单应矩阵定义为H=A[rt],其中A是固有的摄像机矩阵,R是旋转矩阵,t是平移向量。 我想用图片估计摄像机的视角,以及摄像机在3d房间中的方位

我可以用opencv函数估计单应矩阵:findHomography,我认为它是有效的!!! 以下是我的做法:

static Mat mFindHomography(MatOfKeyPoint keypoints1, MatOfKeyPoint keypoints2, MatOfDMatch matches){
    List<Point> lp1 = new ArrayList<Point>(500);
    List<Point> lp2 = new ArrayList<Point>(500);

    KeyPoint[] k1 = keypoints1.toArray();
    KeyPoint[] k2 = keypoints2.toArray();

    List<DMatch> matchesList = matches.toList();

    if (matchesList.size() < 4){
        MatOfDMatch mat = new MatOfDMatch();
        return mat;
    }

    // Add matches keypoints to new list to apply homography
    for(DMatch match : matchesList){
        Point kk1 = k1[match.queryIdx].pt;
        Point kk2 = k2[match.trainIdx].pt;
        lp1.add(kk1);
        lp2.add(kk2);
    }

    MatOfPoint2f srcPoints = new MatOfPoint2f(lp1.toArray(new Point[0]));
    MatOfPoint2f dstPoints  = new MatOfPoint2f(lp2.toArray(new Point[0]));

    Mat mask = new Mat();

    Mat homography = Calib3d.findHomography(srcPoints, dstPoints, Calib3d.RANSAC, 10, mask); // Finds a perspective transformation between two planes. ---Calib3d.LMEDS Least-Median robust method 

    List<DMatch> matches_homo = new ArrayList<DMatch>();
    int size = (int) mask.size().height;
    for(int i = 0; i < size; i++){          
        if ( mask.get(i, 0)[0] == 1){
            DMatch d = matchesList.get(i);
            matches_homo.add(d);
        }
    }

    MatOfDMatch mat = new MatOfDMatch();
    mat.fromList(matches_homo);

    matchesFilterdByRansac = (int) mat.size().height;
    return homography;
}
请注意,opencv 3.0有一个同调分解函数(),但我正在为android使用opencv 2.4.4!!!java中有它的包装器吗

第二个问题是欧拉角中旋转矩阵的分解。是否存在以下问题:

    float[] eulerOrientation = new float[3];
SensorManager.getOrientation(rotationMatrix, eulerOrientation); 
我也用过这个,但效果不是更好

double pitch = Math.atan2(pose.get(2, 1)[0], pose.get(2, 2)[0]);
double roll = Math.atan2(-1*pose.get(2, 0)[0], Math.sqrt( Math.pow(pose.get(2, 1)[0], 2) + Math.pow(pose.get(2, 2)[0], 2)) );
double yaw = Math.atan2(pose.get(1, 0)[0], pose.get(0, 0)[0]);

非常感谢您的回复

我希望这个答案能帮助今天寻找解决方案的人

我的答案使用C++和OpenCV 2.4.9。我从opencv 3.0复制了decomposehomographymat函数。在计算单应之后,我使用复制的函数来分解单应。要过滤单应矩阵并从4个分解中选择正确答案,请检查我的答案

要从旋转矩阵获取euler角度,可以参考。用这种方法我能得到很好的结果

double pitch = Math.atan2(pose.get(2, 1)[0], pose.get(2, 2)[0]);
double roll = Math.atan2(-1*pose.get(2, 0)[0], Math.sqrt( Math.pow(pose.get(2, 1)[0], 2) + Math.pow(pose.get(2, 2)[0], 2)) );
double yaw = Math.atan2(pose.get(1, 0)[0], pose.get(0, 0)[0]);