1. 程式人生 > >一天建成羅馬 translated from 《building Rome in a Day》

一天建成羅馬 translated from 《building Rome in a Day》

2.系統設計

我們的系統在一組計算機(節點)上執行,其中一個節點被指定為主節點。 主節點負責各種作業排程決策。

在本節中,我們描述了系統的詳細設計,它可以自然分為三個不同的階段:(1)預處理§2.1,(2)匹配§2.2和(3)幾何估計§2.4。

2.1 預處理和特徵提取

我們假設這些影象在中央商店中可用,並以固定大小的塊為單位按需將其分發到群集節點。這會自動執行負載平衡,更強大的節點接收更多影象進行處理。

這是唯一需要中央檔案伺服器的階段。系統的其餘部分在不使用共享儲存的情況下執行。這樣做是為了使我們能夠獨立於我們的匹配和重建實驗從網際網路上下載影象。對於生產用途而言,可以在匹配和重建過程開始時,讓每個群集節點都可以直接抓取Internet上的影象。

在每個節點上,我們首先驗證影象檔案是否可讀,有效的影象。然後,我們提取EXIF標籤(如果存在),並記錄焦距。我們還對大於200萬畫素的影象進行縮減取樣,保留它們的縱橫比並縮放它們的焦距。影象然後轉換為灰度,並從中提取SIFT特徵[10]。由於Andrea Vedaldi的SIFT ++演算法的的速度和靈活的介面[20],我們採用了此演算法。在這個階段結束時,整組影象被分割成不相交的集合,每個節點一個。每個節點都擁有與其分割槽關聯的影象和SIFT特徵。

2.2 影象匹配

匹配兩幅影象時的關鍵計算任務是利用興趣點的光度匹配和使用基本矩陣和本質矩陣的魯棒性估計對這些匹配進行幾何校驗。但是兩幅影象之間所有特徵的詳盡匹配過於昂貴,然而用近似相鄰搜尋取得的出色的結果已經有所報導。我們使用ANN庫[3]來匹配SIFT特徵。對於每一對影象,將其中一個影象的特徵插入到k-d樹中,並將來自另一個影象的特徵用作查詢。對於每個查詢,我們考慮最近的兩個鄰居,其中通過Lowe的比率測試的配對影象被接受[10]。我們使用基於優先順序佇列的搜尋方法,最大訪問次數為200次。在我們的實踐中,這些引數在計算成本和匹配精度之間提供了良好的折中。然後,根據EXIF標籤中焦距資訊的可用性,使用基於RANSAC的基本矩陣或本質矩陣[18]估算修正並驗證近似近鄰搜尋所得的匹配。

這兩個操作構成了我們匹配引擎的計算核心。

不幸的是,即使對上述匹配過程進行了優化實施,匹配集合中所有影象對也是不現實的。對於10萬張影象的集合來說,可以轉化為5,000,000,000兩兩比較,在這樣的情況下即使使用500個核心以每個核心每秒10個影象的速度執行也需要約11.5天才能匹配。進一步來說,這還沒有考慮所有核心都需要訪問所有影象的所有SIFT特徵資料的網路傳輸。

即使我們能夠進行所有這些配對匹配,這也會浪費計算量,因為絕大多數影象對不匹配。這是從一組與城市名稱這樣的廣泛標籤相關聯的影象中預期的。因此,我們必須小心選擇系統花費時間匹配的影象對。

基於最近的有效目標檢測工作[15,11,5,13],我們使用多階段匹配方案。每個階段都包含一個提案步驟和一個驗證步驟。在提案步驟中,系統確定一組影象對,預計它們將共享常見的場景元素。在驗證步驟中,對這些影象對執行詳細的特徵匹配。以這種方式獲得的匹配然後通知下一個建議步驟。

在我們的系統中,我們使用兩種方法來生成提案:基於詞彙樹的整體影象相似度§2.2.1和拓展查詢§2.2.4。驗證階段在§2.2.2中描述。圖1顯示了整個匹配流程的系統圖。

2.2.1詞彙樹提案

