C++ 从基本矩阵中提取平移和旋转

C++ 从基本矩阵中提取平移和旋转,c++,opencv,matrix,rotation,translation,C++,Opencv,Matrix,Rotation,Translation,我试图从计算的基本矩阵中检索平移和旋转向量。我确实使用OpenCV,一般的方法来自维基百科。我的代码如下: //Compute Essential Matrix Mat A = cameraMatrix(); //Computed using chessboard Mat F = fundamentalMatrix(); //Computed using matching keypoints Mat E = A.t() * F * A; //Perfrom SVD on E SVD decom

我试图从计算的基本矩阵中检索平移和旋转向量。我确实使用OpenCV,一般的方法来自维基百科。我的代码如下:

//Compute Essential Matrix
Mat A = cameraMatrix(); //Computed using chessboard
Mat F = fundamentalMatrix(); //Computed using matching keypoints
Mat E = A.t() * F * A;

//Perfrom SVD on E
SVD decomp = SVD(E);

//U
Mat U = decomp.u;

//S
Mat S(3, 3, CV_64F, Scalar(0));
S.at<double>(0, 0) = decomp.w.at<double>(0, 0);
S.at<double>(1, 1) = decomp.w.at<double>(0, 1);
S.at<double>(2, 2) = decomp.w.at<double>(0, 2);

//V
Mat V = decomp.vt; //Needs to be decomp.vt.t(); (transpose once more)

//W
Mat W(3, 3, CV_64F, Scalar(0));
W.at<double>(0, 1) = -1;
W.at<double>(1, 0) = 1;
W.at<double>(2, 2) = 1;

cout << "computed rotation: " << endl;
cout << U * W.t() * V.t() << endl;
cout << "real rotation:" << endl;
Mat rot;
Rodrigues(images[1].rvec - images[0].rvec, rot); //Difference between known rotations
cout << rot << endl;
很明显,这似乎是一个问题,我只是不知道它可能是什么

编辑: 以下是我在未转换vt时得到的结果(显然来自另一个场景):

这是我的计算相机矩阵,误差很小(大约0.17…)

以下是我在尝试重新投影立方体时得到的结果。。。 摄影机0,立方体是轴对齐的,旋转和平移是(0,0,0)。

另一个是第一张图像中点的轮廓线。
请查看此链接:


参见第2页。R有两种可能。第一种是UWVT,第二种是UWTVT。你用了第二个。尝试第一种方法。

8点算法是计算基本矩阵的最简单方法,但如果小心,您可以很好地执行它。获得良好结果的关键是在构造要求解的方程之前对输入数据进行适当的仔细归一化。许多算法都可以做到这一点。 像素点坐标必须更改为摄影机坐标,您可以在以下行中执行此操作:

mate=A.t()*F*A

然而,这一假设并不准确。如果已知摄像机校准矩阵K,则可以对点x应用反向,以获得以标准化坐标表示的点

X{norm}=K.inv()*X{pix}
其中
X{pix}(2)
,z等于1

在8PA的情况下,简单的点变换可以提高结果的稳定性。建议的标准化是每个图像的平移和缩放,以使参考点的质心位于坐标原点,且点与原点的RMS距离等于
\sqrt{2}
。注意,建议在反规范化之前执行奇点条件


参考:检查一下:

decomp.vt
是V转置,而不是V。如果你说
U*W.t()*V
,你会得到什么?请原谅我迟来的回答,谢谢你的更正。我显然忘记了这个。我用新的结果更新了答案,不幸的是,它们似乎仍然不完全正确。计算的失真系数是否也应该以某种方式乘以基本矩阵?我的cameraMatrix可能是错误的吗?这个公式来自维基百科。我在第一篇文章中添加了我当前的矩阵。唉,除了维基百科,我不确定这个算法的细节。你有没有用这些矩阵旋转图像,看看它与原始图像的对齐程度?谢谢。这正是我所缺少的。我还可以推荐新书《通过实际的计算机视觉项目掌握OpenCV》中非常简单易懂的资源。谢谢-我不知道这本书。你能提供一个链接来解释如何确定哪个R是正确的吗?它写在幻灯片中,在我的例子中,我只是“测试过”通过将矩阵应用于实际点,得出四种可能的解决方案。也许您可以使用标准化平移向量的点积和每个R的第三列来实现更有效的测试。以查看它们是否“面向”正确的方向。现在的链接是:
computed rotation:
[0.8543027125286542, -0.382437675069228, 0.352006107978011;
  0.3969758209413922, 0.9172325022900715, 0.03308676972148356;
  0.3355250705298953, -0.1114717965690797, -0.9354127247453767]

real rotation:
[0.9998572365450219, 0.01122579241510944, 0.01262886032882241;
  -0.0114034800333517, 0.9998357441946927, 0.01408706050863871;
  -0.01246864754818991, -0.01422906234781374, 0.9998210172891051]
computed rotation: 
[0.8720599858028177, -0.1867080200550876, 0.4523842353671251;
 0.141182538980452, 0.9810442195058469, 0.1327393312518831;
-0.4685924368239661, -0.05188790438313154, 0.8818893204535954]
real rotation
[0.8670861432556456, -0.427294988334106, 0.2560871201732064;
 0.4024551137989086, 0.9038194629873437, 0.1453969040329854;
-0.2935838918455123, -0.02300806966752995, 0.9556563855167906]
[1699.001342509651, 0, 834.2587265398068;
  0, 1696.645251354618, 607.1292618175946;
  0, 0, 1]