svo_note
SVO論文筆記
- 1.frame overviews
- 2. Motion Estimate Thread
- 2.1 Sparse Model-based Image Alignment 基于稀疏點(diǎn)亮度的位姿預(yù)估
- 2.2 Relaxation Through Feature Alignment 基于圖塊的特征點(diǎn)匹配
- 2.3 Pose and Structure Refinement
- 3 Mapping Thread
- 3.1 depth-filter
- 3.2 初始化
- 參考:
1.frame overviews
SVO的整體框架如鏈接,可以看到整個(gè)SVO的結(jié)構(gòu)是由兩個(gè)線程構(gòu)成的,第一個(gè)線程有三個(gè)主要的操作,a. Sparse Model-based Image Alignment; b. Feature Alignment; c. Pose&Structure Refinement。第二個(gè)線程主要是map的過程,一旦有一幀被定義為keyframe,就提取其中的feature,并初始化深度濾波器,如果不是keyframe,則一直更新深度濾波器,如果某個(gè)feature的深度收斂了,則生成3D點(diǎn)放入Map中作為landmark。
2. Motion Estimate Thread
該線程中主要求解當(dāng)前幀的位姿(Sparse Model-based Image Alignment; Feature Alignment)和local BA(Pose&Structure Refinement). svo 方法中motion estimation的步驟可以簡單概括如下:
對稀疏的特征塊使用direct method 配準(zhǔn),獲取相機(jī)位姿;
通過獲取的位姿預(yù)測參考幀中的特征塊在當(dāng)前幀中的位置,由于深度估計(jì)的不準(zhǔn)導(dǎo)致獲取的位姿也存在偏差,從而使得預(yù)測的特征塊位置不準(zhǔn)。由于預(yù)測的特征塊位置和真實(shí)位置很近,所以可以使用牛頓迭代法對這個(gè)特征塊的預(yù)測位置進(jìn)行優(yōu)化。
特征塊的預(yù)測位置得到優(yōu)化,說明之前使用直接法預(yù)測的有問題。利用這個(gè)優(yōu)化后的特征塊預(yù)測位置,再次使用直接法,對相機(jī)位姿(pose)以及特征點(diǎn)位置(structure)進(jìn)行優(yōu)化
2.1 Sparse Model-based Image Alignment 基于稀疏點(diǎn)亮度的位姿預(yù)估
該部分類似于光流,不過求解的不是對應(yīng)關(guān)系,而是相對位姿。
直接法具體過程如下:
??step1. 準(zhǔn)備工作。假設(shè)相鄰幀之間的位姿Tk,k?1T_{k,k?1}Tk,k?1?已知,一般初始化為上一相鄰時(shí)刻的位姿或者假設(shè)為單位矩陣。通過之前多幀之間的特征檢測以及深度估計(jì),我們已經(jīng)知道第k-1幀中特征點(diǎn)位置以及它們的深度。
??step2. 重投影。知道Ik?1I_{k?1}Ik?1?中的某個(gè)特征在圖像平面的位置(u,v),以及它的深度d,能夠?qū)⒃撎卣魍队暗饺S空間pk?1p_{k?1}pk?1?,該三維空間的坐標(biāo)系是定義在Ik?1I_{k?1}Ik?1?攝像機(jī)坐標(biāo)系的。所以,我們要將它投影到當(dāng)前幀IkI_{k}Ik?中,需要位姿轉(zhuǎn)換Tk,k?1T_{k,k?1}Tk,k?1?,得到該點(diǎn)在當(dāng)前幀坐標(biāo)系中的三維坐標(biāo)pkp_kpk?。最后通過攝像機(jī)內(nèi)參數(shù),投影到IkI_{k}Ik?的圖像平面(u′,v′)(u′,v′)(u′,v′),完成重投影。
??step3. 迭代優(yōu)化更新位姿 。按理來說對于空間中同一個(gè)點(diǎn),被極短時(shí)間內(nèi)的相鄰兩幀拍到,它的亮度值應(yīng)該沒啥變化。但由于位姿是假設(shè)的一個(gè)值,所以重投影的點(diǎn)不準(zhǔn)確,導(dǎo)致投影前后的亮度值是不相等的。不斷優(yōu)化位姿使得這個(gè)殘差最小,就能得到優(yōu)化后的位姿Tk,k?1T_{k,k?1}Tk,k?1?。
??將上述過程公式化如下:通過不斷優(yōu)化位姿Tk,k?1T_{k,k?1}Tk,k?1?最小化殘差損失函數(shù)。其優(yōu)化函數(shù)為:
Tk?1k=argmin??ρ[δI(T,u)]duT_{k?1}^k=argmin?_?ρ[δI(T,u)]du Tk?1k?=argmin???ρ[δI(T,u)]du
其中:
-
ρ[?]=0.5∥?∥2ρ[?]=0.5∥?∥^ 2ρ[?]=0.5∥?∥2,可見整個(gè)過程是一個(gè)最小二乘法的問題;
-
δI(T,u)=Ik(π(T?π?1(u,du)))?Ik?1(u)δI ( T , u ) = I _k(π ( T* π ^{? 1} ( u , d u ) )) ? I k ? 1 ( u )δI(T,u)=Ik?(π(T?π?1(u,du)))?Ik?1(u),這個(gè)殘差對比的是圖像位置上的像素值的灰度,其中u ∈ ? ,?表示即可以在k-1幀圖像上看到,又可以通過投影在k幀上看到
-
對于比對灰度值的算法來說,一般都會用一個(gè)patch size中的全部像素的灰度進(jìn)行對比,因此下面的公式中都不僅僅使用一點(diǎn)像素,而是使用多點(diǎn)像素進(jìn)行求解的,但是在這個(gè)過程中,作者為了提高計(jì)算的速度,并沒有進(jìn)行patch的投影,算是以量取勝吧
NOTE:公式中 π?1(u,du)π ^{? 1} ( u , d u )π?1(u,du) 為根據(jù)圖像位置和深度逆投影到三維空間,第二步 T?π?1(u,du)T* π ^{? 1} ( u , d u )T?π?1(u,du) 將三維坐標(biāo)點(diǎn)旋轉(zhuǎn)平移到當(dāng)前幀坐標(biāo)系下,第三步 π(T?π?1(u,du))π ( T* π ^{? 1} ( u , d u ) )π(T?π?1(u,du)) 再將三維坐標(biāo)點(diǎn)投影回當(dāng)前幀圖像坐標(biāo)。當(dāng)然在優(yōu)化過程中,殘差的計(jì)算方式不止這一種形式:有前向(forwards),逆向(inverse)之分,并且還有疊加式(additive)和構(gòu)造式(compositional)之分。這方面可以讀讀光流法方面的論文,Baker的大作《Lucas-Kanade 20 Years On: A Unifying Framework》。選擇的方式不同,在迭代優(yōu)化過程中計(jì)算雅克比矩陣的時(shí)候就有差別,一般為了減小計(jì)算量,都采用的是inverse compositional algorithm。
優(yōu)化目標(biāo)函數(shù):
把上述的notation帶入到優(yōu)化函數(shù)中就可以得到
Tk?1k=argmin∑i∈?1/2∥δI(Tk?1k,ui)∥2T_{k?1}^k=argmin∑_{i∈?}1/2∥δI(T_{k?1}^k,u_i)∥^2 Tk?1k?=argmini∈?∑?1/2∥δI(Tk?1k?,ui?)∥2
其中雅克比矩陣為圖像殘差對李代數(shù)的求導(dǎo),可以通過鏈?zhǔn)角髮?dǎo)得到:
J=?δI(ξ,ui)?ξ=?Ik?1(a)?a∣a=ui.?π(b)?b∣b=pi.?T(ξ)?ξ∣ξ=0.pi=?I?u.?u?b.?b?ξJ=\frac{\partial\delta I(\xi,u_i)}{\partial\xi} = \frac{\partial I_{k-1}(a)}{\partial a}|_{a=u_{i}}.\frac{\partial π(b)}{\partial b}|_{b=p_{i}}.\frac{\partial T(\xi)}{\partial \xi}|_{\xi=0}.p_i = \frac{\partial I}{\partial u}. \frac{\partial u}{\partial b}. \frac{\partial b}{\partial \xi} J=?ξ?δI(ξ,ui?)?=?a?Ik?1?(a)?∣a=ui??.?b?π(b)?∣b=pi??.?ξ?T(ξ)?∣ξ=0?.pi?=?u?I?.?b?u?.?ξ?b?
對于上一幀的每一個(gè)特征點(diǎn),都進(jìn)行這樣的計(jì)算, 在自己本來的層數(shù)上, 取那個(gè)特征點(diǎn)左上角的 4x4 圖塊。如果特征點(diǎn)映射回原來的層數(shù)時(shí),坐標(biāo)不是整數(shù),就進(jìn)行插值,其實(shí),本來提取特征點(diǎn)的時(shí)候,在這一層特征點(diǎn)坐標(biāo)就應(yīng)該是整數(shù)。把圖塊往這一幀的圖像上的對應(yīng)的層數(shù)投影,然后計(jì)算雅克比和殘差。 計(jì)算殘差時(shí), 因?yàn)橥队暗奈恢貌⒉粍偤檬钦麛?shù)的像素,所以會在投影點(diǎn)附近插值,獲取與投影圖塊對應(yīng)的圖塊。最后,得到一個(gè)巨大的雅克比矩陣,以及殘差矩陣。但是為了節(jié)省存儲空間,提前就轉(zhuǎn)換成了 H 矩陣 $ H =J *J ^ T$ 。
上面的非線性最小化二乘問題,可以用高斯牛頓迭代法求解,位姿的迭代增量ξ(李代數(shù))可以通過下述方程計(jì)算:
JTJξ=?JTδI(0)Hξ=?JTδI(0)ξ=?H?1JTδI(0)J^TJξ =-J^T \delta I(0) \\ H \xi=-J^T \delta I(0) \\ \xi =-H^{-1}J^T \delta I(0) \\ JTJξ=?JTδI(0)Hξ=?JTδI(0)ξ=?H?1JTδI(0)
然后,得到 T(ξ)T(\xi)T(ξ) ,逆矩陣得到 T(ψ)T(\psi)T(ψ) ,再更新出 Tk,k?1T_{k,k-1}Tk,k?1? 。然后,在新的位置上,再從像素點(diǎn)坐標(biāo),投影出新的點(diǎn) pk?1p_{k-1}pk?1?。每一層迭代 30 次。 因?yàn)檫@種 inverse-compositional 方法,用這種近似的思想,雅克比就可以不用再重新計(jì)算了。(因?yàn)橹匦峦队俺鲂碌?p 點(diǎn)的位置, 這個(gè)過程沒有在殘差公式里面表現(xiàn)出來。) 這樣子逐層下去,重復(fù)之前的步驟。
對于每一個(gè)圖塊的每一個(gè)像素,它的雅克比計(jì)算如下。
?I?u\frac{\partial I}{\partial u}?u?I?, 是這個(gè)像素插值點(diǎn)在圖像上的梯度,就是水平右邊的像素點(diǎn)減去水平左邊的像素點(diǎn),豎直下邊的像素點(diǎn)減去豎直上邊的像素點(diǎn)。如下圖所示。
?u?b\frac{\partial u}{\partial b}?b?u?算的是投影雅克比
u=π(b)=K[bx/bzby/bzbz/bz]=[fx0cx0fycy001]?[bx/bzby/bz1]=[fxbx/bz+u0fyby/bz+v01]u=π(b)=K \left[ \begin{matrix} b_x/b_z \\ b_y/b_z \\b_z/b_z \end{matrix} \right] =\left[ \begin{matrix} f_x &0 &c_x\\ 0 &f_y &c_y\\0 &0 &1 \end{matrix} \right] * \left[ \begin{matrix} b_x/b_z \\ b_y/b_z \\1 \end{matrix} \right] =\left[ \begin{matrix} f_xb_x/b_z +u_0\\ f_yb_y/b_z +v_0\\1 \end{matrix} \right] u=π(b)=K???bx?/bz?by?/bz?bz?/bz?????=???fx?00?0fy?0?cx?cy?1????????bx?/bz?by?/bz?1????=???fx?bx?/bz?+u0?fy?by?/bz?+v0?1????
?u?b=[fx/bz0?fx.bx/bz20fy/bz?fy.by/bz2]\frac{\partial u}{\partial b}= \left[ \begin{matrix} f_x/b_z & 0 &-f_x.b_x/b^2_z\\ 0 &f_y/b_z & -f_y.b_y/b^2_z \end{matrix} \right] ?b?u?=[fx?/bz?0?0fy?/bz???fx?.bx?/bz2??fy?.by?/bz2??]
?b?ξ=?T(ξ)p?ξ=[I?p∧]=?(δ?∧+δρ)?[δρδ?]\frac{\partial b}{\partial \xi} =\frac{\partial T(\xi)p}{\partial \xi} =[I \quad -p^{\wedge}] =\frac{\partial (\delta \phi^{\wedge} + \delta \rho)}{\partial [\delta \rho \quad\delta \phi]} ?ξ?b?=?ξ?T(ξ)p?=[I?p∧]=?[δρδ?]?(δ?∧+δρ)?
=[1000pz?py010?pz0px001py?px0]= \left[ \begin{matrix} 1 & 0 & 0 & 0 & p_z&-p_y\\ 0 & 1 & 0 & -p_z& 0 & p_x\\ 0 & 0 & 1 & p_y & -p_x& 0 \end{matrix} \right] =???100?010?001?0?pz?py??pz?0?px???py?px?0????
為了方便計(jì)算,雖然 b=T(ξ)pb =T(\xi) pb=T(ξ)p ,但因?yàn)?span id="ze8trgl8bvbq" class="katex--inline">T(ξ)T(\xi)T(ξ) 是一個(gè)很小的擾動(dòng),所以可以認(rèn)為 b=T(ξ)pb =T(\xi) pb=T(ξ)p,
?u?b=?u?T(ξ)p≈?u?p\frac{\partial u}{\partial b}=\frac{\partial u}{\partial {T(\xi) p}}\approx\frac{\partial u}{\partial p}?b?u?=?T(ξ)p?u?≈?p?u?
所以,后兩項(xiàng)就可以相乘,統(tǒng)一用 p 來表示了。 可以認(rèn)為$ f =f_x=f_y$ 。
因此,
?u?b=?b?ξ=[fx/bz0?fx.bx/bz20fy/bz?fy.by/bz2]?[1000pz?py010?pz0px001py?px0]\frac{\partial u}{\partial b} =\frac{\partial b}{\partial \xi} = \left[ \begin{matrix} f_x/b_z & 0 &-f_x.b_x/b^2_z\\ 0 &f_y/b_z & -f_y.b_y/b^2_z \end{matrix} \right] * \left[ \begin{matrix} 1 & 0 & 0 & 0 & p_z&-p_y\\ 0 & 1 & 0 & -p_z& 0 & p_x\\ 0 & 0 & 1 & p_y & -p_x& 0 \end{matrix} \right] ?b?u?=?ξ?b?=[fx?/bz?0?0fy?/bz???fx?.bx?/bz2??fy?.by?/bz2??]????100?010?001?0?pz?py??pz?0?px???py?px?0????
=[fx/pz0?fx/pz2?fxpxpy/pz2fx+fxpx2/pz2?fxpy/pz0fy/pz?fy/pz2?fy?fypy2/pz2?fypypy/pz2fypx/pz]= \left[ \begin{matrix} f_x/p_z & 0 & -f_x/p^2_z & -f_xp_xp_y/p^2_z & f_x+f_xp^2_x/p^2_z &-f_xp_y/p_z\\ 0 & f_y/p_z & -f_y/p^2_z & - f_y -f_yp^2_y/p^2_z& -f_yp_yp_y/p^2_z & f_yp_x/p_z \end{matrix} \right] =[fx?/pz?0?0fy?/pz???fx?/pz2??fy?/pz2???fx?px?py?/pz2??fy??fy?py2?/pz2??fx?+fx?px2?/pz2??fy?py?py?/pz2???fx?py?/pz?fy?px?/pz??]
=[].f(fx、fy)= [].f(f_x 、f_y) =[].f(fx?、fy?)
對于每一個(gè)特征點(diǎn),根據(jù)像素位置算出?I?u\frac{\partial I}{\partial u}?u?I?,再根據(jù)反投影出來的空間點(diǎn)位置 p 算出上式的左邊項(xiàng),根據(jù)特征點(diǎn)所在的層數(shù)算出 f 。然后,相乘,就得到了一行雅克比矩陣。 再根據(jù) $H=J J ^ T ,,,J^TJξ =-J^T \delta I(0)$加到 H 矩陣和殘差矩陣上。
最后,在優(yōu)化出ξ\xiξ 后,更新如下,
Tk,k?1=Tk,k?1Tk?1,k?1=Tk,k?1Tψ=Tk,k?1T(ξ)?1T_{k,k-1}=T_{k,k-1}T_{k-1,k-1}=T_{k,k-1}T_{\psi}=T_{k,k-1}T(\xi)^{-1} Tk,k?1?=Tk,k?1?Tk?1,k?1?=Tk,k?1?Tψ?=Tk,k?1?T(ξ)?1
注釋:但是在程序里面,直接就是Tk,k?1=Tk,k?1T(ξ)T_{k,k-1}=T_{k,k-1}T(\xi)Tk,k?1?=Tk,k?1?T(ξ) 。可能是為了加快計(jì)算,認(rèn)為T(ξ)?1≈Tk,k?1T(\xi)^{-1} \approx T_{k,k-1}T(ξ)?1≈Tk,k?1? 。 在 sparse_align.cpp 的 307行
T_curnew_from_ref = T_curold_from_ref * SE3::exp(-x_); 這個(gè)地方, 為什么不是 T_curnew_from_ref = T_curold_from_ref *(SE3::exp(x_)).inverse()**需要以后研究一下。
到這里,我們已經(jīng)能夠估計(jì)位姿了,但是這個(gè)位姿肯定不是完美的。導(dǎo)致重投影預(yù)測的特征點(diǎn)在中的位置并不和真正的吻合,也就是還會有殘差的存在。如下圖所示:
圖中灰色的特征塊為真實(shí)位置,藍(lán)色特征塊為預(yù)測位置。幸好,他們偏差不大,可以構(gòu)造殘差目標(biāo)函數(shù),和上面直接法類似,不過優(yōu)化變量不再是相機(jī)位姿,而是像素的位置(u′,v′)(u′,v′)(u′,v′),通過迭代對特征塊的預(yù)測位置進(jìn)行優(yōu)化。這就是svo中提到的Feature Alignment。
2.2 Relaxation Through Feature Alignment 基于圖塊的特征點(diǎn)匹配
通過第一步的幀間匹配能夠得到當(dāng)前幀相機(jī)的位姿,但是這種frame to frame估計(jì)位姿的方式不可避免的會帶來累計(jì)誤差從而導(dǎo)致漂移。所以,應(yīng)該通過已經(jīng)建立好的地圖模型,來進(jìn)一步約束當(dāng)前幀的位姿。
地圖模型通常來說保存的就是三維空間點(diǎn),因?yàn)?strong>每一個(gè)Key frame通過深度估計(jì)能夠得到特征點(diǎn)的三維坐標(biāo),這些三維坐標(biāo)點(diǎn)通過特征點(diǎn)在Key Frame中進(jìn)行保存。所以SVO地圖上保存的是Key Frame 以及還未插入地圖的KF中的已經(jīng)收斂的3d點(diǎn)坐標(biāo)(這些3d點(diǎn)坐標(biāo)是在世界坐標(biāo)系下的),也就是說地圖map不需要自己管理所有的3d點(diǎn),它只需要管理KF就行了。
那選取KF的標(biāo)準(zhǔn)是啥?KF中保存了哪些東西?
比如,當(dāng)新的幀new frame和相鄰KF的平移量超過場景深度平均值的12%時(shí)(比如四軸上升),new frame就會被當(dāng)做KF,它會被立即插入地圖。同時(shí),又在這個(gè)新的KF上檢測新的特征點(diǎn)作為深度估計(jì)的seed,這些seed會不斷融合新的new frame進(jìn)行深度估計(jì)。
但是,如果有些seed點(diǎn)3d點(diǎn)位姿通過深度估計(jì)已經(jīng)收斂了,怎么辦?
map用一個(gè)point_candidates來保存這些尚未插入地圖中的點(diǎn)。所以map這個(gè)數(shù)據(jù)結(jié)構(gòu)中保存了兩樣?xùn)|西,以前的KF的3d點(diǎn)以及新的尚未插入地圖的KF中已經(jīng)收斂的3d點(diǎn)。
通過地圖我們保存了很多三維空間點(diǎn),很明顯,每一個(gè)new frame都是可能看到地圖中的某些點(diǎn)的。由于new frame的位姿通過上一步的直接法已經(jīng)計(jì)算出來了,按理來說這些被看到的地圖上的點(diǎn)可以被投影到這個(gè)new frame中,即圖中的藍(lán)色方框塊。上圖中分析了,所有位姿誤差導(dǎo)致這個(gè)方框塊在new frame中肯定不是真正的特征塊所處的位置。所以需要Feature Alignment來找到地圖中特征塊在new frame中應(yīng)該出現(xiàn)的位置,根據(jù)這個(gè)位置誤差為進(jìn)一步的優(yōu)化做準(zhǔn)備。基于光度不變性假設(shè),特征塊在以前參考幀中的亮度應(yīng)該和new frame中的亮度差不多。所以可以重新構(gòu)造一個(gè)殘差,對特征預(yù)測位置進(jìn)行優(yōu)化:
ui′=argmin12∥Ik(ui′)?AiIr(ui)∥2u^′_i=argmin \frac{1}{2}∥I_k(u^′_i)?A_iI_r(u_i)∥^2 ui′?=argmin21?∥Ik?(ui′?)?Ai?Ir?(ui?)∥2
注意這里的優(yōu)化變量是像素位置,這過程就是光流法跟蹤。并且注意,光度誤差的前一部分是當(dāng)前圖像中的亮度值,后一部分不是 Ik?1I_{k?1}Ik?1?而是 iri_rir?,即它是根據(jù)投影的3d點(diǎn)追溯到的這個(gè)3d點(diǎn)所在的key frame中的像素值,而不是相鄰幀。由于是特征塊對比并且3d點(diǎn)所在的KF可能離當(dāng)前幀new frame比較遠(yuǎn),所以光度誤差和前面不一樣的是還加了一個(gè)仿射變換,需要對KF幀中的特征塊進(jìn)行旋轉(zhuǎn)拉伸之類仿射變換后才能和當(dāng)前幀的特征塊對比。
??這時(shí)候的迭代量計(jì)算方程和之前是一樣的,只不過雅克比矩陣變了,這里的雅克比矩陣很好計(jì)算:
KaTeX parse error: Undefined control sequence: \matrix at position 12: J= \left[ \?m?a?t?r?i?x?{ \frac{\part…
就是圖像橫縱兩個(gè)方向的梯度嘛。
??通過這一步我們能夠得到優(yōu)化后的特征點(diǎn)預(yù)測位置,它比之前通過相機(jī)位姿預(yù)測的位置更準(zhǔn),所以反過來,我們利用這個(gè)優(yōu)化后的特征位置,能夠進(jìn)一步去優(yōu)化相機(jī)位姿以及特征點(diǎn)的三維坐標(biāo)。所以位姿估計(jì)的最后一步就是Pose and Structure Refinement。
2.3 Pose and Structure Refinement
在一開始的直接法匹配中,我們是使用的光度誤差,這里由于優(yōu)化后的特征位置和之前預(yù)測的特征位置存在差異,這個(gè)能用來構(gòu)造新的優(yōu)化目標(biāo)函數(shù)。
Tw,k=argmin12∑i(∥ui?π(Tw,k,wpi)∥)2T_{w,k}=argmin \frac{1}{2}∑_i (∥u_i?π(T_{w,k},_wp_i)∥)^2 Tw,k?=argmin21?i∑?(∥ui??π(Tw,k?,w?pi?)∥)2
這個(gè)部分就是一個(gè)BA,不過論文也說了,最后一步也會有一個(gè)local BA,修正位姿和3D點(diǎn)
上式中誤差變成了像素重投影以后位置的差異(不是像素值的差異),優(yōu)化變量還是相機(jī)位姿,雅克比矩陣大小為2×6(橫縱坐標(biāo)u,v分別對六個(gè)李代數(shù)變量求導(dǎo))。這一步是就叫做motion-only Bundler Adjustment。同時(shí)根據(jù)根據(jù)這個(gè)誤差定義,我們還能夠?qū)Λ@取的三維點(diǎn)的坐標(biāo)(x,y,z)進(jìn)行優(yōu)化,還是上面的誤差像素位置誤差形式,只不過優(yōu)化變量變成三維點(diǎn)的坐標(biāo),這一步叫Structure -only Bundler Adjustment,優(yōu)化過程中雅克比矩陣大小為2×32×3(橫縱坐標(biāo)u,vu,v分別對點(diǎn)坐標(biāo)(x,y,z)變量求導(dǎo))。
Discussion
論文討論了該方法中的前幾個(gè)步驟,討論了如果使用傳統(tǒng)的LK光流法的話,時(shí)間會增加,同時(shí)較大距離的跟蹤需要較大的patch以及金字塔的應(yīng)用,同時(shí)因?yàn)闀嬖诟鷣G的情況,因此需要外點(diǎn)檢測,而在SVO的方法中,因?yàn)橛衒eature alignment的步驟,使得特征點(diǎn)的位置還是比較準(zhǔn)確的,因此能保證沒有外點(diǎn)。
3 Mapping Thread
該線程中主要的工作就是判斷當(dāng)前幀是否可以作為key frame,之后進(jìn)行深度濾波器的迭代以及初始化工作。下面主要說明深度濾波器的相關(guān)推導(dǎo)
3.1 depth-filter
最基本的深度估計(jì)就是三角化,這是多視角幾何的基礎(chǔ)內(nèi)容(可以參看圣經(jīng)Hartly的《Multiple View Geometry in Computer Vision》中的第十二章structure computation;可以參看我的相應(yīng)博客)。我們知道通過兩幀圖像的匹配點(diǎn)就可以計(jì)算出這一點(diǎn)的深度值,如果有多幅圖像,那就能計(jì)算出這一點(diǎn)的多個(gè)深度值。這就像對同一個(gè)狀態(tài)變量我們進(jìn)行了多次測量,因此,可以用貝葉斯估計(jì)來對多個(gè)測量值進(jìn)行融合,使得估計(jì)的不確定性縮小。如下圖所示:
一開始深度估計(jì)的不確定性較大(淺綠色部分),通過三角化得到一個(gè)深度估計(jì)值以后,能夠極大的縮小這個(gè)不確定性(墨綠色部分)。
??在這里,先簡單介紹下svo中的三角化計(jì)算深度的過程,主要是極線搜索確定匹配點(diǎn)。在參考幀Ir中,我們知道了一個(gè)特征的圖像位置,假設(shè)它的深度值在[dmin,dmax][dmin,dmax]之間,那么根據(jù)這兩個(gè)端點(diǎn)深度值,我們能夠計(jì)算出他們在當(dāng)前幀Ik中的位置,如上圖中草綠色圓圈中的線段。確定了特征出現(xiàn)的極線段位置,就可以進(jìn)行特征搜索匹配了。如果極線段很短,小于兩個(gè)像素,那直接使用上面求位姿時(shí)提到的Feature Alignment光流法就可以比較準(zhǔn)確地預(yù)測特征位置。如果極線段很長,那分兩步走,第一步在極線段上間隔采樣,對采樣的多個(gè)特征塊一一和參考幀中的特征塊匹配,用Zero mean Sum of Squared Differences 方法對各采樣特征塊評分,那個(gè)得分最高,說明他和參考幀中的特征塊最匹配。第二步就是在這個(gè)得分最高點(diǎn)附近使用Feature Alignment得到次像素精度的特征點(diǎn)位置。像素點(diǎn)位置確定了,就可以三角化計(jì)算深度了。得到一個(gè)新的深度估計(jì)值以后,用貝葉斯概率模型對深度值更新。在LSD slam中,假設(shè)深度估計(jì)值服從高斯分布,用卡爾曼濾波(貝葉斯的一種)來更新深度值。這種假設(shè)中,他認(rèn)為深度估計(jì)值效果很棒,很大的概率出現(xiàn)在真實(shí)值(高斯分布均值)附近。而SVO的作者采用的是Vogiatzis的論文《Video-based, real-time multi-view stereo》提到的概率模型,而在深度濾波器中,論文把真實(shí)深度的分布看做一個(gè)正態(tài)分布+均勻分布的模型
這個(gè)概率模型是一個(gè)高斯分布加上一個(gè)設(shè)定在最小深度dmindmin和最大深度dmaxdmax之間的均勻分布。這個(gè)均勻分布的意義是假設(shè)會有一定的概率出現(xiàn)錯(cuò)誤的深度估計(jì)值。有關(guān)這個(gè)概率模型來由更嚴(yán)謹(jǐn)?shù)恼撟C去看看Vogiatzis的論文。同時(shí),有關(guān)這個(gè)概率模型遞推更新的過程具體可以看Vogiatzis在論文中提到的Supplementary material,論文中告知了下載地址。知道了這個(gè)貝葉斯概率模型的遞推過程,程序就可以實(shí)現(xiàn)深度值的融合了,結(jié)合supplementary material去看svo代碼中的updateSeeds(frame)這個(gè)程序就容易了,整個(gè)程序里的那些參數(shù)的計(jì)算遞歸過程的推導(dǎo),我簡單截個(gè)圖,這部分我也沒細(xì)看(公式19是錯(cuò)誤的,svo作者指出了),現(xiàn)在有幾篇博客對該部分進(jìn)行了推導(dǎo)。詳見盧彥斌:svo原理解析,東北大學(xué)孫志明:svo的Supplementary matterial 推導(dǎo)過程](https://blog.csdn.net/u013004597/article/details/52069741)
在深度估計(jì)的過程中,除了計(jì)算深度值外,這個(gè)深度值的不確定性也是需要計(jì)算的,它在很多地方都會用到,如極線搜索中確定極線的起始位置和長度,如用貝葉斯概率更新深度的過程中用它來確定更新權(quán)重(就像卡爾曼濾波中協(xié)方差矩陣扮演的角色),如判斷這個(gè)深度點(diǎn)是否收斂了,如果收斂就插入地圖等等。SVO的作者Forster作為第二作者發(fā)表的《REMODE: Probabilistic, Monocular Dense Reconstruction in Real Time》中對由于特征定位不準(zhǔn)導(dǎo)致的三角化深度誤差進(jìn)行了分析,如上圖。
它是通過假設(shè)特征點(diǎn)定位差一個(gè)像素偏差,來計(jì)算深度估計(jì)的不確定性。具體推導(dǎo)見原論文,簡單的幾何關(guān)系。
3.2 初始化
? SVO的初始化過程:它假設(shè)前兩個(gè)關(guān)鍵幀所拍到的特征點(diǎn)在一個(gè)平面上(四軸飛行棋對地面進(jìn)行拍攝),然后估計(jì)單應(yīng)性H矩陣,并通過三角化來估計(jì)初始特征點(diǎn)的深度值。SVO初始化時(shí)triangulation的方法具體代碼是vikit/math_utils.cpp里的triangulateFeatureNonLin()函數(shù),使用的是中點(diǎn)法,關(guān)于這個(gè)三角化代碼算法的推導(dǎo)見github issue。
還有就是SVO適用于攝像頭垂直向下的情況(也就是無人機(jī)上,垂直向上也可以,朝著一面墻也可以),為什么呢?
1.初始化的時(shí)候假設(shè)的是平面模型
2.KF的選擇是個(gè)極大的限制,除了KF的選擇原因外攝像頭水平朝前運(yùn)動(dòng)的時(shí)候,SVO中的深度濾波做的不好,這個(gè)討論可以看看github issue,然而在我的測試中,不知道修改了哪些參數(shù),稍微改動(dòng)了部分代碼,發(fā)現(xiàn)前向運(yùn)動(dòng),并且對著非平面SVO也是很溜的。
參考:
[1] http://blog.csdn.net/heyijia0327
[2] https://blog.csdn.net/heyijia0327/article/details/51083398
[3] https://blog.csdn.net/u013004597/article/details/52069741
[4] SVO論文翻譯總結(jié)
[5] http://rpg.ifi.uzh.ch/svo_pro.html
[6] https://www.cnblogs.com/wxt11/p/7097250.html
總結(jié)
- 上一篇: 狗狗驱虫一次多少钱
- 下一篇: 【Boost】noncopyable:不