sfm演算法是一種基於各種收集到的無序進行三維重建的離線演算法。在進行核心的演算法structure-from-motion之前需要一些準備工作,挑選出合適的。
首先從中提取焦距資訊(之後初始化ba需要),然後利用sift等特徵提取演算法去提取影象特徵,用kd-tree模型去計算兩張特徵點之間的歐式距離進行特徵點的匹配,從而找到特徵點匹配個數達到要求的影象對。對於每乙個影象匹配對,計算對極幾何,估計f矩陣並通過ransac演算法優化改善匹配對。這樣子如果有特徵點可以在這樣的匹配對中鏈式地傳遞下去,一直被檢測到,那麼就可以形成軌跡。
之後進入structure-from-motion部分,關鍵的第一步就是選擇好的影象對去初始化整個ba過程。首先對初始化選擇的兩幅進行第一次ba,然後迴圈新增新的進行新的ba,最後直到沒有可以繼續新增的合適的,ba結束。得到相機估計引數和場景幾何資訊,即稀疏的3d點雲。其中兩幅之間的bundle adjust用的是稀疏光束平差法sba軟體包,這是一種非線性最小二乘的優化目標函式演算法。
對於特徵檢測這一步,使用的是具有尺度和旋轉不變性的sift描述子,其魯棒性較強,適合用來提取尺度變換和旋轉角度的各種特徵點資訊,其準確性強,在這種離線演算法不需要考慮時間成本的情況下也較有優勢。sift演算法通過不同尺寸的高斯濾波器(dog)計算得到特徵點的位置資訊(x,y),同時還提供乙個描述子descriptor資訊,在乙個特徵點周圍4*4的方格直方圖中,每乙個直方圖包含8個bin的梯度方向,即得到乙個4*4*8=128維的特徵向量。除此之外,sift演算法計算得到的尺寸scale和方向orientation兩個資訊並沒有用上。
一旦每個的特徵點被提出來以後,就需要進行兩兩之間的特徵點匹配,用f (i)表示影象i周圍的特徵點。對於每乙個影象對i和j,考慮每乙個特徵f ∈ f (i)找到最近鄰的特徵向量fnn ∈ f (j):
事實上演算法中用到乙個kd-tree的資料結構去計算最近鄰匹配。然後令最近鄰的距離為d1,再找到第二近的匹配對點之間距離為d2,如果兩個距離d1和d2之比小於乙個閾值如0.6,就可以判定為可接受的匹配對。這樣子,影象i中的特徵點在影象j中至多乙個匹配特徵點,但是影象j中可能匹配影象i中多個特徵點,就會出現多對一的情況,實際上特徵點之間應該一一對應。所以還需要乙個去除重複特徵點匹配對的演算法去解決這種多對一的情況。最後如果兩個之間的特徵點匹配數不少於16個即為初選影象對。
然而初選的匹配對可能還是不可靠,需要用幾何約束去檢測。這個測試是基於事實的,假設乙個靜止場景,不是所有的匹配特徵點在實際場景中是符合物理規律的。那麼就需要計算對極幾何,f矩陣可以把兩張之間的畫素座標聯絡起來,幷包含相機的內參資訊。每乙個符合的匹配對畫素座標都需要滿足:
像這種f矩陣計算出有很多雜訊資料,需要用ransac(隨機抽樣一致性)演算法進行濾波,用8點法來進行ransaca假設,其中外點個數的閾值應該小於影象長與寬的0.6%。
當所有的兩兩匹配影象對被確定以後,就可以考慮把多個影象中都出現的共同特徵匹配點連線起來,就能形成軌跡了。例如,特徵f1 ∈ f (i1)匹配特徵f2 ∈ f (i2),f2匹配特徵f3 ∈ f (i3) ,這些特徵就可以形成乙個軌跡。然後利用寬度優先搜尋bfs去找到每個特徵點在所有影象對中的完整軌跡。
一旦符合的軌跡都找到後,就構造影象連線圖,包含每個影象的節點,和有共同軌跡的影象邊緣。
描述攝像機的外引數用到3*3的旋轉矩陣r和1*3的平移向量(或者攝像機中心座標向量),攝像機的內引數用乙個焦距f和兩個徑向畸變引數k1和k2描述。幾何場景提供軌跡中的每個3d點xj,通過投影方程,乙個3d點xj被投影到攝像機的2d影象平面上。投影誤差就是投影點和影象上真實點之間的距離。如下圖:
對於n個視角和m個軌跡,投影誤差的目標優化方程可以寫為:
當攝像機i觀察到軌跡j的時候wij取1,反之取0,||qij - p (ci, xj)||就是攝像機i中的軌跡j的投影誤差累積和。sfm演算法的目標就是找到合適的相機和場景引數去優化這個目標函式,g是採用乙個非線性最小二乘的優化方法求解,著名的有光束平差法bundle adjustment.
首先選擇合適的初始化影象對,這十分重要,一旦錯誤的初始化,將會陷入區域性最優而使得之後的ba陷入死迴圈,無法正確求解得到全域性最優。具體有兩點要求:第一,要有足夠多的匹配點;第二,要有足夠遠的相機中心。
特別的,在這裡用到兩個影象變換之間的單應性模型來找初始化影象對。如果不能很好的符合單應性模型,說明相機中心還是有一定距離的。同樣採用ransac方法來降噪,改善匹配的可靠性,盡量選取低的內點百分比,但是至少保證100個匹配內點。
系統採用5點法來估計初始化匹配對的外參,然後軌跡三角化後可以提供初始化的3d點,初始化的兩幀就可以開始進行第一次bundle adjustment了。在這裡用的是稀疏光束平差法sparse bundle adjustment(sba)。
最後,不斷新增新的攝像機和3d點進行ba。這個過程直到剩下的攝像機觀察到的點不超過20為止,說明剩下的攝像機沒有足夠的點可以新增,ba結束。得到相機估計引數和場景幾何資訊,即稀疏的3d點雲。
大規模SfM的Cut Expand
expand 判斷cluster的大小。若cluster的image的數目足夠小,不進行任何操作,返回cluster cluster的大小可以進行cut,對cluster進行normalized cut,返回每個image及其所屬的cluster id 將image分配到clustered的chil...
日常小結 opencv3 sfm
opencv3中間新增了額外的sfm模組。但是新版本還是有很多問題這裡說下配置。先貼幾個 首先opencv的就從官網下就完了 其次擴充套件包從github下 然後就是編譯安裝就行。如果要執行sfm的demo。viz需要先安裝。這裡提供幾個編譯選項 mkdir build cd build camke...
OpenCV實現SfM(一) 相機模型
注意 本文中的 必須使用opencv3.0或以上版本進行編譯,因為很多函式是3.0以後才加入的。目錄 sfm介紹 sfm的全稱為structure from motion,即通過相機的移動來確定目標的空間和幾何關係,是三維重建的一種常見方法。它與kinect這種3d攝像頭最大的不同在於,它只需要普通...