多视几何——三角化求解3D空间点坐标
VINS-Mono / VINS-Fusion中triangulatePoint()函数通过三角化求解空间点坐标,代码所体现的数学描述不是很直观,查找资料,发现参考文献[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],
\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\)为深度值,有:
\Rightarrow \lambda\mathbf{x}\times TX=0 \\
\Rightarrow \mathbf{\hat{x}}TX=0 \\
\tag{2-2}
\]
借助式(2-1)展开,有:
\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\),再相加,即可得到第三行,因此,其线性相关,保留前两行即可,有
\tag{2-4}
\]
因此,已知一个归一化平面坐标\(\mathbf{x}\)和变换\(T_{cw}\),可以构建两个关于\(X\)的线性方程组。有两个以上的图像观测,即可求出\(X\)
\tag{2-5}
\]
上述方程没有非零解,使用SVD求最小二乘解,解可能不满足齐次坐标形式(第四个元素为1),因此,
\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点坐标方式类似。
&\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)中应用了该性质,在本质矩阵推导中,也应用了该性质,如本质矩阵的前两步推导:
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空间点坐标的更多相关文章
- 三角化---深度滤波器---单目稠密重建(高翔slam---十三讲)
一.三角化 [1]三角化得到空间点的三维信息(深度值) (1)三角化的提出 三角化最早由高斯提出,并应用于测量学中.简单来讲就是:在不同的位置观测同一个三维点P(x, y, z),已知在不同位置处观察 ...
- 用canvas 实现个图片三角化(LOW POLY)效果
之前无意中看到Ovilia 用threejs做了个LOW POLY,也就是图片平面三角化的效果,觉得很惊艳,然后就自己花了点时间尝试了一下. 我是没怎么用过threejs,所以就直接用canvas的2 ...
- 文本主题模型之LDA(三) LDA求解之变分推断EM算法
文本主题模型之LDA(一) LDA基础 文本主题模型之LDA(二) LDA求解之Gibbs采样算法 文本主题模型之LDA(三) LDA求解之变分推断EM算法 本文是LDA主题模型的第三篇,读这一篇之前 ...
- [CGAL]带岛多边形三角化
CGAL带岛多边形三角化,并输出(*.ply)格式的模型 模型输出的关键是节点和索引 #include <CGAL/Triangulation_vertex_base_with_id_2.h&g ...
- Schur 三角化定理的推论
将学习到什么 从 Schur 的酉三角化定理可以收获一批结果,在这一部分介绍重要的几个. 迹与行列式 相似矩阵具有相同的特征多项式, 从特征多项式一节中, 我们又知道,相似矩阵的迹以及行列式都是相 ...
- PCL贪婪投影三角化算法
贪婪投影三角化算法是一种对原始点云进行快速三角化的算法,该算法假设曲面光滑,点云密度变化均匀,不能在三角化的同时对曲面进行平滑和孔洞修复. 方法: (1)将三维点通过法线投影到某一平面 (2)对投影得 ...
- Unity3D之空间转换学习笔记(三):3D数学
3D数学基础 向量 向量可以看做具有方向和大小的一条线段. 比如:我们如果用点A减去点B,则可以得到一个向量,该向量的方向为点B面向点A的方向,而大小为两点的距离.这个方法在游戏开发中经常用到,比如我 ...
- 最近公共祖先(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- ...
- 几何 三垂模型 及 正方形 及 弦图 及 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 ...
随机推荐
- Openfire源码使用Install4j打包
https://www.ej-technologies.com/download/install4j/files 下载并安装install4jhttps://www.ej-technologies.c ...
- 从内存的角度观察 堆、栈、全局区(静态区)(static)、文字常量区、程序代码区
之前写了一篇堆栈的,这里再补充下内存其他的区域 1.栈区(stack)— 由编译器自动分配释放 ,存放函数的参数值,局部变量的值等.其操作方式类似于数据结构中的栈. 2.堆区(heap) — 一般由程 ...
- 18.9.10 LeetCode刷题笔记
本人算法还是比较菜的,因此大部分在刷基础题,高手勿喷 选择Python进行刷题,因为坑少,所以不太想用CPP: 1.买股票的最佳时期2 给定一个数组,它的第 i 个元素是一支给定股票第 i 天的价格. ...
- Unit01: JDBC原理 、 JDBC基础编程
Unit01: JDBC原理 . JDBC基础编程 这个文件里面有两块内容: 1.用比较麻烦的方式连接数据库,test1(),test4() 2.创建DBTool,测试DBTool连接数据库 ,tes ...
- Renesas APIs ***
一个线程,强行结束另外一个线程,并将其挂起: static void SuspendTask(TX_THREAD *thread) { UINT status = ; UINT state; stat ...
- shell中date命令对month进行加减操作的bug
shell脚本中如何取上个月的月份呢?很容易能想到下面的命令: date +%Y%m -d '-1 month' 或者 date +%Y%m -d 'last month' 在大部分情况下这个命令 ...
- VB.NET实现32位、64位远线程运行ASM,注入非托管、托管DLL
这是一个老话题,远线程函数给我们提供了机会在其他进程中启动一个新线程,所以我们可以做很多事情.但事情远远没有结束,如果我们要做的事情非常复杂,那么将面临编写大量的ASM代码,虽然我们可以用VC之类的工 ...
- Management
using System; using System.Collections.Generic; using System.Linq; using System.Text; using System.T ...
- struts2学习(7)值栈简介与OGNL引入
一.值栈简介: 二.OGNL引入: com.cy.action.HelloAction.java: package com.cy.action; import java.util.Map; impor ...
- Java 代码块
一.简介 1.普通代码块: 类中方法的方法体 2.构造代码块: 构造块会在创建对象时被调用,每次创建时都会被调用,优先于类构造函数执行. 3.静态代码块: 用static{}包裹起来的代码片段,只会执 ...