Opencv 单应矩阵分解为旋转矩阵和平移向量
我正在使用opencv 2.4.4为android开发一个增强现实应用程序,在单应分解方面遇到了一些问题。 我们知道,单应矩阵定义为H=A[rt],其中A是固有的摄像机矩阵,R是旋转矩阵,t是平移向量。 我想用图片估计摄像机的视角,以及摄像机在3d房间中的方位 我可以用opencv函数估计单应矩阵:findHomography,我认为它是有效的!!! 以下是我的做法: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
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]);