VINS-Mono / VINS-FusiontriangulatePoint()函数通过三角化求解空间点坐标,代码所体现的数学描述不是很直观,查找资料,发现参考文献[1]对这个问题进行详细解释,记录笔记以备忘。

1. VINS-Mono中相关代码

void FeatureManager::triangulatePoint(Eigen::Matrix<double, 3, 4> &Pose0, Eigen::Matrix<double, 3, 4> &Pose1,
Eigen::Vector2d &point0, Eigen::Vector2d &point1, Eigen::Vector3d &point_3d)
{
Eigen::Matrix4d design_matrix = Eigen::Matrix4d::Zero();
design_matrix.row(0) = point0[0] * Pose0.row(2) - Pose0.row(0);
design_matrix.row(1) = point0[1] * Pose0.row(2) - Pose0.row(1);
design_matrix.row(2) = point1[0] * Pose1.row(2) - Pose1.row(0);
design_matrix.row(3) = point1[1] * Pose1.row(2) - Pose1.row(1);
Eigen::Vector4d triangulated_point;
triangulated_point =
design_matrix.jacobiSvd(Eigen::ComputeFullV).matrixV().rightCols<1>();
point_3d(0) = triangulated_point(0) / triangulated_point(3);
point_3d(1) = triangulated_point(1) / triangulated_point(3);
point_3d(2) = triangulated_point(2) / triangulated_point(3);
}

2. 数学推导

先介绍一个重要的向量叉乘向矩阵运算转换的性质[4],

\[\mathbf{a \times b = \hat{a}b}=\begin{bmatrix}0 &-a_3 &a_2 \\ a_3 &0 &-a_1 \\ -a_2 &a_1 &0\end{bmatrix}\begin{bmatrix}b_1\\b_2 \\b_3\end{bmatrix}
\tag{2-1}
\]

其中,\(\mathbf{\hat{a}}\)表示向量\(\mathbf{a}\)对应的反对称矩阵(skew-symmetric matrix)。

对于,\(X\)为三维空间点在世界坐标系下的齐次坐标\(X=\begin{bmatrix}x\\y\\z\\1\end{bmatrix}\),和 \(T=\begin{bmatrix}\mathbf{r_1} \\ \mathbf{r_2} \\ \mathbf{r_3}\end{bmatrix}=\begin{bmatrix}R &\mathbf{t}\end{bmatrix}\)为世界坐标系到相机坐标系的变换。和 \(\mathbf{x}=\begin{bmatrix}u\\v\\1\end{bmatrix}\)为归一化平面坐标,\(\lambda\)为深度值,有:

\[\lambda \mathbf{x} = TX \\
\Rightarrow \lambda\mathbf{x}\times TX=0 \\
\Rightarrow \mathbf{\hat{x}}TX=0 \\
\tag{2-2}
\]

借助式(2-1)展开,有:

\[\begin{align}
\mathbf{\hat{x}}TX &= \begin{bmatrix}0 &-1 &v \\ 1 &0 &-u \\ -v &u &0\end{bmatrix} \begin{bmatrix}\mathbf{r_1} \\ \mathbf{r_2} \\ \mathbf{r_3}\end{bmatrix}X\\
&=\begin{bmatrix}-\mathbf{r_2}+v\mathbf{r_3} \\ \mathbf{r_1}-u\mathbf{r_3} \\ -v\mathbf{r_1} + u\mathbf{r_2}\end{bmatrix}X\\
\tag{2-3}
\end{align}
\]

其中\(\begin{bmatrix}-\mathbf{r_2}+v\mathbf{r_3} \\ \mathbf{r_1}-u\mathbf{r_3} \\ -v\mathbf{r_1} + u\mathbf{r_2}\end{bmatrix}\),第一行\(\times -u\),第二行\(\times -v\),再相加,即可得到第三行,因此,其线性相关,保留前两行即可,有

\[\begin{bmatrix}-\mathbf{r_2}+v\mathbf{r_3} \\ \mathbf{r_1}-u\mathbf{r_3} \end{bmatrix}X=0
\tag{2-4}
\]