受文字檢索啟發的方法已經在物件和影象檢索問題上取得了巨大的成功。這些方法基於將影象以文字包的形式再現,其中文字是通過量化影象特徵而獲得的。我們使用基於詞彙樹的方法[11],其中使用分層k-均值樹來量化特徵描述符。 (關於如何使用測試影象的小集合建立詞彙樹的細節,請參閱第3節)。這些量化指標被聚合到影象中的所有特徵上以獲得影象的詞頻(TF)向量,以及文件頻率( DF)向量用於影象的集合(圖1a-e)。文件頻率向量跨節點聚整合單個向量,並在整個叢集中傳播。每個節點對它擁有的術語頻率向量進行歸一化處理,以獲得該節點的TFIDF矩陣。這些每個節點的TFIDF矩陣通過網路傳播,以便每個節點可以計算其TFIDF向量與其餘TFIDF向量之間的內積。實際上,這是TFIDF向量矩陣與其自身的分散式乘積,但每個節點只計算塊

的行相對應的一組影象。 對於每幅影象,確定最高得分的k1 + k2影象,其中第一張k1影象用於初始驗證階段,另外的k2影象用於放大連線成分(見下文)。

我們的系統與Nister和Stewenius [11]的系統不同,因為他們的系統有一個固定的資料庫,它們匹配傳入的影象。 因此,他們可以將資料庫儲存在詞彙樹本身中,並評估影象的匹配分數。 在我們的例子中,查詢集與資料庫相同,並且在功能編碼時不可用。 因此,我們必須有一個單獨的矩陣乘法階段來找到最匹配的影象。

2.2.2 驗證和詳細匹配

下一步是驗證候選影象匹配,然後找到匹配影象之間的一組詳細匹配。如果影象全部位於單個機器上,驗證提出的匹配影象對的任務將是通過影象對執行的簡單問題,可能需要注意驗證次序的執行次序,以便儘量減少磁碟I / O。但是,在我們的案例中,影象及其特徵描述符分佈在整個群集中。因此,要求節點匹配影象對(i,j)需要它從叢集的其他兩個節點獲取影象特徵。這是不可取的,因為網路傳輸速度和本地磁碟傳輸之間存在很大差異。此外,這為三個節點建立工作。因此,影象對應該以一種尊重資料區域性性的方式在整個網路上分佈,並儘量減少網路傳輸量(圖1f-g)。

我們用一些方法進行了實驗,結果令人驚訝。我們最初試圖在任何驗證完成之前優化網路傳輸。在這種設定中,一旦主節點具有需要驗證的所有影象對,它就會建立一個連線共享影象的影象對的圖形。使用MeTiS [7],該圖被分割成與計算節點一樣多的塊。然後通過解決線性分配問題來將分割槽與計算節點相匹配,從而最大限度地減少向每個節點發送所需檔案所需的網路傳輸數量。

這個演算法適用於小問題大小,但隨著問題規模的增加,其效能會下降。我們假設所有影象對之間的詳細匹配採用相同的恆定時間是錯誤的:一些節點提前完成並且閒置長達一個小時。

我們嘗試的第二個想法是將圖形過度分割成小塊,並按需將它們分組到群集節點。當一個節點請求另一塊工作時,網路傳輸最少的塊被分配給它。這個策略實現了更好的負載平衡,但是規模更大問題越來越大,我們需要劃分的圖形變得非常龐大,分割槽本身成為瓶頸。

給出最佳結果的方法是使用簡單的貪心bin-packing演算法(其中每個bin表示傳送到節點的作業集),其工作方式如下。主節點維護每個節點上的影象列表。當一個節點要求工作時,它會遍歷可用映像對列表,如果它們不需要任何網路傳輸,則將它們新增到該映像對中,直到該映像對已滿或者不再有要新增的映像對為止。然後,它選擇一個影象(特徵向量列表)以傳送到節點,選擇影象以允許它將最大數量的影象對新增到該箱中。重複此過程,直到箱滿。該演算法有一個缺點:它可能需要多次掃描所有需要匹配的影象對。對於大問題,工作計劃可能成為瓶頸。一個簡單的解決方案是一次只考慮一部分工作,而不是試圖全域性優化。這種視窗化的方法在實踐中效果很好,我們所有的實驗都是用這種方法執行的。

