Homography 理解本文轉(zhuǎn)自:http://m.blog.csdn.net/blog/xuluhui123/17115073
在計算機(jī)視覺中,平面的單應(yīng)性被定義為一個平面到另外一個平面的投影映射。因此一個二維平面上的點映射到攝像機(jī)成像儀上的映射就是平面單應(yīng)性的例子。如果點Q到成像儀上的點q的映射使用齊次坐標(biāo),這種映射可以用矩陣相乘的方式表示。若有一下定義:
則可以將單應(yīng)性簡單的表示為:
這里引入?yún)?shù)s,它是任意尺度的比例(目的是使得單應(yīng)性定義到該尺度比例)。通常根據(jù)習(xí)慣放在H的外面。
H有兩部分組成:用于定位觀察的物體平面的物理變換和使用攝像機(jī)內(nèi)參數(shù)矩陣的投影。
物理變換部分是與觀測到的圖像平面相關(guān)的部分旋轉(zhuǎn)R和部分平移t的影響之和,表示如下
這里R為33大小的矩陣,t表示一個一個3維的列矢量。
攝像機(jī)內(nèi)參數(shù)矩陣用M表示,那么我們重寫單應(yīng)性如下:
我們知道單應(yīng)性研究的是一個平面上到另外一個平面的映射,那么上述公式中的Q,就可以簡化為平面坐標(biāo)中的Q',即我們使Z=0。即物體平面上的點我們用x,y表示,相機(jī)平面上的點,我們也是用二維點表示。我們?nèi)サ袅薢方向的坐標(biāo),那么相對于旋轉(zhuǎn)矩陣R,R可以分解為R=[r1 r2 r3],那么r3也就不要了,參考下面的推導(dǎo):
其中H為:
是一個3×3大小的矩陣.
故最終的單應(yīng)性矩陣可表示如下:
OpenCV就是利用上述公式來計算單應(yīng)性矩陣。它使用同一物體的多個圖像來計算每個視場的旋轉(zhuǎn)和平移,同時也計算攝像機(jī)的內(nèi)參數(shù)。我們知道旋轉(zhuǎn)和平移共6個參數(shù),攝像機(jī)內(nèi)參數(shù)為4個參數(shù)。對于每一個視場有6個要求解的新參數(shù)和4個不變的相機(jī)內(nèi)參數(shù)。對于平面物體如棋盤,能夠提供8個方差,即映射一個正方形到四邊形可以用4個(x,y)來描述。那么對于兩個視場,我們就有82=16=2*6+4,即求解所有的參數(shù),至少需要兩個視場。
為什么正方形到四邊形的四個點的映射可以確定8個方程呢,結(jié)果是顯然的,我們假設(shè)物體平面上的正方形的一個頂點坐標(biāo)為(u,v),成像儀與該點對應(yīng)的點坐標(biāo)為(x,y),我們假設(shè)它們之間的關(guān)系如下:
u=f(x,y);
v=g(x,y);
顯然,我們把四點的對應(yīng)坐標(biāo)帶入到上述公式可以得到8個方程。
這里我們會想物體平面上正方形的四個頂點坐標(biāo)如何確定,其實我們就可以理解為角點的個數(shù),對于尺度的話,我們有s進(jìn)行控制。對于圖像平面上的角點的位置,我們可以可以通過尋找角點來定位他們的位置。其實對于具體的操作,由于還沒細(xì)讀代碼和相關(guān)原理,在這里只能大體猜測一下。等日后學(xué)習(xí)了,再來糾正。
單應(yīng)性矩陣H把源圖像平面上的點集位置與目標(biāo)圖像平面上(通常是成像儀平面)的點集位置聯(lián)系起來:
OpenCV就是利用多個視場計算多個單應(yīng)性矩陣的方法來求解攝像機(jī)內(nèi)參數(shù)。
OpenCV提供了一個方便的C函數(shù)cvFindHomography(),函數(shù)接口如下:
void cvFindHomography(
const CvMat* src_points,
const CvMat* dst_points,
CvMat* homography
);
1、src_points,dst_points為N×2或者N×3的矩陣,N×2表示點是以像素坐標(biāo)表示。N×3表示以齊次坐標(biāo)表示。
2、homography,為3*3大小的矩陣,用來存儲輸出的結(jié)果。
C++函數(shù)的接口:
Mat findHomography( const Mat& srcPoints, const Mat& dstPoints,
Mat& status, int method=0,
double ransacReprojThreshold=3 );
Mat findHomography( const Mat& srcPoints, const Mat& dstPoints,
vector<uchar>& status, int method=0,
double ransacReprojThreshold=3 );
Mat findHomography( const Mat& srcPoints, const Mat& dstPoints,
int method=0, double ransacReprojThreshold=3 );
1、srcPoints,dstPoints為CV_32FC2或者vector<Point2f>類型
2、method:0表示使用所有點的常規(guī)方法;CV_RANSAC 基于RANSAC魯棒性的方法;CV_LMEDS 最小中值魯棒性方法
3、ransacReprojThreshod 僅在RANSAC方法中使用,一個點對被認(rèn)為是內(nèi)層圍值(非異常值)所允許的最大投影誤差。即如果:
那么點i被認(rèn)為是異常值。如果srcPoints和dstPoints單位是像素,通常意味著在某些情況下這個參數(shù)的范圍在1到10之間。
4、status,可選的輸出掩碼,用在CV_RANSAC或者CV_LMEDS方法中。注意輸入掩碼將被忽略。
這個函數(shù)找到并且返回源圖像平面和目的圖像平面之間的透視變換矩陣H:
使得下面的返回投影誤差(back-projection)最?。?br>
如果參數(shù)method設(shè)置為默認(rèn)值0,該函數(shù)使用一個簡單的最小二乘方案來計算初始的單應(yīng)性估計。
然而,如果不是所有的點對(srcPoints,dstPoints)都適應(yīng)這個嚴(yán)格的透視變換。(也就是說,有一些異常值),這個初始估計值將很差。在這種情況下,我們可以使用兩個魯棒性算法中的一個。RANSCA和LMEDS這兩個方法都嘗試不同的隨機(jī)的相對應(yīng)點對的子集,每四對點集一組,使用這個子集和一個簡單的最小二乘算法來估計單應(yīng)性矩陣,然后計算得到單應(yīng)性矩陣的質(zhì)量quality/goodness。(對于RANSAC方法是內(nèi)層圍點的數(shù)量,對于LMeDs是中間的重投影誤差)。然后最好的子集用來產(chǎn)生單應(yīng)性矩陣的初始化估計和inliers/outliers的掩碼。
忽略方法,魯棒性與否,計算得到的單應(yīng)性矩陣使用Levenberg-Marquardt方法來進(jìn)一步減少重投影誤差,從而進(jìn)一步提純。(對于魯棒性的方法僅使用內(nèi)圍層點(inliers))。
RANSAC方法,幾乎可以處理任含有何異常值比率的情況,但是它需要一個閾值用來區(qū)分inliers和outliers。LMeDS方法不需要任何閾值,但是它僅在inliers大于50%的情況下才能正確的工作。最后,如果你確信在你計算得到的特征點僅含一些小的噪聲,但是沒有異常值,默認(rèn)的方法可能是最好的選擇。(因此,在計算相機(jī)參數(shù)時,我們或許僅使用默認(rèn)的方法)
這個函數(shù)用來找到初始化內(nèi)參數(shù)和外參數(shù)矩陣。單應(yīng)性矩陣取決于一個尺度,那么通常歸一化,以使得h33=1。
再貼一個知乎回答:
