JOVANA
Library Glossary Getting Started Three Levels Fields How it works Mission
Join the mission
All guides

恢復深度:立體視覺、點雲與三維重建

兩隻眼睛(或一台移動的相機)如何找回平面照片丟掉的第三個維度,把影像變成可測量的三維形狀。

照片丟掉的那個維度

相機把豐富的三維世界壓扁成平面的二維影像。鏡頭前的每一個點都落在一個像素上,而 針孔相機模型 精確地告訴我們這是怎麼發生的:一個三維點沿著穿過鏡頭的光線,投影到像平面上。但這種投影是一條單行道。一旦一個點變成了像素,相機就忘記了它有多遠。你桌上的一隻咖啡杯,和房間另一頭一隻一模一樣的杯子,可能產生完全相同的像素——深度,正是平面照片悄悄丟棄的資訊。

對機器人來說,這個缺失的數字就是一切。要抓住杯子、繞過桌子或避開牆壁,機器人需要的是真實單位的距離——公尺,而不是像素。深度感知的全部工作,就是*把第三個維度找回來*。讓這一切成為可能的訣竅優雅而簡單:從兩個略有差異的視角觀察同一個場景,再比較各自看到了什麼。

立體視覺:兩隻眼睛,一個三角形

立體視覺 用兩台相隔固定距離的相機來模仿那個眨眼的把戲,這段固定距離叫作*基線*。每台相機都從自己的視角拍下場景。由於視角不同,同一個真實世界中的點,在左圖和右圖中會落在不同的水平位置上。這種以像素為單位測量的左右位移,叫作視差——它正是 深度估計 的核心。

這種關係非常直接:視差大意味著近,視差小意味著遠。正前方的一個點,在兩個視角間位移很大;地平線上的一座山,則幾乎不動。如果你知道基線和相機的焦距(來自 相機標定),一條簡短的公式就能把視差直接換算成距離。兩台相機和場景中的點構成一個三角形,我們解出它的深度——這就是為什麼這叫作*三角測量*。

depth Z = (focal_length f  ×  baseline B) / disparity d

   big disparity d   ->  small Z  (object is near)
   small disparity d  ->  large Z  (object is far)
立體深度公式:一旦求出某個像素的視差 d,深度便隨之而來。

難的部分是*匹配*:對於左圖中的一個像素,右圖中哪個像素才是同一個真實點?這和你用 特徵描述子 匹配 影像關鍵點 時遇到的對應問題是同一個,但立體視覺有一個很大的捷徑。標定之後,匹配像素總是位於另一幅影像中的同一條水平線上,於是搜尋範圍從整幅二維影像縮小到了一行。純色的牆面和光亮的表面仍然會帶來麻煩——沒有紋理可供匹配,視差就只能靠猜。

從深度到點雲

一旦每個像素都有了深度,我們就能把平面影像從螢幕上抬起來,送回到空間中去。取每個像素在影像中的位置,附上它測得的距離,再用標定好的相機模型,算出這個點在三維空間中真正所處的位置。對整幅影像都這樣做,你就得到了一片 點雲:成千上萬乃至數百萬個微小的 (x, y, z) 點,漂浮在機器人的座標系裡,每個點往往還帶著顏色。它就是感知輸出的原始、無結構的三維資料。

點雲很強大,但也很雜亂。它沒有物體或表面的概念——只有一堆點。於是機器人要做進一步的處理:把鄰近的點聚成物體,擬合平面以找出桌面和地板,或者把從不同角度採集的多片點雲縫合成一片。對齊兩片有重疊的點雲,正是 疊代最近點(ICP) 的工作,它不斷微調一片點雲,直到它的點盡可能貼合到另一片之上。

當你把許多視角融合成一個乾淨的單一表面時,就從原始點跨入了 三維重建 ——把點雲變成一個不漏水的網格,或一個整潔的模型,可供你測量、列印,或放進模擬器。點雲還為下游任務提供輸入,例如 六自由度物體位姿估計:機器人把一個已知物體的形狀擬合到這些點上,從而在抓取之前精確弄清它的位置和朝向。

一台移動的相機:運動恢復結構

其實你並不需要兩台相機。一台*移動*的相機,隨著時間從許多視角看到了場景——而第 1 幀和第 10 幀之間的間隔,作用就像一條立體基線。運動恢復結構(SfM)正是利用了這一點。它在一連串影像中追蹤同樣的特徵,並根據這些特徵如何在幀間滑動,一舉解開一個了不起的雙重謎題:場景的三維形狀,*以及*相機為拍下它而走過的路徑

  1. 在每一幀中偵測特徵,並跨幀匹配它們,追蹤每個特徵如何移動——這與 光流(影像間逐像素的運動)密切相關。
  2. 根據匹配到的運動,估計相機在各視角之間是如何移動的(即它不斷變化的位姿)。
  3. 在兩個或更多已知相機位姿之間,對每個被追蹤的特徵做三角測量,把它定位到三維空間,從而構建出一片稀疏點雲。
  4. 把每一個相機位姿和每一個三維點放在一起聯合最佳化(光束法平差),使整個重建結果保持一致。

如果逐幀即時地執行它,SfM 就成了機器人在一邊給世界建圖、一邊推斷自身位置時的視覺骨幹。把相機和慣性感測器配在一起,你就得到了 視覺慣性里程計:來自視覺和來自慣性單元的運動估計互相印證,對機器人身在何處、周圍一切位於何方,給出更穩定的估計。

深度會在哪裡出錯

恢復出來的深度從來都不是完美的,有兩個陷阱反覆出現。第一個是尺度不確定性。一台單獨移動的相機,可以恢復出場景的*形狀*和自身路徑的*形狀*——但恢復不出它們真實的大小。近距離拍攝的一列小火車模型,看起來和遠距離拍攝的一列真火車一模一樣。SfM 重建出的世界差著一個未知的尺度因子;沒有外部幫助,它無法告訴你一道門是一公尺寬,還是一百公尺寬。

解決辦法是餵進一個真實的測量值:來自立體裝置的已知基線、能感知真實加速度的慣性感測器、輪式里程計,或者一個已知尺寸的標定物。這其中任何一個,都能把那個懸浮的重建釘到真實的公尺上。這正是為什麼第二台相機或一個 IMU 物有所值——它鎖定了單憑視覺無法確定的那個尺度。

第二個陷阱是深度雜訊。在純色牆面、玻璃、鏡子和陰影處——這些沒有東西可供匹配的地方——視差變得不可靠。遠處的點尤其脆弱:在遠距離上,一個極小的視差誤差會變成一個巨大的距離誤差,所以你看得越遠,深度就越模糊。好的機器人把深度當作一個帶有不確定性的測量值來對待,而不是金科玉律——它們對深度做濾波、與其他感測器融合,並且對近處的讀數遠比對遠處的讀數更信任。