
雙視角SFM也就是只有兩張圖做稀疏重建是很多三維重建任務(wù)里最容易被低估的一環(huán)。單目SFM序列幀多、冗余大跑起來(lái)反而穩(wěn)雙視角就兩張圖基線、重疊度、紋理、外參全靠這兩張圖硬扛稍微有點(diǎn)問題就直接崩。我前后用COLMAP、OpenMVG、Meshroom這幾套流程做過(guò)不少雙視角重建踩過(guò)的坑比單目多得多。這篇就把一個(gè)完整的雙視角SFM過(guò)程從頭到尾拆開講清楚包括數(shù)據(jù)采集、特征匹配、幾何驗(yàn)證、增量式重建、BA優(yōu)化、稠密重建和網(wǎng)格化每一步為什么這么做、參數(shù)怎么定、崩了怎么救都給你說(shuō)明白。適合正在做三維重建課程任務(wù)、需要快速跑通雙視角流程、或者想搞清楚SFM內(nèi)部機(jī)制的人參考。1. 雙視角SFM到底難在哪先搞清楚問題邊界1.1 雙視角和單目序列的本質(zhì)差異很多人第一次做雙視角SFM會(huì)下意識(shí)覺得圖少應(yīng)該更簡(jiǎn)單。恰恰相反雙視角是SFM里最脆弱的一種配置。單目序列有幾十上百幀幀間冗余極大某一對(duì)匹配錯(cuò)了后面的BA還能把它拉回來(lái)雙視角只有一次匹配機(jī)會(huì)兩張圖之間的特征對(duì)應(yīng)關(guān)系一旦有系統(tǒng)性偏差整個(gè)重建就廢了。從幾何角度看雙視角SFM本質(zhì)上就是求解一個(gè)對(duì)極幾何問題兩張圖之間的相對(duì)位姿由一個(gè)旋轉(zhuǎn)矩陣R和一個(gè)平移向量t描述而t的尺度是不可觀測(cè)的——這是單目和雙視角SFM的共同宿命。你重建出來(lái)的模型形狀是對(duì)的但絕對(duì)尺寸是任意的除非你有額外的尺度約束比如已知兩個(gè)點(diǎn)之間的真實(shí)距離或者有IMU、深度相機(jī)提供尺度。所以雙視角SFM的輸出嚴(yán)格來(lái)說(shuō)是一個(gè)相似變換意義下的重建結(jié)果形狀正確尺度自由整體可以任意旋轉(zhuǎn)平移。這一點(diǎn)在做任務(wù)的時(shí)候必須心里有數(shù)不然你會(huì)糾結(jié)為什么我的模型和真實(shí)尺寸對(duì)不上。1.2 雙視角能恢復(fù)什么、不能恢復(fù)什么雙視角能恢復(fù)的東西其實(shí)不少兩張圖的相機(jī)內(nèi)參如果做自標(biāo)定、相對(duì)外參、稀疏三維點(diǎn)云、以及每張圖的位姿。但有幾個(gè)東西它天生做不了絕對(duì)尺度前面說(shuō)了沒有額外約束就恢復(fù)不了。被遮擋區(qū)域兩張圖看不到的地方就是看不到?jīng)]有任何辦法。弱紋理區(qū)域的穩(wěn)定匹配白墻、純色桌面這種特征點(diǎn)根本提不出來(lái)。大基線下的匹配兩張圖視角差太大外觀變化劇烈描述子匹配會(huì)大面積失敗。我一般會(huì)先判斷手里的兩張圖屬于哪種情況。如果兩張圖是圍繞物體轉(zhuǎn)15到30度拍的重疊度在70%以上紋理豐富那雙視角SFM基本能跑得很漂亮。如果兩張圖視角差了60度以上或者有一張是俯拍一張是平視那就要做好心理準(zhǔn)備可能需要人工干預(yù)匹配。1.3 一個(gè)典型的雙視角任務(wù)場(chǎng)景假設(shè)你手里有兩張照片一張從物體左前方拍一張從右前方拍中間大概轉(zhuǎn)了25度物體是一個(gè)有紋理的擺件背景比較干凈。這就是雙視角SFM最理想的輸入。整個(gè)流程走下來(lái)大概是這樣的特征提取每張圖提取幾千個(gè)SIFT特征點(diǎn)。特征匹配兩張圖之間做暴力匹配或FLANN匹配。幾何驗(yàn)證用RANSAC估計(jì)基礎(chǔ)矩陣F或本質(zhì)矩陣E剔除誤匹配。初始化選一對(duì)好的匹配點(diǎn)三角化得到初始三維點(diǎn)。位姿求解從E矩陣分解出R和t恢復(fù)第二張圖的位姿。BA優(yōu)化聯(lián)合優(yōu)化相機(jī)位姿和三維點(diǎn)最小化重投影誤差。稠密重建用MVS多視圖立體生成稠密點(diǎn)云。網(wǎng)格化用泊松重建或Delaunay生成網(wǎng)格。這套流程在COLMAP里可以一條命令跑完但如果你想真正理解每一步在干什么就得手動(dòng)拆開看。下面我按這個(gè)順序把每一步的原理、參數(shù)、坑點(diǎn)都講透。2. 數(shù)據(jù)采集與預(yù)處理雙視角成敗的第一道關(guān)2.1 兩張圖怎么拍才靠譜雙視角SFM對(duì)輸入圖像的要求比單目序列苛刻得多。我總結(jié)了幾條硬性經(jīng)驗(yàn)基線要適中。基線太短三角化出來(lái)的三維點(diǎn)深度不確定性極大點(diǎn)云會(huì)像紙片一樣飄基線太長(zhǎng)兩張圖外觀差異大匹配直接崩。經(jīng)驗(yàn)值是基線約為物體到相機(jī)距離的1/5到1/3。比如你離物體1米拍兩張圖相機(jī)之間移動(dòng)20到30厘米比較合適。重疊度要夠。兩張圖的重疊區(qū)域最好在70%以上。判斷方法很簡(jiǎn)單把兩張圖并排看共同可見的特征區(qū)域是不是占了大部分。如果重疊不到50%匹配點(diǎn)會(huì)集中在重疊區(qū)邊緣區(qū)域重建質(zhì)量很差。曝光要一致。兩張圖如果一張亮一張暗SIFT描述子會(huì)受到明顯影響。拍攝時(shí)鎖定曝光、鎖定白平衡或者后期做直方圖匹配。我一般會(huì)在拍攝前用手動(dòng)模式固定ISO、快門、光圈避免自動(dòng)曝光帶來(lái)的差異。紋理要豐富。純色、反光、透明表面是SFM的天敵。如果物體本身紋理弱可以在旁邊放一些有紋理的參照物或者用投影儀打散斑圖案這是結(jié)構(gòu)光的思路但雙視角SFM里偶爾也用。2.2 圖像預(yù)處理的幾個(gè)必要?jiǎng)幼髂玫絻蓮垐D之后別急著丟進(jìn)SFM。先做幾件事去畸變?nèi)绻鄼C(jī)有畸變尤其是廣角鏡頭先用標(biāo)定參數(shù)去畸變。COLMAP支持在重建時(shí)估計(jì)畸變但雙視角下畸變和位姿容易耦合最好提前標(biāo)定好。統(tǒng)一分辨率兩張圖分辨率差太多特征尺度不一致匹配會(huì)變差。統(tǒng)一縮放到長(zhǎng)邊1600到2000像素比較合適太大跑得慢太小特征不夠?;叶然疭IFT本身在灰度圖上工作彩色信息對(duì)匹配幫助有限。當(dāng)然COLMAP內(nèi)部會(huì)處理但你自己做實(shí)驗(yàn)時(shí)灰度化能省不少事。直方圖均衡如果兩張圖亮度差異明顯做一次CLAHE限制對(duì)比度自適應(yīng)直方圖均衡能顯著提升匹配數(shù)量。提示預(yù)處理階段不要做過(guò)度降噪。SIFT對(duì)噪聲有一定魯棒性但過(guò)度高斯模糊會(huì)抹掉細(xì)節(jié)反而降低特征點(diǎn)數(shù)量和匹配質(zhì)量。2.3 相機(jī)內(nèi)參自標(biāo)定還是提前標(biāo)定雙視角SFM里相機(jī)內(nèi)參的處理有兩種路線路線一提前標(biāo)定。用棋盤格標(biāo)定板提前算出焦距、主點(diǎn)、畸變系數(shù)重建時(shí)固定內(nèi)參。這是最穩(wěn)的做法尤其適合你手頭相機(jī)固定、要做多次重建的場(chǎng)景。路線二自標(biāo)定。讓SFM流程自己估計(jì)內(nèi)參。雙視角下自標(biāo)定是欠約束的——兩張圖能提供的約束有限內(nèi)參和位姿容易耦合估計(jì)出來(lái)的焦距可能偏差很大。COLMAP在雙視角下如果開啟內(nèi)參優(yōu)化經(jīng)常會(huì)跑飛。我的建議是能標(biāo)定就標(biāo)定。如果實(shí)在沒法標(biāo)定至少把焦距固定成一個(gè)合理估計(jì)值比如根據(jù)EXIF里的焦距和傳感器尺寸換算只讓流程優(yōu)化主點(diǎn)或者干脆全固定。這樣重建的穩(wěn)定性會(huì)好很多。3. 特征提取與匹配雙視角SFM的核心戰(zhàn)場(chǎng)3.1 SIFT為什么還是首選深度學(xué)習(xí)特征SuperPoint、DISK、LoFTR這幾年很火但在雙視角SFM這個(gè)場(chǎng)景里SIFT依然是性價(jià)比最高的選擇。原因有幾個(gè)成熟穩(wěn)定SIFT從2004年到現(xiàn)在各種實(shí)現(xiàn)都經(jīng)過(guò)大量驗(yàn)證行為可預(yù)測(cè)。尺度不變雙視角下兩張圖拍攝距離可能不同SIFT的尺度不變性很重要。匹配框架完善COLMAP、OpenMVG對(duì)SIFT的支持最完整包括GPU加速版本??山忉屝詮?qiáng)出問題的時(shí)候你能通過(guò)可視化匹配點(diǎn)判斷是哪里錯(cuò)了。LoFTR這類檢測(cè)器-free的匹配方法在弱紋理場(chǎng)景下確實(shí)有優(yōu)勢(shì)但雙視角SFM里如果紋理足夠SIFT完全夠用而且速度更快、更容易調(diào)試。3.2 特征提取的關(guān)鍵參數(shù)以COLMAP為例SIFT提取有幾個(gè)關(guān)鍵參數(shù)參數(shù)含義雙視角推薦值說(shuō)明max_num_features每圖最大特征數(shù)8000-16000雙視角建議多提冗余大first_octave起始八度-1 或 0-1會(huì)放大圖像提更多點(diǎn)peak_threshold峰值閾值0.006-0.01越低點(diǎn)越多噪聲也越多edge_threshold邊緣閾值10默認(rèn)即可estimate_affine_shape估計(jì)仿射形狀0雙視角下開啟容易不穩(wěn)雙視角下我一般把max_num_features設(shè)到12000以上因?yàn)閮蓮垐D匹配時(shí)能用的點(diǎn)越多越好。peak_threshold可以適當(dāng)降低到0.006多提一些點(diǎn)反正后面RANSAC會(huì)剔除誤匹配。3.3 匹配策略暴力匹配還是FLANN兩張圖之間的匹配本質(zhì)是在高維描述子空間里找最近鄰。兩種主流做法暴力匹配Brute-Force對(duì)圖1的每個(gè)描述子在圖2的所有描述子里找最近的。復(fù)雜度是O(N*M)N和M各一萬(wàn)的話就是1億次距離計(jì)算。用GPU加速COLMAP的match命令支持CUDA可以很快跑完。FLANN匹配用KD樹或LSH做近似最近鄰速度快但可能漏掉一些正確匹配。雙視角下圖少我建議直接用暴力匹配保證召回率。匹配完之后要做比率測(cè)試Lowes ratio test對(duì)每個(gè)匹配找最近鄰和次近鄰如果最近鄰距離 0.7到0.8倍的次近鄰距離才保留。這個(gè)測(cè)試能剔除大量模糊匹配。雙視角下比率閾值可以放寬到0.8因?yàn)楸緛?lái)匹配就少太嚴(yán)會(huì)剩不下幾個(gè)點(diǎn)。3.4 幾何驗(yàn)證RANSAC估計(jì)F矩陣匹配完的點(diǎn)里還有大量誤匹配必須用幾何約束剔除。雙視角下用的是對(duì)極幾何如果兩個(gè)點(diǎn)x1和x2是正確匹配它們必須滿足 x2^T * F * x1 0其中F是基礎(chǔ)矩陣。用RANSAC估計(jì)F的流程隨機(jī)選8對(duì)匹配點(diǎn)8點(diǎn)法或5對(duì)5點(diǎn)法。用這些點(diǎn)算一個(gè)F。統(tǒng)計(jì)所有匹配點(diǎn)里滿足 x2^T * F * x1 閾值 的內(nèi)點(diǎn)數(shù)。重復(fù)若干次保留內(nèi)點(diǎn)最多的F。用所有內(nèi)點(diǎn)重新精算F。COLMAP里這一步是自動(dòng)的但你要關(guān)注內(nèi)點(diǎn)率。雙視角下如果內(nèi)點(diǎn)率低于30%說(shuō)明匹配質(zhì)量很差重建大概率會(huì)失敗。這時(shí)候要回頭檢查圖像質(zhì)量、重疊度、紋理。注意F矩陣估計(jì)出來(lái)之后可以分解出R和t但F本身包含了內(nèi)參信息。如果你已經(jīng)知道內(nèi)參應(yīng)該用本質(zhì)矩陣E K2^T * F * K1E的分解更穩(wěn)定。4. 增量式重建從兩張圖到三維點(diǎn)云4.1 初始化選哪對(duì)點(diǎn)做三角化雙視角只有兩張圖初始化就是選一對(duì)匹配點(diǎn)做三角化得到初始三維點(diǎn)然后以此為基準(zhǔn)恢復(fù)位姿。聽起來(lái)簡(jiǎn)單但選點(diǎn)有講究不要選太近的點(diǎn)兩個(gè)點(diǎn)在圖里挨得近三角化的深度不確定性極大。不要選深度差異太大的點(diǎn)一個(gè)點(diǎn)離相機(jī)很近一個(gè)很遠(yuǎn)尺度不好定。選分布均勻的點(diǎn)覆蓋圖像各個(gè)區(qū)域避免都擠在角落。實(shí)際操作中COLMAP會(huì)用一個(gè)評(píng)分函數(shù)自動(dòng)選初始點(diǎn)對(duì)考慮匹配點(diǎn)的分布、三角化角度等因素。你手動(dòng)做的話可以選圖像中心區(qū)域、匹配穩(wěn)定、三角化角度在5到30度之間的點(diǎn)對(duì)。4.2 位姿求解從E矩陣到R和t有了初始三維點(diǎn)和對(duì)應(yīng)的二維匹配就可以求解第二張圖的位姿。流程是從F或E矩陣分解出4組可能的(R, t)解。用初始三維點(diǎn)做cheirality check手性檢驗(yàn)三維點(diǎn)必須在兩個(gè)相機(jī)的前方。選出唯一正確的解。這里有個(gè)細(xì)節(jié)E矩陣分解出的t是單位向量尺度未知。所以恢復(fù)出來(lái)的位姿平移部分只有方向沒有大小。這也是為什么雙視角SFM的尺度是自由的。4.3 三角化把匹配點(diǎn)變成三維點(diǎn)三角化就是給定兩個(gè)相機(jī)的位姿和一對(duì)匹配點(diǎn)求三維空間中的交點(diǎn)。數(shù)學(xué)上是解一個(gè)最小二乘問題對(duì)于相機(jī)1x1 P1 * X 對(duì)于相機(jī)2x2 P2 * X其中P1、P2是投影矩陣X是三維點(diǎn)。兩個(gè)方程聯(lián)立用SVD或DLT求解。三角化的質(zhì)量取決于三角化角度兩條射線之間的夾角。角度太小2度深度誤差極大角度太大60度匹配可能不準(zhǔn)。雙視角下理想角度是5到30度。4.4 BA優(yōu)化讓重投影誤差最小初始重建出來(lái)之后位姿和三維點(diǎn)都有誤差。BABundle Adjustment就是聯(lián)合優(yōu)化所有相機(jī)參數(shù)和三維點(diǎn)最小化重投影誤差min Σ ||x_ij - π(K_i, R_i, t_i, X_j)||^2其中x_ij是第i個(gè)相機(jī)看到的第j個(gè)點(diǎn)的二維觀測(cè)π是投影函數(shù)X_j是三維點(diǎn)。雙視角BA的參數(shù)量很小兩個(gè)相機(jī)各6個(gè)外參3旋轉(zhuǎn)3平移加上幾千個(gè)三維點(diǎn)各3個(gè)坐標(biāo)。用Levenberg-Marquardt算法迭代求解通常幾十次迭代就收斂。COLMAP里BA是自動(dòng)跑的但你可以通過(guò)ba_refine_focal_length、ba_refine_principal_point等參數(shù)控制優(yōu)化哪些量。雙視角下我建議固定內(nèi)參只優(yōu)化外參和三維點(diǎn)避免內(nèi)參和位姿耦合。4.5 重建結(jié)果的評(píng)估指標(biāo)重建完怎么判斷好壞幾個(gè)關(guān)鍵指標(biāo)重投影誤差平均重投影誤差應(yīng)該在0.5到1.5像素之間。超過(guò)2像素說(shuō)明有問題。內(nèi)點(diǎn)數(shù)最終參與重建的三維點(diǎn)數(shù)量。雙視角下幾百到幾千個(gè)點(diǎn)算正常。三角化角度分布大部分點(diǎn)的三角化角度應(yīng)該在5到30度。軌跡長(zhǎng)度雙視角下每個(gè)點(diǎn)最多被2個(gè)相機(jī)看到軌跡長(zhǎng)度就是2。如果重投影誤差大、內(nèi)點(diǎn)少先別急著調(diào)參數(shù)回頭看看匹配質(zhì)量。大部分雙視角重建失敗根因都在匹配階段。5. 稠密重建與網(wǎng)格化從稀疏點(diǎn)到可用模型5.1 稀疏點(diǎn)云到稠密點(diǎn)云MVS的基本思路稀疏重建出來(lái)只有幾百到幾千個(gè)點(diǎn)只能看出大致形狀。要得到可用的模型需要做稠密重建MVSMulti-View Stereo。雙視角MVS的核心思路是對(duì)參考圖的每個(gè)像素在極線上搜索匹配像素。計(jì)算深度值得到深度圖。把深度圖反投影到三維空間得到稠密點(diǎn)云。雙視角MVS的難點(diǎn)在于只有兩個(gè)視角遮擋和弱紋理區(qū)域很難處理。COLMAP的patch_match_stereo在雙視角下能跑但效果不如多視角。如果對(duì)稠密質(zhì)量要求高建議多拍幾張圖哪怕只多拍3到5張稠密效果都會(huì)好很多。5.2 深度圖融合與點(diǎn)云濾波MVS出來(lái)的是每張圖的深度圖需要融合成統(tǒng)一的三維點(diǎn)云。融合時(shí)會(huì)做一致性檢查同一個(gè)三維點(diǎn)在不同深度圖里的投影深度要一致不一致的剔除。融合完的點(diǎn)云還有噪聲需要濾波統(tǒng)計(jì)濾波剔除離群點(diǎn)比如每個(gè)點(diǎn)看它周圍K個(gè)鄰居的平均距離超過(guò)閾值就刪。半徑濾波半徑內(nèi)鄰居數(shù)少于閾值的點(diǎn)刪掉。下采樣用體素柵格下采樣控制點(diǎn)云密度。這些在CloudCompare或Open3D里都能做。我一般用Open3D的remove_statistical_outlier和voxel_down_sample幾行代碼搞定。5.3 泊松重建與網(wǎng)格后處理點(diǎn)云到網(wǎng)格最常用的是泊松重建Poisson Reconstruction。它的思路是把點(diǎn)云的法向量看作一個(gè)向量場(chǎng)求一個(gè)標(biāo)量函數(shù)的梯度等于這個(gè)向量場(chǎng)然后提取等值面。泊松重建對(duì)噪聲魯棒能生成封閉的、水密的網(wǎng)格適合有紋理的物體。參數(shù)上關(guān)鍵是depth控制八叉樹深度越大越精細(xì)。雙視角點(diǎn)云通常比較稀疏depth設(shè)8到10比較合適太大容易過(guò)擬合噪聲。重建完的網(wǎng)格還要后處理去小連通分量刪掉面積很小的孤立網(wǎng)格塊。平滑拉普拉斯平滑或Taubin平滑去掉表面噪聲。簡(jiǎn)化如果面片太多用二次誤差度量QEM簡(jiǎn)化到合理面數(shù)。5.4 紋理映射讓模型有顏色網(wǎng)格出來(lái)是灰白的要貼紋理。雙視角紋理映射的基本做法是對(duì)每個(gè)面片選一個(gè)可見的相機(jī)視角把該視角的圖像投影到面片上。兩個(gè)視角的話選投影角度更正的、遮擋更少的那個(gè)。COLMAP的texture_mesh命令支持這種操作。但雙視角下紋理映射會(huì)有明顯的接縫和拉伸因?yàn)橹挥袃蓚€(gè)視角很多面片在兩個(gè)視角下都是斜視。如果對(duì)紋理要求高還是得多視角。6. 雙視角SFM常見崩盤場(chǎng)景與排查鏈路6.1 匹配點(diǎn)太少?gòu)膱D像質(zhì)量查起現(xiàn)象兩張圖匹配完只有幾十個(gè)點(diǎn)RANSAC之后剩個(gè)位數(shù)。排查順序看圖像本身是不是太模糊、太暗、紋理太少先肉眼判斷??刺卣鼽c(diǎn)數(shù)量每張圖提了多少SIFT點(diǎn)如果只有幾百個(gè)說(shuō)明peak_threshold太高或者圖像紋理確實(shí)弱??雌ヅ淇梢暬哑ヅ潼c(diǎn)畫出來(lái)是不是集中在某個(gè)小區(qū)域如果是說(shuō)明重疊度不夠??疵枋鲎泳嚯x分布正確匹配的描述子距離應(yīng)該明顯小于錯(cuò)誤匹配。如果兩者混在一起說(shuō)明圖像外觀差異太大。對(duì)應(yīng)的解決手段提高特征點(diǎn)數(shù)量、放寬比率測(cè)試閾值、做直方圖均衡、換用LoFTR等學(xué)習(xí)方法。6.2 重建出來(lái)是紙片三角化角度太小現(xiàn)象點(diǎn)云看起來(lái)是平的沒有深度感像一張紙。根因兩張圖基線太短三角化角度太小深度不確定性極大。排查算一下所有三維點(diǎn)的三角化角度分布。如果大部分點(diǎn)角度小于2度基本可以確定是基線問題。解決重新拍攝增大基線。如果沒法重拍只能接受這個(gè)結(jié)果或者引入額外的深度先驗(yàn)。6.3 BA不收斂或跑飛內(nèi)參耦合現(xiàn)象BA迭代過(guò)程中重投影誤差不降反升或者位姿估計(jì)出離譜的值。根因雙視角下內(nèi)參和位姿耦合同時(shí)優(yōu)化容易跑飛。排查看BA日志是不是焦距估計(jì)出了負(fù)值或者極大值。解決固定內(nèi)參只優(yōu)化外參和三維點(diǎn)。如果必須估計(jì)內(nèi)參加一個(gè)合理的先驗(yàn)約束比如焦距在某個(gè)范圍內(nèi)。6.4 稠密重建空洞多遮擋和弱紋理現(xiàn)象稠密點(diǎn)云大片空洞物體表面不完整。根因雙視角遮擋嚴(yán)重或者表面弱紋理導(dǎo)致MVS匹配失敗。排查看深度圖空洞區(qū)域是不是對(duì)應(yīng)遮擋區(qū)或弱紋理區(qū)。解決增加視角數(shù)量是最有效的。如果只能雙視角可以調(diào)MVS參數(shù)增大window_radius、降低min_consistency但效果有限。6.5 一個(gè)完整的排查決策表現(xiàn)象最可能根因快速驗(yàn)證方法解決手段匹配點(diǎn)少紋理弱/重疊低可視化匹配點(diǎn)增紋理/重拍/換匹配器點(diǎn)云扁平基線太短算三角化角度增大基線BA跑飛內(nèi)參耦合看焦距估計(jì)值固定內(nèi)參稠密空洞遮擋/弱紋理看深度圖增視角/調(diào)MVS參數(shù)重投影誤差大匹配有系統(tǒng)偏差看重投影殘差分布重新匹配/剔除離群點(diǎn)7. 工具鏈選型與實(shí)操建議7.1 COLMAP、OpenMVG、Meshroom怎么選三套主流工具各有適用場(chǎng)景COLMAP功能最全命令行GUI都有稀疏和稠密都支持文檔完善。雙視角SFM首選。缺點(diǎn)是參數(shù)多新手容易懵。OpenMVGOpenMVSOpenMVG做稀疏OpenMVS做稠密和網(wǎng)格。模塊化清晰適合想深入理解流程的人。配置稍麻煩。Meshroom節(jié)點(diǎn)式界面可視化好適合快速出結(jié)果。但雙視角下自動(dòng)化程度太高出問題不好排查。我的建議學(xué)習(xí)流程用COLMAP命令行每一步都能看到中間結(jié)果快速出結(jié)果用Meshroom想改算法用OpenMVG。7.2 COLMAP雙視角實(shí)操命令一個(gè)完整的COLMAP雙視角流程# 1. 特征提取 colmap feature_extractor \ --database_path ./database.db \ --image_path ./images \ --ImageReader.single_camera 1 \ --SiftExtraction.max_num_features 12000 \ --SiftExtraction.peak_threshold 0.006 # 2. 特征匹配 colmap exhaustive_matcher \ --database_path ./database.db \ --SiftMatching.guided_matching 1 \ --SiftMatching.max_ratio 0.8 # 3. 稀疏重建 colmap mapper \ --database_path ./database.db \ --image_path ./images \ --output_path ./sparse \ --Mapper.ba_refine_focal_length 0 \ --Mapper.ba_refine_principal_point 0 # 4. 去畸變可選 colmap image_undistorter \ --image_path ./images \ --input_path ./sparse/0 \ --output_path ./dense \ --output_type COLMAP # 5. 稠密重建 colmap patch_match_stereo \ --workspace_path ./dense \ --PatchMatchStereo.window_radius 7 \ --PatchMatchStereo.min_consistency 0.5 # 6. 深度圖融合 colmap stereo_fusion \ --workspace_path ./dense \ --output_path ./dense/fused.ply # 7. 網(wǎng)格重建 colmap poisson_mesher \ --input_path ./dense/fused.ply \ --output_path ./dense/meshed-poisson.ply \ --PoissonMeshing.depth 9幾個(gè)關(guān)鍵點(diǎn)single_camera 1表示兩張圖用同一個(gè)相機(jī)共享內(nèi)參ba_refine_focal_length 0固定焦距避免雙視角下跑飛guided_matching 1開啟引導(dǎo)匹配能提升匹配質(zhì)量。7.3 參數(shù)調(diào)整的經(jīng)驗(yàn)法則雙視角下參數(shù)調(diào)整有幾個(gè)原則特征提取寧多勿少反正后面會(huì)篩多提點(diǎn)沒壞處。匹配閾值寧松勿嚴(yán)雙視角匹配本來(lái)就少太嚴(yán)會(huì)剩不下。BA優(yōu)化寧少勿多固定內(nèi)參只優(yōu)化必要的量。稠密參數(shù)寧穩(wěn)勿精雙視角稠密質(zhì)量有限參數(shù)太激進(jìn)反而出更多噪聲。7.4 結(jié)果可視化的幾個(gè)工具重建完怎么檢查幾個(gè)工具COLMAP GUI直接看稀疏點(diǎn)云和相機(jī)位姿最方便。CloudCompare看稠密點(diǎn)云和網(wǎng)格測(cè)量、濾波、對(duì)比都行。Open3DPython里做點(diǎn)云處理和可視化適合寫腳本批量分析。MeshLab網(wǎng)格后處理和紋理檢查。我一般用COLMAP GUI看稀疏結(jié)果確認(rèn)位姿和點(diǎn)云沒問題再用CloudCompare看稠密結(jié)果最后用MeshLab檢查網(wǎng)格質(zhì)量。8. 雙視角SFM的進(jìn)階優(yōu)化思路8.1 引入額外約束提升尺度可觀測(cè)性雙視角SFM的尺度自由問題可以通過(guò)引入額外約束解決已知距離如果物體上有兩個(gè)點(diǎn)之間的真實(shí)距離已知可以據(jù)此恢復(fù)尺度。IMU輔助如果拍攝設(shè)備有IMU可以提供重力方向和加速度約束尺度。深度相機(jī)RGB-D相機(jī)直接提供深度尺度天然可觀測(cè)。這些約束在COLMAP里不能直接用需要自己寫代碼做后處理或者用支持這些約束的框架。8.2 用學(xué)習(xí)特征替換SIFT如果雙視角圖像紋理弱、外觀差異大SIFT匹配會(huì)崩。這時(shí)候可以換用SuperPoint SuperGlue學(xué)習(xí)特征學(xué)習(xí)匹配在弱紋理下表現(xiàn)好很多。LoFTR檢測(cè)器-free的稠密匹配適合低紋理場(chǎng)景。DISK學(xué)習(xí)特征對(duì)視角變化魯棒。這些方法可以和COLMAP結(jié)合用學(xué)習(xí)特征提取和匹配把匹配結(jié)果導(dǎo)入COLMAP做后續(xù)重建。COLMAP支持導(dǎo)入自定義匹配但需要轉(zhuǎn)成它認(rèn)識(shí)的格式。8.3 多視角擴(kuò)展從雙視角到小規(guī)模序列如果雙視角效果不理想最直接的改進(jìn)是多拍幾張。哪怕只多拍3到5張覆蓋不同角度重建質(zhì)量會(huì)有質(zhì)的提升。多視角下匹配冗余大誤匹配影響小。三角化角度分布更合理。稠密重建遮擋少空洞少。BA約束多位姿更準(zhǔn)。所以我的建議是如果條件允許永遠(yuǎn)不要只拍兩張。雙視角SFM更多是教學(xué)和理解流程用實(shí)際項(xiàng)目里至少拍一圈。8.4 后處理點(diǎn)云配準(zhǔn)與融合如果你有多個(gè)雙視角重建結(jié)果比如從不同角度拍了兩組可以把它們配準(zhǔn)融合每組各自做雙視角SFM得到局部點(diǎn)云。用ICP迭代最近點(diǎn)或特征配準(zhǔn)FPFHRANSAC對(duì)齊兩組點(diǎn)云。融合成完整模型。這一步在CloudCompare里可以手動(dòng)做也可以用Open3D寫腳本自動(dòng)做。配準(zhǔn)的關(guān)鍵是找到足夠的重疊區(qū)域否則ICP會(huì)收斂到錯(cuò)誤解。9. 我踩過(guò)的幾個(gè)真實(shí)坑9.1 自動(dòng)曝光毀掉匹配有一次拍兩組圖相機(jī)自動(dòng)曝光一張亮一張暗。SIFT匹配數(shù)量直接掉了一半RANSAC之后內(nèi)點(diǎn)率不到20%。后來(lái)鎖定曝光重拍匹配點(diǎn)翻了三倍。這個(gè)坑很隱蔽因?yàn)閮蓮垐D肉眼看著都正常但描述子對(duì)亮度變化敏感。9.2 廣角畸變導(dǎo)致BA跑飛用廣角鏡頭拍沒做去畸變直接跑COLMAP。結(jié)果BA把畸變系數(shù)和位姿一起優(yōu)化跑出了一個(gè)離譜的畸變模型點(diǎn)云扭曲成球面。后來(lái)提前用棋盤格標(biāo)定去畸變問題解決。雙視角下畸變和位姿耦合特別嚴(yán)重一定要提前處理。9.3 基線太短導(dǎo)致點(diǎn)云扁平有一次拍物體兩張圖相機(jī)幾乎沒動(dòng)就轉(zhuǎn)了個(gè)角度。重建出來(lái)的點(diǎn)云完全是平的深度信息幾乎沒有。算了一下三角化角度大部分點(diǎn)小于1度。這個(gè)坑的教訓(xùn)是雙視角SFM的基線不能省寧可多走兩步。9.4 稠密重建參數(shù)太激進(jìn)調(diào)MVS參數(shù)時(shí)把window_radius設(shè)得很大想多恢復(fù)一些點(diǎn)。結(jié)果噪聲點(diǎn)暴增點(diǎn)云里全是飛點(diǎn)。后來(lái)老老實(shí)實(shí)用默認(rèn)參數(shù)配合統(tǒng)計(jì)濾波效果反而更好。雙視角稠密重建穩(wěn)比多重要。9.5 忽略內(nèi)參固定導(dǎo)致重建不穩(wěn)定一開始沒固定內(nèi)參讓COLMAP自己優(yōu)化。兩張圖跑出來(lái)的焦距每次都不一樣重建結(jié)果也不可復(fù)現(xiàn)。后來(lái)固定內(nèi)參結(jié)果穩(wěn)定多了。雙視角下內(nèi)參優(yōu)化就是給自己找麻煩。10. 雙視角SFM的適用邊界與替代方案10.1 什么時(shí)候該用雙視角SFM雙視角SFM適合這些場(chǎng)景教學(xué)和理解流程兩張圖跑通全流程能看清每一步在干什么??焖僭万?yàn)證手頭只有兩張圖想快速看個(gè)大概形狀。紋理豐富、基線適中的物體條件好的話雙視角也能出不錯(cuò)的結(jié)果。作為多視角流程的調(diào)試子集先用兩張圖調(diào)通參數(shù)再擴(kuò)展到多視角。10.2 什么時(shí)候不該用雙視角SFM這些場(chǎng)景雙視角基本沒戲需要高精度測(cè)量雙視角精度有限尺度還不可觀測(cè)。弱紋理或反光物體匹配直接崩。大場(chǎng)景雙視角覆蓋不了。需要完整模型遮擋區(qū)域恢復(fù)不了。10.3 替代方案對(duì)比方案適用場(chǎng)景優(yōu)勢(shì)劣勢(shì)雙視角SFM教學(xué)、快速原型流程簡(jiǎn)單、快精度低、尺度自由、遮擋多多視角SFM一般重建精度高、完整需要多拍、流程長(zhǎng)結(jié)構(gòu)光高精度小物體精度極高需要專用設(shè)備激光掃描大場(chǎng)景高精度精度高、尺度準(zhǔn)設(shè)備貴、點(diǎn)云稀疏神經(jīng)輻射場(chǎng)新視角合成渲染質(zhì)量高需要多視角、訓(xùn)練慢雙視角SFM的定位很清楚它是理解三維重建的入門磚不是終點(diǎn)。把雙視角跑通了再擴(kuò)展到多視角、學(xué)習(xí)特征、神經(jīng)渲染路子就寬了。11. 寫在最后幾個(gè)實(shí)用建議雙視角SFM這個(gè)任務(wù)說(shuō)難不難說(shuō)簡(jiǎn)單也不簡(jiǎn)單。流程是固定的但每一步都有坑。我的經(jīng)驗(yàn)是把80%的精力花在數(shù)據(jù)采集和匹配上這兩步做好了后面基本順理成章這兩步做砸了后面怎么調(diào)參數(shù)都救不回來(lái)。具體來(lái)說(shuō)拍圖的時(shí)候鎖定曝光、保證重疊、留足基線預(yù)處理的時(shí)候去畸變、統(tǒng)一分辨率、做直方圖均衡匹配的時(shí)候多提特征、放寬閾值、開引導(dǎo)匹配重建的時(shí)候固定內(nèi)參、關(guān)注重投影誤差和內(nèi)點(diǎn)率。這幾條做到了雙視角SFM跑出個(gè)像樣的結(jié)果不難。另外別迷信自動(dòng)化工具的一鍵出結(jié)果。雙視角這種脆弱配置出問題是常態(tài)你得知道每一步在干什么才能定位問題。COLMAP的命令行雖然麻煩但中間結(jié)果都能看到排查起來(lái)比黑盒工具強(qiáng)得多。最后再分享一個(gè)小技巧如果雙視角重建效果不理想先別急著換工具或調(diào)參數(shù)把匹配點(diǎn)可視化出來(lái)看一眼。十有八九問題就寫在那些匹配線上。