2012-11-02 68 views
1

我一直在我的OpenCV和OpenGL組件之間來回切換,我不確定這兩者中的哪一個應該正確。相機校準:高寬比與圖像寬高比不同。如何糾正?

使用OpenCV攝像機校準產生fx,fy,高寬比約爲1,這將對應於方形大小的圖像。我的校準輸出:

... 
image_width: 640 
image_height: 480 
board_width: 6 
board_height: 9 
square_size: 5. 
flags: 0 
camera_matrix: !!opencv-matrix 
    rows: 3 
    cols: 3 
    dt: d 
    data: [ 6.6244874649105122e+02, 0., 3.4060477796553954e+02, 
     0., 6.4821741696313484e+02, 2.5815418044786418e+02, 
     0., 0., 1. ] 
distortion_coefficients: !!opencv-matrix 
    rows: 5 
    cols: 1 
    dt: d 
    data: [ -1.1832005538154940e-01, 1.2254891816651683e+00, 3.8133468645674677e-02, 1.3073747832019200e-02, -3.9497162757084490e+00 ] 

然而,我的形象寬度爲640×480,你可以在校準輸出看到。

當我在框架中檢測到棋盤並用OpenGL繪製棋盤時,OpenGL在高度上呈現的確很好,但在寬度方向上展開,因此它不適合實際所在的棋盤。當然,解決這個問題的方法是將校準的fx分量乘以480/640,但我不知道是否應該這樣。

我該如何糾正?根據圖像大小縮放校準值,或者在OpenGL中進行修改以解決問題?

編輯

有捕捉和顯示之間的區別。 I 使用已校準的智能手機拍攝了圖像,並且該智能手機吐出了640x480的圖像。

爲了找到棋盤,我使用瞭如上所示的內在函數,它們被校準了。然後,無論我給OpenGL的哪一個長寬比,都是fx/fy,640/480還是fx/fy * 640/480,都是錯誤的。在OpenGL中以OpenGL投影回來的方式在寬度方向拉伸的棋盤。

,它看起來完全正確在OpenGL中,唯一的辦法是,如果我使用FX = 640,尋找棋盤 FY = 480 。這是錯誤的,以及因爲現在我完全忽略了相機內在... enter image description here

EDIT2

我的意思是無論我怎樣設定縱橫比,我傳遞給gluPerspective,它不出來吧。

gluPerspective(/* field of view in degree */ m_fovy, 
    /* aspect ratio */ 1.0/m_aspect_ratio, 
    /* Z near */ 1.0, /* Z far */ 1000.0); 

我已經試過了m_aspect_ratio值:OpenCV中的calibrationMatrixValues的

  • 輸出的寬高比
  • FX/FY
  • 四百八十零分之六百四十零
  • FX/FY * 640/480
  • 輸出校準矩陣值* 640/480

所有的東西似乎都是寬度。請注意,棋盤的原點在我的屏幕截圖中是圖像中最上面的內角:它的放置正確,圖像中最底部的內角也是如此。這是一個縮放問題..

EDIT3

這是一件真的,真的很愚蠢..我設置的OpenGL像這樣的長寬比:

gluPerspective(/* field of view in degree */ m_fovy, 
    /* aspect ratio */ 1.0/m_aspect_ratio, 
    /* Z near */ 1.0, /* Z far */ 1000.0); 

和設置

m_aspect_ratio = viewportpixelheight/viewportpixelwidth; 

沒有意識到viewportpixelheightviewportpixelwidth是整數,所以我正在做整數除法, 1或0中

回答

1

相機校準矩陣地圖的世界(交換它們時)座標轉換圖像座標。 OpenGL將圖像座標映射到屏幕座標。如果你的問題是如何顯示圖像,你應該在OpenGL中處理它。

我對此感到抱歉。我試圖做的是區分捕獲和顯示圖像。你是正確的,物理相機的縱橫比可以從焦距計算出來。這些焦距和長寬比由相機的硬件固定。一旦你捕捉到了這個圖像,雖然你可以用OpenGL選擇的任何寬高比來顯示它。您可以裁剪和拉伸圖像以改變所顯示內容的縱橫比。相機的縱橫比與您的屏幕的縱橫比相匹配並不是給定的。 OpenCV使用物理相機的直接原始測量值計算相機校準矩陣。如果我們假設它們是正確的並且是恆定的(如果沒有縮放,這兩個看起來都是合理的),那麼對OpenGL的任何進一步的改變都是寬高比的責任。當我說fx和fy沒有確定寬高比時,我指的是顯示的寬高比,這個比例並不是很清楚,我很抱歉。

而且,我應該提到,可以計算從焦距寬高比的原因是,焦距以像素爲單位表示和那些單元可以在x和y軸上的不同。可以找到一個簡短的解釋here

我發現在相機矩陣中焦距的最佳解釋是在Computer Vision Algorithms and Applications的相機內部函數部分。在pdf中,從書中的第72頁開始。

+0

這不可能是正確的。對於OpenGL,我提供從fx和fy計算的視野。長寬比也由fx和fy計算。此外,我已經手動將cx和cy設置爲精確的圖像中心,因爲這兩個值的校準非常不準確。如果我在橫向模式下校準相機,然後以縱向模式拍攝相框,該怎麼辦?我仍然覺得我應該縮放fx和fy,因爲這些決定了fovy和縱橫比... – user1378489

+0

附加信息:fov和縱橫比是在OpenCV方法校準中計算的矩陣值 – user1378489

+0

@ user1378489對於混淆感到抱歉,請參閱編輯,是否會使其更清晰? – Hammer

0

1.0的縱橫比不指示正方形圖像,則表示正方形像素(這可以解釋爲什麼它幾乎總是1.0;非方形像素相對少見除了在攝像機anamorphic format捕獲)。相機矩陣不包含有關絕對圖像尺寸物理相機尺寸的信息。

另一方面,gluPerspective的縱橫比確實代表圖像尺寸。重要的是不要混淆另一個方面的比例。

如果你想使用gluPerspective,這是可能的,但你應該明白,gluPerspective不會讓你模型的所有固有相機參數(即軸線歪斜和主點偏移)的。我描述瞭如何設置縱橫比並正確使用in this article

然而,我強烈建議使用任一gluFrustum(其允許非零主點偏移),或直接glLoadMatrix(其也允許非零軸線歪斜)。兩種方法都在this article中解釋。