从基本矩阵中提取平移和旋转
Extract Translation and Rotation from Fundamental Matrix
我试图从计算的基本矩阵中检索平移和旋转向量。我确实使用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;
最后,我尝试将估计的旋转与我使用每个图像中的棋盘计算的旋转进行比较(我计划在没有棋盘的情况下获得外部参数)。例如,我得到这个:
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]
很明显好像有问题,我就是想不出是什么。
编辑:以下是我用未转置的vt得到的结果(显然来自另一个场景):
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]
这是我的计算相机矩阵,误差很低(约0.17…)。
[1699.001342509651, 0, 834.2587265398068;
0, 1696.645251354618, 607.1292618175946;
0, 0, 1]
这是我在尝试重新投影立方体时得到的结果…摄像机0,立方体与坐标轴对齐,旋转和平移为(0,0,0)。图像http://imageshack.us/a/img802/5292/bildschirmfoto20130110u.png
和另一个,与第一个图像中的点的尾线。图像http://imageshack.us/a/img546/189/bildschirmfoto20130110uy.png
请看下面的链接:
DIKU-3DCV2/资料/Lecture16.pdf。
替代链接参见第2页。r有两种可能,第一种是UWVT,第二种是UWTVT。你用的是第二种。
8点算法是计算基本矩阵的最简单方法,但如果注意的话,您可以很好地执行它。在构造求解方程之前,对输入数据进行适当的规范化处理是获得良好结果的关键。很多算法都能做到。像素点坐标必须更改为相机坐标,您可以在这一行进行更改:
Mat E = A.t() * F * A;
然而,这个假设是不准确的。如果摄像机标定矩阵K已知,则可以对点x应用逆,得到归一化坐标表示的点。
X_{norm}= K.inv()*X_{pix}
,其中X_{pix}(2)
, z = 1。
在8PA的情况下,简单的点变换提高了结果的稳定性。建议的归一化是对每个图像进行平移和缩放,使参考点的质心位于坐标的原点,并且点到原点的均方根距离等于sqrt{2}
。请注意,建议在非正规化之前执行奇点条件。
参考:如果:你仍然感兴趣,请查看
- 从包含m行的文件中提取n行,必要时(惰性地)重复该文件
- 如何从 std::atomic 中提取指针 T<T>?
- 与互斥锁相比,旋转锁可以保证上下文切换
- 为什么istream不支持右值提取
- 绘制旋转的三角形
- 如何设置一个范围来提取我想要获得的信息
- 旋转模型矩阵时的形状失真
- 四边形的 2D 旋转
- 垂直方向的 Gtk3+ 旋转按钮 (c/c++)
- 发布旋转矩阵(openGL/glm)
- 视觉工作室项目.提取源文件夹名称
- C++17 - 使用自定义分配器的节点提取/重新插入 - 适用于 clang++/libc++,但不适用于 libstd
- 顺时针迭代旋转 3 位数字
- 从字符串中提取整数并形成一个数组
- C ++中的StringStream有助于使用向量从字符串中提取逗号分隔的整数,而不是空格分隔的整数,为什么?
- asn1c 不会从 asn.1 模块中提取八位字节字符串的默认值
- 从 std::vector<无符号字符>切片中提取 int?
- 在C++中使用重载提取运算符时出现问题
- 从特征::等距3d提取旋转时出错
- 从基本矩阵中提取平移和旋转