我們現在知道原則上4對匹配點對就可以唯一確定單應矩陣,但是在實際應用中我們無法保證兩個視圖嚴格滿足使用條件(只有旋轉變換;遠景;平面場景),所以要使用擬合的方法求一個最優解。現在就來以SIFT算法源碼爲例,看一下是怎麼求解的。這是RobHess寫的SIFT源碼中求解矩陣的代碼部分,我們依次看每一個參數的含義:
H1 = ransac_xform( feat1, n1, FEATURE_FWD_MATCH, lsq_homog, 4, 0.01,//求變換矩陣用4對匹配對
homog_xfer_err, 3.0, NULL, NULL );//允許錯誤概率爲0.01
第一個參數是指向struct feature的指針。
第二個參數是圖1中特徵點的數目。結合第一個參數和函數get_matched_features找到特徵點1對應的匹配對CvPoint2D64f* pts, * mpts,要求至少有4對匹配對。
第三個參數決定使用每個特徵點的哪個匹配域進行變換矩陣的計算,對應的匹配點對是每個特徵點的img_pt域和其匹配點的img_pt域
第四個參數xform_fn:函數指針,指向根據輸入的點對進行變換矩陣計算的函數,一般傳入lsq_homog()函數。lsq_homog()函數會根據CvPoint2D64f* pts, * mpts利用RANSAC計算單應矩陣。源碼的註釋中有這麼兩句話:Returns the 3 x 3 least-squares planar homography matrix.Calculates a least-squares planar homography from point correspondeces.
這就到了今天的重點:
CvMat* lsq_homog( CvPoint2D64f* pts, CvPoint2D64f* mpts, int n )
{
CvMat* H, * A, * B, X;
double x[9];
int i;
if( n < 4 )
{
fprintf( stderr, "Warning: too few points in lsq_homog(), %s line %d\n",
__FILE__, __LINE__ );
return NULL;
}
/* set up matrices so we can unstack homography into X; AX = B */
A = cvCreateMat( 2*n, 8, CV_64FC1 );//2*n行,8列
B = cvCreateMat( 2*n, 1, CV_64FC1 );
X = cvMat( 8, 1, CV_64FC1, x );//8行一列,初始值爲x,x是一個數組指針
H = cvCreateMat(3, 3, CV_64FC1);
cvZero( A );
for( i = 0; i < n; i++ )
{
cvmSet( A, i, 0, pts[i].x );
cvmSet( A, i+n, 3, pts[i].x );
cvmSet( A, i, 1, pts[i].y );
cvmSet( A, i+n, 4, pts[i].y );
cvmSet( A, i, 2, 1.0 );
cvmSet( A, i+n, 5, 1.0 );
cvmSet( A, i, 6, -pts[i].x * mpts[i].x );
cvmSet( A, i, 7, -pts[i].y * mpts[i].x );
cvmSet( A, i+n, 6, -pts[i].x * mpts[i].y );
cvmSet( A, i+n, 7, -pts[i].y * mpts[i].y );
cvmSet( B, i, 0, mpts[i].x );
cvmSet( B, i+n, 0, mpts[i].y );
}
cvSolve( A, B, &X, CV_SVD );
x[8] = 1.0;
X = cvMat( 3, 3, CV_64FC1, x );
cvConvert( &X, H );
cvReleaseMat( &A );
cvReleaseMat( &B );
return H;
}
lsq_homog()函數中的B很容易理解,就是2nx1的列向量,存放圖2中匹配點的座標:
按道理A也應該是這種形式的矩陣,存放圖1中的特徵點,但是實際的A是這樣子的:
爲什麼要將A變形成這種形式呢?因爲在計算機中,求解非齊次方程組也是先轉換成齊次方程組如AX=0,然後再轉化爲min ||Ax||2 的非線性優化問題(超定方程,通過最小二乘擬合得到近似解)。這也是爲什麼稱作最小二乘求解的原因。
首先我們知道單應矩陣是3x3的矩陣,有8個自由度
如果將H矩陣看作是一維數組,,那麼我們可以很容易得到
但是因爲單應矩陣中自由度是8,h22=1,所以可以將等式中左邊的矩陣的最後一列捨去,變成源碼中的形式。
這裏我們以AX=B爲例說明一下最小二乘問題。AX=B是我們很熟悉的齊次方程,m個方程求解n個未知數,考試的時候經常考察它什麼時候有唯一非零解,但是其實大多時候如機器學習中,樣本數遠大於特徵數m>n,約束的個數大於未知數的個數,稱爲超定問題(overdetermined)。也就是說,X要滿足的條件過於多,不可能同時滿足,即沒有解,只能使用如最小二乘法來擬合。
最小二乘問題:
齊次方程時最小化問題爲:
即:在做最小二乘估計時,其實不需要完整進行SVD分解,只需要得到AT*A的最小特徵值對應的特徵向量即可。
Reference:
- https://blog.csdn.net/qq_32454557/article/details/76647374
- 劉毅的推導https://www.cnblogs.com/liufuqiang/p/5663175.html
- 稱爲超定問題(overdetermined)http://www.cnblogs.com/houkai/p/6656894.html