2011-07-26 81 views
5

我想通過使用 基本矩陣和維基百科上給出的算法來恢復攝像機的運動[1]。對於 ,我需要找到基本矩陣。我正在使用 OpenCV :: findFundamentalMat。FindFundamentalMatrix沒有找到基本矩陣

兩個意外的行爲: 1)使用不同的擬合算法產生不同的結果,尤其是 FM_8POINT是不同的。 2)給定一組點對(y,x),yFx = 0不滿足,並且 總是大於0.

我在這裏沒有理解什麼嗎?我的例子是假的,還是 正在進行?任何人都可以提出更好的測試例子嗎

下面是一個簡單的例子。創建12個人工點,將這些點向右移動10個像素,從這兩組點中找到基本矩陣,併爲每個點打印yFx。

實施例:

int main(int argc, const char* argv[]) 
{ 
    // Create two sets of points. Points in pts2 are moved 10pixel to the right of the points in pts1. 
    std::vector<cv::Point2f> pts1, pts2; 
    for(double y = 0; y < 460; y+=150) 
    { 
      for(double x= 0; x < 320; x += 150) 
      { 
        pts1.push_back(cv::Point2f(x, y)); 
        pts2.push_back(cv::Point2f(x+10.0, y)); 
      } 
    } 

    cv::Mat F = cv::findFundamentalMat(pts1, pts2); 

    for(int i = 0; i < pts1.size(); i++) 
    { 
      // Creating p1, p2, the two points. Please let me know if this can be done in fewer lines. 
      cv::Mat p1(3,1, CV_64FC1), p2(3,1, CV_64FC1); 

      p1.at<double>(0) = pts1.at(i).x; 
      p1.at<double>(1) = pts1.at(i).y; 
      p1.at<double>(2) = 1.0; 

      p2.at<double>(0) = pts2.at(i).x; 
      p2.at<double>(1) = pts2.at(i).y; 
      p2.at<double>(2) = 1.0; 

      // Print yFx for each pair of points. This should be 0 for all. 
      cout << p1.t() * F * p2 << endl; 
    } 
} 

對於FM_RANSAC我得到[1.999],[2],[2],[1.599],[1.599],[1.599], [1.198],[1.198], [1.198],[0.798],[0.798],[0.798]

對於FM_8POINT,基本矩陣爲零(3,3),因此對於所有y,x,yFx爲0 。

我只找到:T and R estimation from essential matrix但這並沒有多大幫助。

編輯:yFx是錯誤的方式(p1/p2切換在cout線)。這個例子也不起作用,因爲所有的點都在一架飛機上。

回答

3

我相信基本矩陣解決了方程p2.t() * F * p1 = 0,即你的代碼中有p1和p2相反。至於爲什麼8點算法返回零矩陣,我不知道,對不起。

編輯:好的,我相信我記得爲什麼8點算法在這裏產生了一個糟糕的結果。在兩組點之間的移動是純翻譯沒有旋轉,即它只有三個自由度。基本矩陣有7個自由度,所以不可能估計;這被稱爲退化情況。參見this paper進一步描述基本/基本矩陣估計中的退化情況。

也可能是人爲移動像素座標所得到的兩個視點之間沒有剛性變換,因此沒有滿足要求的基本矩陣。更好的測試用例可能是使用cv :: warpPerspective等具有已知warp矩陣的函數。

+0

好吧,我不得不P2和P1輪走錯了路。感謝您的發現。我現在看看這篇論文,然後Hartley&Zisserman很快就會到我家門口,也許他們可以提供幫助。 – Unapiedra

1

1)使用不同的擬合算法產生不同的結果, 特別是FM_8POINT是不同的。

不同的方法不會產生相同的結果,這是真的:

  • 例如RANSAC(隨機樣本共識)是findFundamentalMat()的默認方法,它估計的一個轉換的參數一組點包含一些隨機點,這些點是先前的離羣點,它會以一定的概率產生一個正確的結果。
  • 而FM_8POINT旨在找到8點以及使用與線性獨立的方程系統的參數..

2)給定一組點對(Y的,x)中,YFX = 0是不達成,是 總是大於0

這意味着你發現了fundamentalMatrix是不正確的(用壞的估計),這是由於你給作爲輸入,這在真正的純粹的翻譯,是不可能的(這是一個觀點位於無窮遠處的2幅圖像的退化情況... (see epipolar geometry)

我希望它幫你... 朱利安,