{\partial r_{21} \over \partial b_{21}}\)

时间:2022-04-23 06:57:40

这里不想解释怎么 marginalize,什么是 First-Estimate Jacobian。这里只想看看代码,看看Hessian矩阵是怎么结构出来的。

代码顶用于存储窗口优化过程Hessian矩阵使用的导数存储在布局体RawResidualJacobian中。

struct RawResidualJacobian { EIGEN_MAKE_ALIGNED_OPERATOR_NEW; // ================== new structure: save independently =============. VecNRf resF; // typdef Eigen::Matrix<float,MAX_RES_PER_POINT,1> VecNRf; MAX_RES_PER_POINT == 8 // the two rows of d[x,y]/d[xi]. Vec6f Jpdxi[2]; // 2x6 // the two rows of d[x,y]/d[C]. VecCf Jpdc[2]; // 2x4 // the two rows of d[x,y]/d[idepth]. Vec2f Jpdd; // 2x1 // the two columns of d[r]/d[x,y]. VecNRf JIdx[2]; // 9x2 // = the two columns of d[r] / d[ab] VecNRf JabF[2]; // 9x2 // = JIdx^T * JIdx (inner product). Only as a shorthand. Mat22f JIdx2; // 2x2 // = Jab^T * JIdx (inner product). Only as a shorthand. Mat22f JabJIdx; // 2x2 // = Jab^T * Jab (inner product). Only as a shorthand. Mat22f Jab2; // 2x2 };

以上变量的类型中呈现NR,说明该变量是存储了每一个 pattern 点的信息。

此刻将这些变量对应的导数一一列出:

VecNRf resF;对应\(r_{21}\),1x8,这里的\(r_{21}\)是对付一个点,八个 pattern residual 构成的向量。

Vec6f Jpdxi[2];对应\(\partial x_2 \over \partial \xi_{21}\),2x6,注意这里的\(x_2\)是像素坐标。(我一般把像素坐标写成\(x\),对应代码中的变量Ku,归一化坐标写成\(x^{\prime}\),对应代码中的变量u。)

VecCf Jpdc[2];对应\(\partial x_2 \over \partial C\),这里的\(C\)指相机内参\(\begin{bmatrix} f_x, f_y, c_x, c_y\end{bmatrix}^T\)

Vec2f Jpdd;对应\(\partial x_2 \over \partial \rho_1\),2x4,注意是对 host 帧的逆深度求导。

VecNRf JIdx[2];对应\(\partial r_{21} \over \partial x_2\),8x2,这个和 target 帧上的影像梯度相关。

VecNRf JabF[2];对应\({\partial r_{21} \over \partial a_{21}}, {\partial r_{21} \over \partial b_{21}}\),8x1,8x1。

Mat22f JIdx2;对应\({\partial r_{21} \over \partial x_2}^T{\partial r_{21} \over \partial x_2}\),2x8 8x2,2x2。

Mat22f JabJIdx;对应\(\begin{bmatrix}{\partial r_{21} \over \partial a_{21}} & {\partial r_{21} \over \partial b_{21}} \end{bmatrix}^T{\partial r_{21} \over \partial x_2}\),2x8 8x2,2x2。

Mat22f Jab2;对应\(\begin{bmatrix}{\partial r_{21} \over \partial a_{21}} & {\partial r_{21} \over \partial b_{21}} \end{bmatrix}^T\begin{bmatrix}{\partial r_{21} \over \partial a_{21}} & {\partial r_{21} \over \partial b_{21}} \end{bmatrix}\),2x8 2x8,2x2。

在 PointFrameResidual::linearize 中对这些变量进行了计算。

在计算时使用了投影过程中的变量,此刻将这些变量与公式对应。投影过程标准公式如下:

\[\begin{align} x_2 &= K \rho_2 (R_{21} \rho_1^{-1} K^{-1} x_1 + t_{21}) \notag \\ &= K x^{\prime}_2\notag \end{align}\]

变量的对应关系如下:

KliP = \(K^{-1}x_1\) = \(x_1^{\prime}\)

ptp = \(R_{21}K^{-1}x_1 + \rho_1 t_{21}\) = \(\rho_2^{-1}\rho_1K^{-1}x_2\)

drescale = \(\rho_2 \rho_1^{-1}\)

[u, v, 1]^T = \(K^{-1}x_2\) = \(x_2^{\prime}\)

[Ku, Kv, 1]^T = \(x_2\)

1. Vec2f Jpdd;\(\partial x_2 \over \partial \rho_1\)

d_d_x = drescale * (PRE_tTll_0[0]-PRE_tTll_0[2]*u)*SCALE_IDEPTH*HCalib->fxl(); d_d_y = drescale * (PRE_tTll_0[1]-PRE_tTll_0[2]*v)*SCALE_IDEPTH*HCalib->fyl();

计算\(\partial x_2 \over \partial \rho_1\),这个在博客《直接法光度误差导数推导》中已经讲了如何求解。得到的功效是:

\[\begin{bmatrix} f_x \rho_1^{-1}\rho_2(t_{21}^x - u^{\prime}_2t_{21}^z) \\ f_y \rho_1^{-1}\rho_2(t_{21}^y - v^{\prime}_2t_{21}^z)\end{bmatrix}\]

2.VecCf Jpdc[2];\(\partial x_2 \over \partial C\)

d_C_x[2] = drescale*(PRE_RTll_0(2,0)*u-PRE_RTll_0(0,0)); d_C_x[3] = HCalib->fxl() * drescale*(PRE_RTll_0(2,1)*u-PRE_RTll_0(0,1)) * HCalib->fyli(); d_C_x[0] = KliP[0]*d_C_x[2]; d_C_x[1] = KliP[1]*d_C_x[3]; d_C_y[2] = HCalib->fyl() * drescale*(PRE_RTll_0(2,0)*v-PRE_RTll_0(1,0)) * HCalib->fxli(); d_C_y[3] = drescale*(PRE_RTll_0(2,1)*v-PRE_RTll_0(1,1)); d_C_y[0] = KliP[0]*d_C_y[2]; d_C_y[1] = KliP[1]*d_C_y[3]; d_C_x[0] = (d_C_x[0]+u)*SCALE_F; d_C_x[1] *= SCALE_F; d_C_x[2] = (d_C_x[2]+1)*SCALE_C; d_C_x[3] *= SCALE_C; d_C_y[0] *= SCALE_F; d_C_y[1] = (d_C_y[1]+v)*SCALE_F; d_C_y[2] *= SCALE_C; d_C_y[3] = (d_C_y[3]+1)*SCALE_C;

我算对相机内参的导数与代码不一致,,先写出我的求导过程。