驗證影象對是一個兩步過程,包括特徵描述符之間的光度匹配,以及根據相機校準資訊的可用性對基本或基本矩陣進行的穩健估計。在基本矩陣的估計成功的情況下,兩個攝像機的觀察方向之間存在足夠的角度,並且匹配的數量超過閾值,則我們進行完整的歐幾里得兩視角重建並存儲它。這些資訊用於後期(見§2.4),以減少重建問題的規模。

2.2.3 連線關聯元件

在這個階段,如果在它們之間找到匹配的特徵,考慮在邊緣連線兩個影象的一組影象上的圖。我們稱之為匹配圖。為了獲得儘可能全面的重構,我們需要此圖中連線元件的數量最少。為此,我們進一步使用詞彙樹中的提案嘗試連線此圖中的各種連線元件。對於每個影象,我們考慮由詞彙樹建議的下一個k2影象。從這些,我們驗證跨越兩個不同連線元件的影象對(圖1h-i)。我們僅對尺寸為2或更大的影象進行此操作。因此,有效地丟棄了不匹配其頂部k1個提議的匹配中的任何一個的影象。同樣,得到的影象對需要進行詳細的特徵匹配。圖2說明了這一點。請注意,在第一輪之後,匹配圖有兩個連線的元件,它們在第二輪匹配後連線。

2.2.4拓展查詢

在如上所述進行了兩輪匹配之後,我們有一個匹配圖,通常密度不足以可靠地產生良好的重建。為了彌補這一點,我們使用文字和文件檢索研究中的另一個想法 - 查詢擴充套件[5]。

在最簡單的形式中,查詢擴充套件是通過首先查詢與使用者查詢匹配的文件,然後使用它們再次查詢資料庫來完成的,從而擴充套件了初始查詢。系統返回的結果是這兩個查詢的組合。實質上,如果我們要在文件集上定義一個圖形,並通過邊連線相似的文件,並將查詢視為文件,則查詢擴充套件相當於查詢查詢兩個步驟內的所有頂點頂點。

在我們的系統中,我們考慮影象匹配圖,其中影象i和j如果它們具有共同的特徵的最小數目特徵,則連線。現在,如果影象i連線到影象j並且影象j連線到影象k,我們執行詳細的匹配以檢查影象j是否匹配影象k。這個過程可以重複固定的次數,或者直到匹配圖收斂。

迭代迴圈查詢擴充套件時需要注意的一點是漂移。輔助查詢的結果可能會迅速偏離原始查詢。這在我們的系統中不是問題,因為查詢擴充套件影象對在匹配圖中的邊緣連線之前需要經過詳細的幾何驗證。

2.3 初代追蹤

匹配過程的最後一步是將所有成對匹配資訊組合起來,以便在影象之間生成一致的軌跡,即在單個特徵匹配圖(特徵圖)中查詢和標記所有連線的元件。由於匹配資訊本地儲存在計算節點上,軌道生成過程分兩個階段進行(圖1k-m)。首先,每個節點根據本地可用的所有匹配資料生成軌道。這些資料收集在主節點上,然後通過網路廣播到所有節點。觀察匹配圖中每個連線元件的軌跡可以獨立處理。軌道生成隨後繼續為每個計算節點分配一個需要生成軌道的連線元件。當我們基於共享特徵合併軌道時,可以生成不一致軌道,其中同一影象中的兩個特徵點屬於同一軌道。在這種情況下,我們會放棄賽道上的違規點。

一旦生成了軌道,下一步就是從相應的影象特徵檔案中提取軌道中出現的特徵點的二維座標。我們還為每個這樣的特徵點提取畫素顏色,稍後將其用於渲染具有平均值的3D點與其關聯的特徵點的顏色。 再次,這個過程分兩步進行。 給定每個分量的軌跡,每個節點從SIFT和它擁有的影象檔案中提取特徵點座標和點顏色。 這些資料是通過網路收集和廣播的,在每個連線元件的基礎上進行處理。

2.4 物理估計

