當我們有錯誤的匹配點怎麼辦呢?要如何找到正確的八個點來計算 Essential Matrix 呢?這時候就需要用到 Random sample consensus (RANSAC) 算法。
最暴力解法就會是,嘗試所有的組合並找到最好的八個點計算Essential Matrix,假設我們有 1000 個特徵點,我們就有 C(1000, 8)
種組合,這個數字實在太大,所以我們需要一個更有效率的方法。
當然也可以直接把所有的匹配放進 Ax = 0
的方程式中直接解出 E,但這麼做很容易被 outlier 影響,因此我們需要一個更穩健的方法。
我們可以把所有的特徵點匹配,想像成在一個袋子裡面裝了很多球,每次我們就從這個袋子裡面隨機抽八顆球,可以計算出一個 Essential Matrix,然後我們可以計算這個 Essential Matrix 對所有的特徵點的誤差,統計小於某個閥值的點的數量,並且把它記錄下來,把球放回去,一直重複這個過程。
最大票數 = 0
最好的 Essential Matrix = None
for N 次:
隨機抽取 8 個特徵點
計算 Essential Matrix
計算所有特徵點的誤差,並計算 inlier 的數量
if inlier 的數量 > 最大票數:
最大票數 = inlier 的數量
最好的 Essential Matrix = 當前的 Essential Matrix
由於每次抽取式隨機的,只要我們重複這個過程很多次,最後我們就可以找到一個相對準確的 Essential Matrix,它不一定是最好的,但這個 Essential Matrix 是得到最多匹配點同意的(類似投票的的概念)。
假設我們知道 outlier 與 inlier 的比例,我們甚至能夠計算出我們需要多少次的抽樣才能得到一個我們信心水準足夠的 Essential Matrix(機率與統計的 Bernoulli distribution)。
在先前的實作中 cv2.findEssentialMat
已經幫我們做了這個事情:
E, mask = cv2.findEssentialMat(
points1, points2, focal=fx, pp=(cx, cy),
method=cv2.RANSAC, prob=0.999, threshold=1.0
)
prob
代表的是我們要的信心水準,設定越高的信心水準代表的是需要更多的迭代次數(需要更多次的抽樣),而 threshold
代表的則是誤差閥值,得到一個 Essential Matrix 後,所有的匹配點中,哪些點是 inlier,哪些點是 outlier,值約低代表標準越嚴格。
這個方法非常的通用,不只是在計算相機姿態時被使用,也有很多其他的應用,例如在給定一些 3D 空間中的點(存在部分的 outlier),找到一個最適合的直線、平面等等。