通過SVD求解單應矩陣

我們現在知道原則上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中匹配點的座標:

B = \left[ \begin{array}{l} {x_{21}}\\ {x_{22}}\\ {x_{23}}\\ ....\\ {x_{2n}}\\ {y_{21}}\\ {y_{22}}\\ {y_{23}}\\ ....\\ {y_{2n}} \end{array} \right]

按道理A也應該是這種形式的矩陣,存放圖1中的特徵點,但是實際的A是這樣子的:

A = \left[ {\begin{array}{*{20}{c}} {{x_{11}}}&{{y_{11}}}&1&0&0&0&{ - {x_{11}}{x_{21}}}&{ - {y_{11}}{x_{21}}}\\ {{x_{12}}}&{{y_{12}}}&1&0&0&0&{ - {x_{12}}{x_{22}}}&{ - {y_{12}}{x_{22}}}\\ {{x_{13}}}&{{y_{13}}}&1&0&0&0&{ - {x_{13}}{x_{23}}}&{ - {y_{13}}{x_{23}}}\\ {...}&{...}&{...}&{...}&{...}&{...}&{...}&{...}\\ {{x_{1n}}}&{{y_{1n}}}&1&0&0&0&{ - {x_{1n}}{x_{2n}}}&{ - {y_{1n}}{x_{2n}}}\\ 0&0&0&{{x_{11}}}&{{y_{11}}}&1&{ - {x_{11}}{y_{21}}}&{ - {y_{11}}{y_{21}}}\\ 0&0&0&{{x_{12}}}&{{y_{12}}}&1&{ - {x_{12}}{y_{22}}}&{ - {y_{12}}{y_{22}}}\\ 0&0&0&{{x_{13}}}&{{y_{13}}}&1&{ - {x_{13}}{y_{23}}}&{ - {y_{13}}{y_{23}}}\\ {...}&{...}&{...}&{...}&{...}&{...}&{...}&{...}\\ 0&0&0&{{x_{1n}}}&{{y_{1n}}}&1&{ - {x_{1n}}{y_{2n}}}&{ - {y_{1n}}{y_{2n}}} \end{array}} \right]

爲什麼要將A變形成這種形式呢?因爲在計算機中,求解非齊次方程組也是先轉換成齊次方程組如AX=0,然後再轉化爲min ||Ax||2 的非線性優化問題(超定方程,通過最小二乘擬合得到近似解)。這也是爲什麼稱作最小二乘求解的原因。

首先我們知道單應矩陣是3x3的矩陣,有8個自由度

H = \left[ {\begin{array}{*{20}{c}} {{h_{00}}}&{{h_{01}}}&{{h_{02}}}\\ {{h_{10}}}&{{h_{12}}}&{{h_{13}}}\\ {{h_{20}}}&{{h_{21}}}&{{h_{22}}} \end{array}} \right]

如果將H矩陣看作是一維數組,,那麼我們可以很容易得到

但是因爲單應矩陣中自由度是8,h22=1,所以可以將等式中左邊的矩陣的最後一列捨去,變成源碼中的形式。

這裏我們以AX=B爲例說明一下最小二乘問題。AX=B是我們很熟悉的齊次方程,m個方程求解n個未知數,考試的時候經常考察它什麼時候有唯一非零解,但是其實大多時候如機器學習中,樣本數遠大於特徵數m>n,約束的個數大於未知數的個數,稱爲超定問題(overdetermined)。也就是說,X要滿足的條件過於多,不可能同時滿足,即沒有解,只能使用如最小二乘法來擬合。

最小二乘問題:$J(x) = \left\| {Ax - b} \right\|$

齊次方程時最小化問題爲:

即:在做最小二乘估計時,其實不需要完整進行SVD分解,只需要得到AT*A的最小特徵值對應的特徵向量即可

Reference

  1. https://blog.csdn.net/qq_32454557/article/details/76647374
  2. 劉毅的推導https://www.cnblogs.com/liufuqiang/p/5663175.html
  3. 稱爲超定問題(overdeterminedhttp://www.cnblogs.com/houkai/p/6656894.html

 

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