多视几何——三角化求解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 ...
随机推荐
- 【备忘:待完善】nsq集群初体验
本机的一个节点及监控与管理后台 虚拟机中的一个节点 命令: [root@vm-vagrant nsq]# nsqd --lookupd-tcp-address=192.168.23.150:4160 ...
- couchdb的使用例子
couchdb安装 sudo apt-get install erlang sudo apt-get install libmozjs185-dev libicu-dev 下载源码,编译安装 启动以后 ...
- ASP.NET Redis 开发 入门
ASP.NET Redis 开发 文件并发(日志处理)--队列--Redis+Log4Net Redis简介 Redis是一个开源的,使用C语言编写,面向“键/值”对类型数据的分布式NoSQL数据 ...
- 编写hibernateDao,使dao层都实现hibernateDao
package com.wiseweb.core.dao; import java.io.Serializable; import java.util.ArrayList; import java.u ...
- C++类够做函数初始化列表
构造函数初始化列表以一个冒号开始,接着是以逗号分隔的数据成员列表,每个数据成员后面跟一个放在括号中的初始化式.例如: class CExample{ public: int a; float b; C ...
- Collection集合学习(一)———Set接口与具体实现
接口Collection: Collection是Java的一个集合框架, 也是一个根接口.JDK中没有提供此接口的任何实现,但是提供了更具体的子接口Set和List接口的实现,所有的Collecti ...
- Java中RMI远程调用demo
Java远程方法调用,即Java RMI(Java Remote Method Invocation),一种用于实现远程过程调用的应用程序编程接口.它使客户机上运行的程序可以调用远程服务器上的对象.远 ...
- CCNode作为容器实现显示区域剪裁
一直把ccnode当做ui元素的容器使用,比如一段带下划线的文字,我会在一个ccnode中加入一个label和一个sprite,然后作为一个整体传出. 在主界面聊天的时候遇到一个问题,一段聊天信息需要 ...
- day9-IO心得
Gevent协程 Select\Poll\Epoll异步IO与事件驱动 Python连接Mysql数据库操作 RabbitMQ队列 Redis\Memcached缓存 Paramiko SSH Tws ...
- [转] 实现winfrom进度条及进度信息提示,winfrom程序假死处理
china_xuhua 原文地址 1.方法一:使用线程 功能描述:在用c#做WinFrom开发的过程中.我们经常需要用到进度条(ProgressBar)用于显示进度信息.这时候我们可能就需要用到多线 ...