DSO windowed optimization 代码 (2)
3 非 Schur Complement 部分信息计算
参考《DSO windowed optimization 公式》,非Schur Complement 部分指 \(H_{XX}\) 和 \(J^T_{X}r\)。
3.1 AccumulatedTopHessianSSE::addPoint()优化的局部信息计算
EnergyFunctional::accumulateAF_MT() 与 EnergyFunctional::accumulateLF_MT() 遍历每一个点,对每一个点调用 AccumulatedTopHessianSSE::addPoint()。在 AccumulatedTopHessianSSE::addPoint() 中遍历点的每一个 residual。计算所有优化系统的信息,存储在每个点的局部变量和 EnergyFunctional 的局部变量中。
3.1.1 resApprox
首先搞定resApprox。由 VecNRf 可知,这东西是 8x1 的矩阵(也就是每个 residual 都是八个像素点的组合)。
VecNRf resApprox;
if(mode==0) // active
resApprox = rJ->resF;
if(mode==2) // marginalize
resApprox = r->res_toZeroF;
if(mode==1) // linearized
{
// compute Jp*delta
__m128 Jp_delta_x = _mm_set1_ps(rJ->Jpdxi[0].dot(dp.head<6>())+rJ->Jpdc[0].dot(dc)+rJ->Jpdd[0]*dd);
__m128 Jp_delta_y = _mm_set1_ps(rJ->Jpdxi[1].dot(dp.head<6>())+rJ->Jpdc[1].dot(dc)+rJ->Jpdd[1]*dd);
__m128 delta_a = _mm_set1_ps((float)(dp[6]));
__m128 delta_b = _mm_set1_ps((float)(dp[7]));
for(int i=0;i<patternNum;i+=4)
{
// PATTERN: rtz = resF - [JI*Jp Ja]*delta.
__m128 rtz = _mm_load_ps(((float*)&r->res_toZeroF)+i);
rtz = _mm_add_ps(rtz,_mm_mul_ps(_mm_load_ps(((float*)(rJ->JIdx))+i),Jp_delta_x));
rtz = _mm_add_ps(rtz,_mm_mul_ps(_mm_load_ps(((float*)(rJ->JIdx+1))+i),Jp_delta_y));
rtz = _mm_add_ps(rtz,_mm_mul_ps(_mm_load_ps(((float*)(rJ->JabF))+i),delta_a));
rtz = _mm_add_ps(rtz,_mm_mul_ps(_mm_load_ps(((float*)(rJ->JabF+1))+i),delta_b));
_mm_store_ps(((float*)&resApprox)+i, rtz);
}
}
Residual 有三种情况:
- active 情况最简单,直接是 residual。
- marginalize 的情况比较复杂,res_toZeroF 在EFResidual::fixLinearizationF()赋值,而 res_toZeroF 与下面计算的 rtz 是类似的。
- linearized 在这里已经给出了其赋值的方法,下面会说到,linearized residual 是不存在的。
所谓的 linearied residual 是指 EFResidual::isActive() 与 EFResidual::isLinearized 都为 true 的 Residual。初始阶段 isLinearized 为 false,只要搞清楚 isLinearized 在什么时候设置为 true 就可以了解到 linearized residual 是何种意思。查找了 EFResidual::isLinearized 只在 EFResidual::fixLinearizationF 中设置为 true,而 EFResidual::fixLinearizationF() 仅仅只在 FullSystem::flagPointsForRemoval() 中调用。在此处,将那些符合 2 种情况(1. 因为 residual 太少造成了 Out Of Boundary(这里考虑到将要被 marginalize 掉的帧的影响),2. 主帧要被 marginalize 掉)的点的 residual 设置为 linearized。但是这些点紧接着又会在 EnergyFunctional::marginalizePointsF() 中被 marg 掉,被删除掉。最终也没有进入 FullSystem::optimize() 的优化过程中。我在 AccumulatedTopHessianSSE::addPoint() 的这个位置设置了 conditional breakpoint (mode==1),或者assert(mode!=1),实验证明 linearized residual 是不存在的。
active residual 时,
resApprox对应的就是简单的 \(r_{21}\)。linearized residual 时,还要看这个代码是什么意思。
\(\begin{bmatrix} \text{Jp_delta_x} \\ \text{Jp_delta_y} \end{bmatrix} = {\partial x_2 \over \partial \xi_1}{\delta \xi_1} + {\partial x_2 \over \partial \xi_2}{\delta \xi_2} + {\partial x_2 \over \partial C}{\delta C} + {\partial x_2 \over \partial \rho_1}{\delta \rho_1}\)
\(\begin{bmatrix} \text{delta_a} \\ \text{delta_b}\end{bmatrix} = {\partial l_{21} \over \partial l_1}{\delta l_1} + {\partial l_{21} \over \partial l_2}{\delta l_2}\)
\(\text{rtz} = {\partial r_{21} \over \partial \xi_1}{\delta \xi_1} + {\partial r_{21} \over \partial \xi_2}{\delta \xi_2} + {\partial r_{21} \over \partial C}{\delta C} + {\partial r_{21} \over \partial \rho_1}{\delta \rho_1} + {\partial r_{21} \over \partial l_1}{\delta l_1} + {\partial r_{21} \over \partial l_2}{\delta l_2}\)
res_toZeroF与rtz相同。resApprox = res_toZeroF + rtz。
3.1.2 acc
在 AccumulatedTopHessianSSE::addPoint() 函数计算了 Hessian 矩阵。而这里的 Hessian 矩阵是存储了两个帧之间的相互信息,所有的信息存储在 AccumulatedTopHessianSSE::acc 中,acc是一个数组,大小是 8*8 个,位置 (i, j) 上对应的是 i 帧与 j 帧的相互信息。
AccumulatorApprox 也就是AccumulatedTopHessianSSE::acc 变量的“基础”类型。这个类型对应着 13x13 的矩阵。这个矩阵经过阅读代码,可以知道存储的是以下信息。
\]
\]
\]
&= \begin{bmatrix} {\partial r_{21} \over \partial C}^T_{4\times8} \\ {\partial r_{21} \over \partial \xi_{21}}^T_{6\times8} \\ {\partial r_{21} \over \partial l_{21}}^T_{2\times8} \\ {r_{21}}^T_{1\times8} \end{bmatrix} \begin{bmatrix} {\partial r_{21} \over \partial C}_{8\times4} & {\partial r_{21} \over \partial \xi_{21}}_{8\times6} & {\partial r_{21} \over \partial l_{21}}_{8\times2} & {r_{21}}_{8\times1}\end{bmatrix} \notag \\
&= \begin{bmatrix} {{\partial r_{21} \over \partial C}^T{\partial r_{21} \over \partial C}}_{4\times4} & {{\partial r_{21} \over \partial C}^T{\partial r_{21} \over \partial \xi_{21}}}_{4\times6} & {{\partial r_{21} \over \partial C}^T{\partial r_{21} \over \partial l_{21}}}_{4\times2} & {{\partial r_{21} \over \partial C}^T{r_{21}}}_{4\times1} \\ {{\partial r_{21} \over \partial \xi_{21}}^T{\partial r_{21} \over \partial C}}_{6\times4} & {{\partial r_{21} \over \partial \xi_{21}}^T{\partial r_{21} \over \partial \xi_{21}}}_{6\times6} & {{\partial r_{21} \over \partial \xi_{21}}^T{\partial r_{21} \over \partial l_{21}}}_{6\times2} & {{\partial r_{21} \over \partial \xi_{21}}^T{r_{21}}}_{6\times1} \\ {{\partial r_{21} \over \partial l_{21}}^T{\partial r_{21} \over \partial C}}_{2\times4} & {{\partial r_{21} \over \partial l_{21}}^T{\partial r_{21} \over \partial \xi_{21}}}_{2\times6} & {{\partial r_{21} \over \partial l_{21}}^T{\partial r_{21} \over \partial l_{21}}}_{2\times2} & {{\partial r_{21} \over \partial l_{21}}^T{r_{21}}}_{2\times1} \\ {{r_{21}}^T{\partial r_{21} \over \partial C}}_{1\times4} & {{r_{21}}^T{\partial r_{21} \over \partial \xi_{21}}}_{1\times6} & {{r_{21}}^T{\partial r_{21} \over \partial l_{21}}}_{1\times2} & {{r_{21}}^T{r_{21}}}_{1\times1} \end{bmatrix} \notag \end{align}\]
代码中的BotRight对应矩阵右下角 3x3 的分块:
\]
TopRight对应矩阵右上角 10x3 的分块:
\]
Data对应左上角 10x10 的分块:
\]
这个 AccumulatorApprox 中存储的 13x13 矩阵并不是优化过程中整体的大矩阵,只是对应着窗口中两帧之间的相互信息。注意到代码中计算调用acc变量时是这么调用的acc[tid][htIDX],int htIDX = r->hostIDX + r->targetIDX * nframes[tid];,不考虑tid线程编号,acc共有8*8=64个。
继续讲完 AccumulatedTopHessianSSE::addPoint 函数。
函数的目标除了计算不同帧之间的相互信息(变量acc),还需要计算每一个点对于所有 residual 的信息和。即EFPoint中的成员变量Hdd_accAF, bd_accAF, Hcd_accAF, Hdd_accLF, bd_accLF, Hcd_accLF,如果这个点是 active 点,那么设置AF相关的变量,否则设置LF相关变量,如果是 marginalize 点,清除AF相关变量的信息。这三个成员变量将用于计算逆深度的优化量。
局部变量Hdd_acc, bd_acc, Hcd_acc对应着这些EFPoint的成员变量,最后赋值到成员变量。
3.1.3 bd_acc, Hdd_acc, Hcd_acc
JI_r[0] += resApprox[i] *rJ->JIdx[0][i];
JI_r[1] += resApprox[i] *rJ->JIdx[1][i];
...
Vec2f Ji2_Jpdd = rJ->JIdx2 * rJ->Jpdd;
bd_acc += JI_r[0]*rJ->Jpdd[0] + JI_r[1]*rJ->Jpdd[1];
Hdd_acc += Ji2_Jpdd.dot(rJ->Jpdd);
Hcd_acc += rJ->Jpdc[0]*Ji2_Jpdd[0] + rJ->Jpdc[1]*Ji2_Jpdd[1];
JI_r对应 \({\partial r_{21} \over \partial x_2}^T({\partial r_{21} \over \partial \xi_1}{\delta \xi_1} + {\partial r_{21} \over \partial \xi_2}{\delta \xi_2} + {\partial r_{21} \over \partial C}{\delta C} + {\partial r_{21} \over \partial \rho_1}{\delta \rho_1} + {\partial r_{21} \over \partial l_1}{\delta l_1} + {\partial r_{21} \over \partial l_2}{\delta l_2})\),2x1。
Ji2_Jpdd对应 \({\partial r_{21} \over \partial x_2}^T{\partial r_{21} \over \partial \rho_1}\),2x1。
bd_acc对应(1)active 时,\({\partial r_{21} \over \partial \rho_1}^Tr_{21}\);(2)marginalize 时,\({\partial r_{21} \over \partial \rho_1}^T({\partial r_{21} \over \partial \xi_1}{\delta \xi_1} + {\partial r_{21} \over \partial \xi_2}{\delta \xi_2} + {\partial r_{21} \over \partial C}{\delta C} + {\partial r_{21} \over \partial \rho_1}{\delta \rho_1} + {\partial r_{21} \over \partial l_1}{\delta l_1} + {\partial r_{21} \over \partial l_2}{\delta l_2})\)。1x1。
Hdd_acc对应 \({\partial r_{21} \over \partial \rho_1}^T{\partial r_{21} \over \partial \rho_1}\),1x1。
Hcd_acc对应 \({\partial r_{21} \over \partial C}^T{\partial r_{21} \over \partial \rho_1}\),4x1。
3.2 AccumulatedTopHessianSSE::stitchDoubleInternal()优化信息统计
循环for(int k=min;k<max;k++)循环是遍历所有可能的 (host_frame,target_frame) 组合。
内层循环累积计算accH就不用看了,这个循环是用于累加多个线程的结果,accH就是acc[h+nframes*t],参照 3.1。
下面的H(对应 \(H_{XX}\))和b(对应 \(J^T_{X}r\))的累加,使用了 EnergyFunctional::adHost 和 EnergyFunctional::adTarget。这是因为前面计算的 Jacobian 都是对相对状态的偏导,这两个变量存储的是相对状态对绝对状态的偏导。
adHost[h+nframes*t]下标是 (t,h),对应公式 \({\partial X_R^{(th)} \over \partial X_R^{(h)}}^T\)。
adTarget[h+nframes*t]下标是 (t,h),对应公式 \({\partial X_R^{(th)} \over \partial X_R^{(t)}}^T\)。
\(X_R^{(i)}\) 是 i 帧的所有状态,包括 se(3) 和 AffLight 参数,即 \(\begin{bmatrix} \xi_i \\ l_i \end{bmatrix}\)。
DSO windowed optimization 代码 (2)的更多相关文章
- DSO windowed optimization 代码 (4)
5 "step"计算 参考<DSO windowed optimization 公式>,计算各个优化变量的增加量. 公式再写一下: \[\begin{align} \b ...
- DSO windowed optimization 代码 (3)
4 Schur Complement 部分信息计算 参考<DSO windowed optimization 公式>,Schur Complement 部分指 Hsc(\(H_{X\rho ...
- DSO windowed optimization 代码 (1)
这里不想解释怎么 marginalize,什么是 First-Estimates Jacobian (FEJ).这里只看看代码,看看Hessian矩阵是怎么构造出来的. 1 优化流程 整个优化过程,也 ...
- DSO windowed optimization 公式
这里有一个细节,我想了很久才想明白,DSO 中的 residual 联系了两个关键帧之间的相对位姿,但是最终需要优化帧的绝对位姿,中间的导数怎么转换?这里使用的是李群.李代数中的Adjoint. 参考 ...
- Adjoint of SE(3)
以前看的书都提到 SE(3) 和 se(3) 的 Adjoint,但是并没有讲这个东西是干什么用的,只是给了一堆性质.这东西来自群论. 参考 Lie Groups for 2D and 3D Tran ...
- Paper Reading: Stereo DSO
开篇第一篇就写一个paper reading吧,用markdown+vim写东西切换中英文挺麻烦的,有些就偷懒都用英文写了. Stereo DSO: Large-Scale Direct Sparse ...
- Omnidirectional DSO: Direct Sparse Odometry with Fisheye Cameras 论文摘要
1. Abstract 通过一种Unified Omnidirectional Model作为投影方程. 这种方式可以使用图像的所有内容包括有强畸变的区域,而现存的视觉里程计方案只能修正或者切掉来使用 ...
- OD: GS Bypasing via SEH / .data
通过 SEH 绕过 GS 保护 GS 机制没对 SEH 提供保护,所以可心通过攻击异常来绕过 GS. 实验环境为: VMware : Windows sp4, 此版本无 SafeSEH 的影响 Vis ...
- [翻译] JFDepthView 给view提供3D景深
JFDepthView 给view提供3D景深 https://github.com/atljeremy/JFDepthView This is an iOS project for presenti ...
随机推荐
- BZOJ4998星球联盟——LCT+并查集(LCT动态维护边双连通分量)
题目描述 在遥远的S星系中一共有N个星球,编号为1…N.其中的一些星球决定组成联盟,以方便相互间的交流.但是,组成 联盟的首要条件就是交通条件.初始时,在这N个星球间有M条太空隧道.每条太空隧道连接两 ...
- LOJ6387 [THUPC2018] 绿绿与串串 【manacher】
题目分析: 比较简单,先跑一边manacher,然后对于回文部分可以碰到末尾的一定满足条件,否则向后转移. 代码: #include<bits/stdc++.h> using namesp ...
- MT【235】两道函数题
已知$g(x)=x^2-ax+4a$,记$h(x)=|\dfrac{x}{g(x)}|$,若$h(x)$在$(0,1]$上单调递增,求$a$的取值范围. 解答: 已知$$g(x)=\begin{cas ...
- Intent 跳转Activity
Intent 跳转 显示跳转(用类名跳转) Intent i = new Intent(a.this,b.class); 隐士跳转 自定义Action <!--配置跳转Activity--> ...
- 对 static const char* const str[] = {“string”} 的理解
static const char* const str[] = {“string”} 静态常量型指针变量 static const char* 常量型变量 const str[] 这样修饰的作用为 ...
- Ubuntu无法进入Windows的NTFS分区
在Ubuntu进入NTFS分区出现问题,无法访问. 不能访问 新加卷 Error mounting /dev/sda8 at /media/zhuxiaoxi/新加卷: Command-line `m ...
- 洛谷P3952 时间复杂度
大毒瘤...... 时隔快半年我终于花了两个小时堪堪A掉这一题...果然我还没有准备好. 想法:用DFS模拟递归. 时间复杂度的处理:每层循环取max,然后相加. 最大难点:各种繁杂而令人发指的特判. ...
- 【UVA10140】Prime Distance
题目大意:求出一个给定区间 [l, r] 内相邻素数之间的最大距离和最小距离. 题解:由于 l, r 的范围太大,没法直接用筛法得出区间的素数.考虑筛出区间的素数等价于筛掉区间内的所有和数, 根据算术 ...
- 百度地图手机端单触点单击和长按事件,解决部分手机(小米手机)地图单击事件失效,多触点、拖动依然触发长按的bug
/** * Author 岳晓 * * 对百度地图的事件扩展,目前扩展了fastclick和longclick, * 解决某些设备click不执行的问题 * 解决长按事件在拖动.多触点依然执行的bug ...
- react性能检测与优化
网页运行最重要的是速度快嘛,那我们怎么知道网页运行的时候,哪些部分快哪些部分慢呢? 我们可以安装react性能检测工具进行检测,通过安装 然后修改app/index.jsx文件 ,在要检测的组件运行之 ...