因此,已知一个归一化平面坐标\(\mathbf{x}\)和变换\(T_{cw}\),可以构建两个关于\(X\)的线性方程组。有两个以上的图像观测,即可求出\(X\)

\[\begin{bmatrix}-\mathbf{r_2}^{(1)}+v^{(1)}\mathbf{r_3}^{(1)} \\ \mathbf{r_1}^{(1)}-u^{(1)}\mathbf{r_3}^{(1)} \\ -\mathbf{r_2}^{(2)}+v^{(2)}\mathbf{r_3}^{(2)} \\ \mathbf{r_1}^{(2)}-u^{(2)}\mathbf{r_3}^{(2)} \\ \vdots\end{bmatrix}X=0
\tag{2-5}
\]

上述方程没有非零解,使用SVD求最小二乘解,解可能不满足齐次坐标形式(第四个元素为1),因此,

\[X = \begin{bmatrix}x\\y\\z\\1\end{bmatrix} = \begin{bmatrix}x_0/x_3\\x_1/x_3\\x_2/x_3\\x_3/x_3\end{bmatrix}
\tag{2-6}
\]

求得空间点坐标,但是这个解几何意义不明确[1],属于代数最小误差解。不等价于最小重投影误差,也不是最小化3D点距离误差。详细解释参考[1]中PPT。

3. 扩展