一旦軌跡生成後,下一步是在匹配圖的每個連線元件上執行結構運動(SfM),以恢復每個相機的姿態和每個軌道的3D位置。大多數用於無序照片集的SfM系統是漸進式的,首先是一個小的重建,然後一次生成幾張影象,三角化新的點,並進行一輪或多輪非線性最小二乘優化(稱為束調整[19]),以儘量減少重投影誤差。重複此過程,直到不再新增攝像機。但是,由於我們收藏的規模,對所有照片一次採用這種漸進方式是不切實際的。上述增量重建過程中隱含著假設,即所有影象對重建的覆蓋範圍和準確度的影響差不多。網際網路照片收集本質上是多餘的 - 很多照片是從附近的角度拍攝的,處理所有這些照片並不一定會增加重建。因此,最好找到並重建拍攝匹配圖和場景幾何圖形的基本連通性的照片的最小子集[8,17]。完成此操作後,我們可以使用姿態估計重新新增剩餘的所有影象,對所有剩餘的點進行三角測量,然後做一個最終包調整以改善SfM估計。

為了找到這個最小集合,我們使用[17]的骨架集合演算法,該演算法計算一組跨度的影象集,保留影象圖中重要的連通性資訊(例如大型迴圈)。在[17]中,為每對具有已知焦距的匹配影象計算兩幀重建。在我們的系統中,這些成對重建是作為並行匹配的一部分計算的處理。 一旦計算了骨架集,我們就使用增量演算法[16]來估計每個結果元件的SfM引數。 骨架集演算法通常在弱連線邊界上分解連線的元件,從而產生更大的元件集合。

2.4.1 束調整

將SFM問題的規模縮小到骨架集後,重構過程中的主要瓶頸是重投影誤差或束調整(BA)的非線性最小化。公開發布的效能最好的BA軟體是由Lourakis&Argyros [9]提供的Sparse Bundle Adjustment(SBA)。其高效能的關鍵在於使用所謂的Schur補充技巧[19]來減小Levenberg-Marquardt每次迭代需要解決的線性系統的大小(也稱為正規方程) (LM)演算法。該線性系統的大小取決於3D點和相機引數,而Schur補充的大小僅取決於相機引數。然後,SBA使用密集的Cholesky因式分解和解決由此導致的線性系統降低。由於典型的SfM問題中3D點的數量通常比相機數量多兩個數量級或更多,因此會帶來相當大的節省。這適用於小到中等大小的問題,但對於包含數千個影象的大型問題,計算Schur補充的密集Cholesky分解會成為時空瓶頸。然而,對於大問題,Schur補充本身相當稀疏(通常只有少數相機才能看到3D點),利用這種稀疏性可以節省大量的時間和空間。

我們開發了一種新的高效能捆綁調整軟體,根據問題的大小,在截斷的LM演算法和精確的LM演算法之間進行選擇。在第一種情況下,塊對角線預條件共軛梯度法用於近似求解法向方程。在第二種情況下,CHOLMOD [4]是一種用於計算Cholesky分解的稀疏直接方法,用於通過Schur補充來精確求解法方程技巧。 第一種演算法每次迭代的時間複雜度較低,但使用更多的LM迭代,而第二種演算法以每次迭代更多的時間和記憶體為代價收斂得更快。 由此產生的程式碼比SBA使用的記憶體少得多,執行速度快了一個數量級。 確切的執行時間和記憶體節省取決於所涉及的線性系統的稀疏結構。

2.5 分散式計算引擎

我們的匹配和重建演算法被實現為一個雙層系統。該系統的基礎是一個應用激情分散式計算引擎。除了易於移植的小型核心之外,該系統是跨平臺的,可執行在UNIX和Microsoft Windows的所有主流平臺上。該系統體積小且可擴充套件,並且配備了多種排程策略和資料傳輸原語,使用者可自由新增自己的。

該系統針對批量處理大量資料的應用程式。它廣泛支援本地應用程式資料快取以及通過網路按需傳輸資料。如果共享檔案系統可用,則可以使用該檔案系統,但為了獲得最佳效能,所有資料都儲存在本地磁碟上,並且只在需要時通過網路傳輸。它支援各種排程模型,從簡單的資料並行任務到一般的map-reduce樣式計算。分散式計算引擎被編寫為一組Python指令碼,每個計算階段都被實現為Python和C ++程式碼的組合。