opencv的單應矩陣相機標定

給定同一相機在不同角度拍攝的不同照片,如何標定計算機的內參(焦距、主點)、外參(主要是旋轉矩陣)?

opencv的圖片拼接demo stitching_detailed中有示例

主要過程:

1.surf /orb算法查找兩個圖片的特徵點;

2.匹配兩個圖片的特徵點,匹配過程中使用RANSAC算法計算單應矩陣;

3.根據單應矩陣計算焦距;

4.根據單應矩陣、焦距等參數計算旋轉矩陣;

5.計算主點.

1.單應矩陣計算

單應矩陣是在匹配特徵點的過程中得到的

BestOf2NearestMatcher::match->cvFindHomography->runRANSAC
關鍵過程:
1)cvConvertPointsHomogeneous
二維座標轉齊次座標,方便計算H矩陣,這裏只是做了簡單的行列轉換,並增加了一列。
2)estimator.runRANSAC
運行RANSAC算法,目標是找到兩福圖像特徵點之間的映射關係,也就是單應矩陣H,
基本原理:
從兩幅圖像的特徵點中隨機找到4對不同的特徵點,每對特徵點齊次座標對記爲(p1,p2),然後計算矩陣方程的p1=H*p2解,也就是H的估計值,然後把所有特徵點代入,記錄每次得到的內點(也就是符合解的點)的數量,
迭代若干次(初始2000次,根據RANSAC算法會指數性減少),每次都記錄內點數最多的解,最終將內點最多的解作爲單應矩陣H的最優解。
關鍵過程:
<1> CvModelEstimator2::getSubset 從輸入的特徵點中獲取隨機4對特徵點,這些特徵點要滿足在各自圖像上不能在同一直線(否則方程可能無法求解),爲找到這些點需要迭代最多300次,調用checkSubset檢查直線;
<2> CvHomographyEstimator::runKernel 求解4對特徵點構成的8個方程組,得到一次H矩陣的解,H矩陣是3×3矩陣,歸一化後剩餘8個未知數,一對特徵點產生兩個方程,所以需要4個特徵點對產生8個方程
<3> CvModelEstimator2::findInliers 根據得到的H估計解,代入所有特徵點,計算內點,返回內點數、內點mask等,之後會根據每次返回的最大內點數,確定H的最優解;
<4> cvRANSACUpdateNumIters 通過置信度、當前解的內點數等參數更新需要迭代的次數,會從初始的2000次指數性降低。


之後opencv會對返回的內點mask將原來兩幅圖的特徵點放入返回的MatchesInfo結構中,並且再次對這些內點計算其單應矩陣,作爲最終的H矩陣。
BestOf2NearestMatcher::match

2.根據單應矩陣估計內參:焦距

HomographyBasedEstimator::estimate->estimateFocal->focalsFromHomography
直接用公式根據H矩陣計算得到焦距。
原理:
參考《Construction of Panoramic Image Mosaics with Global and Local Alignment.pdf》第3.2節以及第5節
基本解釋:
同一個空間點P(x,y,z)在兩個圖像上的點分別爲P1(x1,y1),P2(x2,y2),根據相機座標系和世界座標系變換公式:P1=K1*R1*P,P2=K2*R2*P,其中Ki,Ri分別爲兩個圖像對應的相機的內參和旋轉矩陣,
由於空間P是同一個點,那麼P1=K1*R1*R2的逆*K2的逆*P2=K1*R12*K2的逆*P2,已知P1P2的單應矩陣H(通過RANSAC算法求出),那麼H=K1*R12*K2的逆,Ki作爲內參主要有焦距和主點,主點可以忽略,
R12爲圖像1到圖像2的旋轉矩陣,那麼H矩陣中只包含旋轉矩陣和焦距參數,根據旋轉矩陣的正交性,可以求解得到焦距,使焦距成爲H矩陣各個元素的表達式,從而求得焦距的估計值。
opencv對每幅圖像求一個焦距然後取其中間值作爲warp球體的半徑。

3.計算外參:旋轉矩陣

在HomographyBasedEstimator::estimate中除了估算焦距之外,還估算了旋轉矩陣:
    findMaxSpanningTree(num_images, pairwise_matches, span_tree, span_tree_centers); 
    span_tree.walkBreadthFirst(span_tree_centers[0], CalcRotation(num_images, pairwise_matches, cameras));
findMaxSpanningTree:
由於可能輸入多個圖像,產生了多個匹配特徵點的MatchesInfo結構,每個MatchesInfo包含兩幅圖像之間匹配的特徵點(內點)以及H矩陣,需要確定這些圖像之間的鄰接關係,
這裏以兩幅圖像之間的內點數量爲權值構建最大生成樹,保證這樣的一個圖片序列兩兩之間的內點數最多,也就最有可能是鄰接的;
span_tree.walkBreadthFirst:
用廣度優先遍歷這棵最大生成樹,分別計算每兩個鄰接圖像(也就是每個相機)的旋轉矩陣R。
原理:

根據上面的公式:H=K1*R12*K2的逆,R12=K1的逆*H*K2,R1=R2*R12=R2*K1的逆*H*K2,已知上幅圖像的R、兩個相機的內參Ki(焦距、主點)、兩幅圖的單應矩陣H,可以求得下幅圖的R。

4.計算內參:主點

簡單設置爲圖像的中心位置

發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章