在VINS-Mono中给出了归一化平面坐标\(\mathbf{x}=\begin{bmatrix}u\\v\\1\end{bmatrix}\),如果只是给出像素坐标\(\mathbf{x'}=\begin{bmatrix}u'\\v'\\1\end{bmatrix}\),并且已知相机内参\(K\),求解3D点坐标方式类似。

\[\begin{align}
&\space\lambda\mathbf{x}' = KTX \\
\Rightarrow &\space\lambda\mathbf{x}'\times KTX=0 \\
\Rightarrow &\space\mathbf{\hat{x}'}KTX=0 \\
\Rightarrow &\space\mathbf{\hat{x}'}PX=0 \\
\tag{3-1}
\end{align}
\]

其中,$\mathbf{\hat{x}'}PX=0 $的形式与式(2-3)的形式一致,同理可以得到式(2-4)的方程。

4. 总结

在多视几何的公式推导中,多次使用"共线向量叉乘等于0"的性质,将等式的某一项置为0,式(2-2)中应用了该性质,在本质矩阵推导中,也应用了该性质,如本质矩阵的前两步推导:

\[\begin{align}
X_2 &= RX_1 + T \\
\hat{T}X_2 &= \hat{T}RX_1+\hat{T}T \\
\tag{4-1}
\end{align}
\]

在多视几何公式推导中,另一个常用的性质是"互相垂直的两个向量点乘为零",在此不再展开。

参考文献

[1] Lecture 7.2 Triangulation https://www.uio.no/studier/emner/matnat/its/UNIK4690/v16/forelesninger/lecture_7_2-triangulation.pdf

多视几何——三角化求解3D空间点坐标的更多相关文章

  1. 三角化---深度滤波器---单目稠密重建(高翔slam---十三讲)

    一.三角化 [1]三角化得到空间点的三维信息(深度值) (1)三角化的提出 三角化最早由高斯提出,并应用于测量学中.简单来讲就是:在不同的位置观测同一个三维点P(x, y, z),已知在不同位置处观察 ...

  2. 用canvas 实现个图片三角化(LOW POLY)效果

    之前无意中看到Ovilia 用threejs做了个LOW POLY,也就是图片平面三角化的效果,觉得很惊艳,然后就自己花了点时间尝试了一下. 我是没怎么用过threejs,所以就直接用canvas的2 ...

  3. 文本主题模型之LDA(三) LDA求解之变分推断EM算法

    文本主题模型之LDA(一) LDA基础 文本主题模型之LDA(二) LDA求解之Gibbs采样算法 文本主题模型之LDA(三) LDA求解之变分推断EM算法 本文是LDA主题模型的第三篇,读这一篇之前 ...

  4. [CGAL]带岛多边形三角化

    CGAL带岛多边形三角化,并输出(*.ply)格式的模型 模型输出的关键是节点和索引 #include <CGAL/Triangulation_vertex_base_with_id_2.h&g ...

  5. Schur 三角化定理的推论

    将学习到什么 从 Schur 的酉三角化定理可以收获一批结果,在这一部分介绍重要的几个.   迹与行列式 相似矩阵具有相同的特征多项式, 从特征多项式一节中, 我们又知道,相似矩阵的迹以及行列式都是相 ...

  6. PCL贪婪投影三角化算法

    贪婪投影三角化算法是一种对原始点云进行快速三角化的算法,该算法假设曲面光滑,点云密度变化均匀,不能在三角化的同时对曲面进行平滑和孔洞修复. 方法: (1)将三维点通过法线投影到某一平面 (2)对投影得 ...

  7. Unity3D之空间转换学习笔记(三):3D数学

    3D数学基础 向量 向量可以看做具有方向和大小的一条线段. 比如:我们如果用点A减去点B,则可以得到一个向量,该向量的方向为点B面向点A的方向,而大小为两点的距离.这个方法在游戏开发中经常用到,比如我 ...

  8. 最近公共祖先(LCA)的三种求解方法

    转载来自:https://blog.andrewei.info/2015/10/08/e6-9c-80-e8-bf-91-e5-85-ac-e5-85-b1-e7-a5-96-e5-85-88lca- ...

  9. 几何 三垂模型 及 正方形 及 弦图 及 jio拉jio模型 及 中位线

    Q:$AO\bot OB,AO=OB,CO\bot OD,CO=OD,BC\bot EF$ 求证 $E$ 为 $AD$ 中点 A:作如图 $AI\bot IH\bot HD$ $\because AO ...

随机推荐

  1. 【备忘:待完善】nsq集群初体验

    本机的一个节点及监控与管理后台 虚拟机中的一个节点 命令: [root@vm-vagrant nsq]# nsqd --lookupd-tcp-address=192.168.23.150:4160 ...

  2. couchdb的使用例子

    couchdb安装 sudo apt-get install erlang sudo apt-get install libmozjs185-dev libicu-dev 下载源码,编译安装 启动以后 ...

  3. ASP.NET Redis 开发 入门

    ASP.NET Redis 开发   文件并发(日志处理)--队列--Redis+Log4Net Redis简介 Redis是一个开源的,使用C语言编写,面向“键/值”对类型数据的分布式NoSQL数据 ...

  4. 编写hibernateDao,使dao层都实现hibernateDao

    package com.wiseweb.core.dao; import java.io.Serializable; import java.util.ArrayList; import java.u ...

  5. C++类够做函数初始化列表

    构造函数初始化列表以一个冒号开始,接着是以逗号分隔的数据成员列表,每个数据成员后面跟一个放在括号中的初始化式.例如: class CExample{ public: int a; float b; C ...

  6. Collection集合学习(一)———Set接口与具体实现

    接口Collection: Collection是Java的一个集合框架, 也是一个根接口.JDK中没有提供此接口的任何实现,但是提供了更具体的子接口Set和List接口的实现,所有的Collecti ...

  7. Java中RMI远程调用demo

    Java远程方法调用,即Java RMI(Java Remote Method Invocation),一种用于实现远程过程调用的应用程序编程接口.它使客户机上运行的程序可以调用远程服务器上的对象.远 ...

  8. CCNode作为容器实现显示区域剪裁

    一直把ccnode当做ui元素的容器使用,比如一段带下划线的文字,我会在一个ccnode中加入一个label和一个sprite,然后作为一个整体传出. 在主界面聊天的时候遇到一个问题,一段聊天信息需要 ...

  9. day9-IO心得

    Gevent协程 Select\Poll\Epoll异步IO与事件驱动 Python连接Mysql数据库操作 RabbitMQ队列 Redis\Memcached缓存 Paramiko SSH Tws ...

  10. [转] 实现winfrom进度条及进度信息提示,winfrom程序假死处理

    china_xuhua 原文地址 1.方法一:使用线程 功能描述:在用c#做WinFrom开发的过程中.我们经常需要用到进度条(ProgressBar)用于显示进度信息.这时候我们可能就需要用到多线 ...