基本矩阵的分解:validationR和T的四种可能解
我想使用OpenCV做一些Motion-from-Motion。 到目前为止,我有基本的矩阵和基本矩阵。 有了基本矩阵我正在做SVD以获得R和T.
我的问题是我有两种可能的R解决方案和两种可能的T解决方案,这导致整体姿势的4种解决方案,其中4种解决方案中只有一种是正确的解决方案。 我怎样才能找到正确的解决方案?
这是我的代码:
private void calculateRT(Mat E, Mat R, Mat T){ Mat w = new Mat(); Mat u = new Mat(); Mat vt = new Mat(); Mat diag = new Mat(3,3,CvType.CV_64FC1); double[] diagVal = {1,0,0,0,1,0,0,0,1}; diag.put(0, 0, diagVal); Mat newE = new Mat(3,3,CvType.CV_64FC1); Core.SVDecomp(E, w, u, vt, Core.DECOMP_SVD); Core.gemm(u, diag, 1, vt, 1, newE); Core.SVDecomp(newE, w, u, vt, Core.DECOMP_SVD); publishProgress("U: " + u.dump()); publishProgress("W: " + w.dump()); publishProgress("vt:" + vt.dump()); double[] W_Values = {0,-1,0,1,0,0,0,0,1}; Mat W = new Mat(new Size(3,3), CvType.CV_64FC1); W.put(0, 0, W_Values); double[] Wt_values = {0,1,0-1,0,0,0,0,1}; Mat Wt = new Mat(new Size(3,3), CvType.CV_64FC1); Wt.put(0,0,Wt_values); Mat R1 = new Mat(); Mat R2 = new Mat(); // u * W * vt = R Core.gemm(u, Wt, 1, vt, 1, R2); Core.gemm(u, W, 1, vt, 1, R1); publishProgress("R: " + R.dump()); // +- T (2 possible solutions for T) Mat T1 = new Mat(); Mat T2 = new Mat(); // T = ut u.col(2).copyTo(T1); publishProgress("T : " + T.dump()); Core.multiply(T, new Scalar(-1.0, -1.0, -1.0), T2); // TODO Here I have to find the correct combination for R1 R2 and T1 T2 }
当从基本矩阵重建两个摄像机的相对欧几里德姿态时,存在理论上的模糊性。 这种模糊性与以下事实有关:给定图像中的2D点,经典的针孔相机模型无法判断相应的3D点是在相机前面还是在相机后面。 为了消除这种模糊性,您需要知道图像中的一个点对应关系:因为这两个2D点被假定为位于两个相机前面的单个3D点的投影(因为它在两个图像中都可见),这将使选择正确的R和T.
为此目的,在以下博士论文的第6.1.4节(第47页)中解释了一种方法:“三维张量的几何,约束和计算”,作者:C.Ressl( PDF )。 以下给出了该方法的概要。 我将用x1和x2表示两个相应的2D点,用K1和K2表示两个相机矩阵,用E12表示基本矩阵。
一世。 计算基本矩阵的SVD E12 = U * S * V'
。 如果det(U) < 0
设置U = -U
。 如果det(V) < 0
设定V = -V
。
II。 定义W = [0,-1,0; 1,0,0; 0,0,1]
W = [0,-1,0; 1,0,0; 0,0,1]
W = [0,-1,0; 1,0,0; 0,0,1]
, R2 = U * W * V'
, T2 = third column of U
III。 定义M = [ R2'*T2 ]x
, X1 = M * inv(K1) * x1
和X2 = M * R2' * inv(K2) * x2
IV。 如果X1(3) * X2(3) < 0
,则设置R2 = U * W' * V'
并重新计算M
和X1
v。如果X1(3) < 0
设置T2 = -T2
六。 定义P1_E = K1 * [ I | 0 ]
P1_E = K1 * [ I | 0 ]
和P2_E = K2 * [ R2 | T2 ]
P2_E = K2 * [ R2 | T2 ]
符号'
表示在步骤iii中使用的转置和符号[.]x
。 对应于偏斜对称运算符。 在3x1向量上应用偏对称运算符e = [e_1; e_2; e_3]
e = [e_1; e_2; e_3]
e = [e_1; e_2; e_3]
结果如下(参见维基百科有关跨产品的文章 ):
[e]x = [0,-e_3,e_2; e_3,0,-e_1; -e_2,e_1,0]
最后,请注意T2
的范数始终为1,因为它是正交矩阵的列之一。 这意味着您将无法恢复两台摄像机之间的真实距离。 为此,您需要知道场景中两点之间的真实距离,并将其考虑在内以计算摄像机之间的真实距离。
- AIDL接口找不到Parcelable类的导入
- 对Eclipse的“Run on server”部署进行故障排除
- 绘制后从JPanel保存图像
- java.lang.OutOfMemoryError:PermGen space Exception
- SocketException:使用ObjectInputStream在服务器上重置连接
- Java(仅限Windows的问题):当弹出modal dialog并单击阻止的JFrame时,alwaysOnTop JFrame会落到z-order的底部
- 你如何签署Java Midlet?
- 强制AXIS客户端使用TLS
- spring-nullpointerexception-无法在无注释类中访问自动连接的带注释的服务(或dao)