DSM: Direct Sparse Mapping

Direct Sparse Mapping (DSM) 是一种计算机视觉算法,用于实时三维重建。它通过Local Map Covisibility Window (LMCW) 和Robust Non-Linear PBA来处理外点和确保里程计精度。DSM的关键特性包括时间窗口策略以优化新点,共视窗口策略以选择关键帧,并使用Student t分布进行外点剔除。此外,DSM的前端处理涉及关键帧选择和新地图点跟踪,确保了在各种场景下的稳健性能。

Direct Sparse Mapping

Introduction

  • 滑窗的会边缘化掉离开视场的点,同时来保证可观性的一致,不能重用边缘化的地图点
  • 特征点法一般根据共视关系选固定位置的激活关键帧和地图点,通过固定一帧的策略保证可观性
  • 选择以前的关键帧,结合时间和共视关系来选择激活的关键帧
  • 时间上远的帧会受drift影响,因此使用多尺度优化,来增加收敛半径
  • 由于距离远伪观测(外点)会增加,使用t分布来更鲁棒地处理

DSO和LDSO的缺点:

  • 使用了不同的目标函数和点类型来完成里程计估计
  • 闭环检测依赖于特征点的可重复性,损失一些可以用来矫正的点
  • 闭环的误差较正均匀分布在关键帧上,这可能不是最优解
  • 地图点的信息没有被reuse

[外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传(img-Ppictdrc-1584384772308)(img/DSM/image-20191210100455354.png)]

Direct Mapping

  • 跟踪线程以帧率速度输出位姿,会判断是否加入关键帧
  • 建图线程处理新的帧,来跟踪关键帧上的点(候选点逆深度更新),插入关键帧会重新计算local window,激活新的点,优化motion和structure。然后为了保证全局一致,移除外点,检测遮挡,避免点的重复。

使用固定其它帧的方式来保证不可观自由度的一致性。

LMCW的初始解不在收敛半径内,所以使用粗到精的方式来优化,估计的几何作为下一层的初始值。

LMCW: Local Map Covisibility Window

由时间和共视策略组成,都是相对于最新关键帧的。

[外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传(img-AOI2c7Q0-1584384772309)(img/Untitled/image-20191209220758429.png)]

时间窗口主要目的是来优化新的点(初始化新点),并且保证里程计精度。

固定时间窗口的大小,从时间窗口移除关键帧的策略:

  • 总是保留上两个关键帧(I1I_1I1I2I_2I2),这保证里程计在挑战环境下(如大旋转)也能保证精度。避免关键帧过早的固定,保证被充分优化。
  • 其他的关键帧要均匀分布在空间中,丢弃有最大距离的,使得视差最大:

s(Ii)=d(I1,Ii)∑j=3Nt(d(Ii,Ij))−1(1) s\left(I_{i}\right)=\sqrt{d\left(I_{1}, I_{i}\right)}\sum_{j=3}^{N_{t}}\left(d\left(I_{i}, I_{j}\right)\right)^{-1} \tag{1} s(Ii)=d(I1,Ii) j=3Nt(d(Ii,Ij))1(1)

共视窗口是和时间窗口有共视关系的关键帧,要找到那些在最新关键帧空白区域有地图点投影的关键帧,具体的策略:

  • 计算距离地图来确定耗尽区域,将时间窗口投影到最新关键帧,计算每个像素到最近地图点的距离。
  • 选择具有最大数目投影点的旧关键帧,会剔除大于一定视角的点,来防止遮挡等情况。
  • 更新距离地图
  • 迭代执行第二步,直到选出足够数目,或者没有关键帧。

激活新地图点前,共视点已经完成投影,避免了提取重复的地图点,保证地图的一致性。

Robust Non-Linear PBA

LMCW的关键帧选取范围广,忽略了实际光度的不一致性,比如由于遮挡,光反射等

提出根据光度误差的分布来剔除外点:
ξ∗=argmin⁡ξ−∑knlog⁡p(rk∣ξ)(2) \xi^{*}=\underset{\xi}{\operatorname{argmin}}-\sum_{k}^{n} \log p\left(r_{k} | \boldsymbol{\xi}\right)\tag{2} ξ=ξarg

### 使用 Eigen 库中的 SparseMatrix 类 #### 创建和初始化稀疏矩阵对象 为了创建一个 `SparseMatrix` 对象,可以指定其维度以及动态分配的空间大小。通常建议预先估计非零元素的数量以优化性能。 ```cpp #include <Eigen/Sparse> // 定义一个双精度浮点数类型的稀疏矩阵, 行优先存储方式 Eigen::SparseMatrix<double> m(rows, cols); m.reserve(Eigen::VectorXi::Constant(cols, 8)); // 预留每列大约有8个非零项 ``` #### 插入非零元素到稀疏矩阵中 通过调用 `.insert()` 方法可以在特定位置插入新的非零条目;如果该位置已经存在,则会更新现有值。注意,在完成所有插入之前不应访问矩阵数据结构。 ```cpp for(int k = 0; k < num_entries; ++k){ int i = row_indices[k]; int j = col_indices[k]; double v = values[k]; // 如果(i,j)处还没有设置过数值则插入新值v m.insert(i, j) = v; } ``` #### 执行基本线性代数运算 一旦构建好稀疏矩阵之后就可以像对待常规密集型矩阵那样执行各种算术计算了。例如求解线性方程组 Ax=b: ```cpp // 构建系数矩阵A (假设已知) Eigen::SparseMatrix<double> A; // 设置右侧向量b Eigen::VectorXd b(n); // 解决Ax=b问题得到x Eigen::SimplicialLLT<Eigen::SparseMatrix<double>> solver(A); Eigen::VectorXd x = solver.solve(b); ``` 对于稠密矩阵,类 `Map<SparseMatrixType>` 可用于将外部缓冲区视为 Eigen 的 SparseMatrix 对象[^1]。这允许更灵活的数据交换机制而无需复制整个数组内容。 在许多应用场景下(比如有限元分析),经常会遇到规模巨大但大部分区域都接近于零的大尺寸矩阵。这时采用专门设计用来保存少量有效成分的形式——即所谓的“稀疏矩阵”,能够显著降低资源占用并加快算法效率[^3]。
评论 3
成就一亿技术人!
拼手气红包6.0元
还能输入1000个字符
 
红包 添加红包
表情包 插入表情
 条评论被折叠 查看
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值