当前位置: 首页 > 面试题库 >

分解基本矩阵:验证R和T的四种可能解法

芮歌者
2023-03-14
问题内容

我想使用OpenCV做一些动态结构。到目前为止,我已经有了基本面和基本面。有了Essentialmatrix,我正在做SVD以获取R和T。

我的问题是我为R有2个可能的解决方案,为T有2个可能的解决方案,这导致整个姿势有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 = u.t
    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(p47)中解释了一种方法: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]R2 = U * W * V'T2 = third column of U

iii。定义M = [ R2'*T2 ]xX1 = M * inv(K1) * x1X2 = M * R2' * inv(K2) * x2

iv。如果X1(3) * X2(3) < 0,请设置R2 = U * W' * V'并重新计算,M然后X1

v。如果已X1(3) < 0设置T2 = -T2

vi。定义P1_E = K1 * [ I | 0 ]P2_E = K2 * [ R2 | T2 ]

符号'表示[.]x步骤iii中使用的转置和符号。对应于斜对称html" target="_blank">运算符。在3x1向量上应用偏斜对称算子e = [e_1; e_2; e_3]将产生以下结果(请参阅Wikipedia关于叉积的文章):

[e]x = [0,-e_3,e_2; e_3,0,-e_1; -e_2,e_1,0]

最后,请注意,范数T2将始终为1,因为它是正交矩阵的列之一。这意味着您将无法恢复两个摄像机之间的真实距离。为此,您需要知道场景中两个点之间的真实距离,并考虑该距离以计算摄像机之间的真实距离。



 类似资料:
  • 非负矩阵分解(non-negative matrix factorization,以下简称NMF)是一种非常常用的矩阵分解方法,它可以适用于很多领域,比如图像特征识别,语音识别等,这里我们会主要关注于它在文本主题模型里的运用。 回顾奇异值分解,它会将一个矩阵分解为三个矩阵:$$A = USigma V^T$$ 如果降维到k维,则表达式为:$$A_{m times n} approx U_{m ti

  • 在Spark MLlib中,推荐算法这块只实现了基于矩阵分解的协同过滤推荐算法。而基于的算法是FunkSVD算法,即将m个用户和n个物品对应的评分矩阵M分解为两个低维的矩阵:$$M_{m times n}=P_{m times k}^TQ_{k times n}$$ 其中k为分解成低维的维数,一般远比m和n小。如果大家对FunkSVD算法不熟悉,可以复习对应的原理篇。 2. Spark推荐算法类库

  • 校验者: @武器大师一个挑俩 @png 翻译者: @柠檬 @片刻 2.5.1. 主成分分析(PCA) 2.5.1.1. 准确的PCA和概率解释(Exact PCA and probabilistic interpretation) PCA 用于对一组连续正交分量中的多变量数据集进行方差最大方向的分解。 在 scikit-learn 中, PCA 被实现为一个变换对象, 通过 fit 方法可以降维成

  • 主要内容:语法,例子,访问矩阵的元素,矩阵计算矩阵是其中元素以二维矩形布局排列的R对象。它们包含相同原子类型的元素。 虽然我们可以创建一个仅包含字符或仅包含逻辑值的矩阵,但它们没有太多用处。 我们使用包含数学元素的矩阵来在数学计算中使用。 矩阵可通过使用函数来创建。 语法 在R中创建矩阵的基本语法是 - 以下是使用的参数的描述 - data - 是将要转为矩阵元素的输入向量。 nrow - 是要创建的行数。 ncol - 是要创建的列数。 b

  • 我对Web浏览器的基本身份验证有点困惑。我原以为Web浏览器只会在之前的响应中收到HTTP 401状态后发送授权标头。然而,似乎Chrome在之后的每个请求中都发送授权标头。它包含我曾经输入的数据,以响应我网站上的401,并与每条消息一起发送(根据Chrome和我的Web服务器附带的开发人员工具)。这是预期的行为吗?我应该在我的401中使用一些标头来推断不应该缓存授权内容吗?我目前正在使用WWW-

  • 表示为一个 4x4 matrix. 在3D计算机图形学中,4x4矩阵最常用的用法是作为一个变换矩阵Transformation Matrix。 有关WebGL中使用的变换矩阵的介绍,请参阅本教程this tutorial。 这使得表示三维空间中的一个点的向量Vector3通过乘以矩阵来进行转换,如平移、旋转、剪切、缩放、反射、正交或透视投影等。这就是把矩阵应用到向量上。 任何3D物体Object3