攝像機內參與OpenGL

參考轉自:https://blog.csdn.net/yanglusheng/article/details/52268234

https://blog.csdn.net/sunboyiris/article/details/78082699

1、 相機參數是三種不同的參數。

相機的內參數是六個分別爲:1/dx、1/dy、r、u0、v0、f。

opencv1裏的說內參數是4個其爲fx、fy、u0、v0。實際其fx=F*Sx,其中的F就是焦距上面的f,Sx是像素/沒毫米即上面的dx,其是最後面圖裏的後兩個矩陣進行先相乘,得出的,則把它看成整體,就相當於4個內參。其是把r等於零,實際上也是六個。

dx和dy表示:x方向和y方向的一個像素分別佔多少長度單位,即一個像素代表的實際物理值的大小,其是實現圖像物理座標系與像素座標系轉換的關鍵。u0,v0表示圖像的中心像素座標和圖像原點像素座標之間相差的橫向和縱向像素數。

畸變參數:k1,k2,k3徑向畸變係數,p1,p2是切向畸變係數。徑向畸變發生在相機座標系轉圖像物理座標系的過程中。而切向畸變是發生在相機制作過程,其是由於感光元平面跟透鏡不平行。

切向畸變如下圖:產生的原因透鏡不完全平行於圖像平面

徑向畸變如下圖:產生原因是光線在遠離透鏡中心的地方比靠近中心的地方更加彎曲徑向畸變主要包含桶形畸變和枕形畸變兩種


相機外參分爲旋轉矩陣和平移矩陣,旋轉矩陣和平移矩陣共同描述瞭如何把點從世界座標系轉換到攝像機座標系


得到攝像機的內參K和相對於每個Marker的外參[R|T]後,就可以開始考慮將虛擬物體添加進來了。老慣例,我還是使用OpenFrameworks。OpenFrameworks是在OpenGL基礎上構建的一套框架,所以3D顯示上,其本質還是OpenGL。

OpenGL的投影模型和普通相機的小孔投影模型是類似的,其PROJECTION矩陣對應與相機的內參K,MODELVIEW矩陣對應與相機的外參。但是,我們之前求得的K和[R|T]還不能直接使用,原因有二,其一,OpenGL投影模型使用的座標系與OpenCV的不同;其二,OpenGL爲了進行Clipping,其投影矩陣需要將點投影到NDC空間中。

Perspective Frustum and Normalized Device Coordinates (NDC)

下一步是求PROJECTION矩陣。由於OpenGL要做Clipping,要求所有在透視椎體中的點都投影到NDC中,在NDC中的點能夠顯示在屏幕上,之外的點則不能。因此,我們的PROJECTION矩陣不僅要有與內參矩陣K相同的透視效果,還得把點投影到NDC中。

 

首先先看看內參矩陣K的形式:

首先假設OpenGL的投影椎體是對稱的,那麼PROJECTION矩陣的形式如下:

使用以上矩陣對某一點(X, Y, Z, 1)投影后,可以得到如下關係:

接下來,OpenGL會對該結果進行Clipping,具體方法是將四個分量都除以-Z,那麼,要使我們的點最終顯示到屏幕上,前三個分量在除以-Z後其變化範圍必須在[-1, 1]內。如下:

由攝像機投影模型(相似三角形)知:

其中由於OpenGL相機的相面在Z軸負方向上,所以是-fx和-fy。xp和yp分別爲某點在相面上的橫座標和縱座標,這兩個座標的原點在圖像的中心,圖像的寬度和高度分別爲w和h,因此xp和yp的取值範圍分別爲[-w/2, w/2]和[-h/2, h/2],可得:

於是

接下來,我們爲OpenGL相機設定兩個面,near和far,只有處於這兩個面之間的點才能投影到NDC空間中,所以當 Z=-n 時,(AZ+B)/-Z = -1,當 Z=-f 時,(AZ+B)/-Z = 1,由此我們可以得到關於A和B的二元一次方程,從而解出A、B:

現在再來考慮OpenGL投影椎體不對稱的情況,這種情況下,PROJECTION矩陣的形式爲:

由於椎體不對稱,這時xp和yp的變化範圍分別爲[l, r]和[b, t],代表圖像左側(left)右側(right),以及底部(bottom)頂部(top),用同樣的方法,我們有:

可得:

  ,  

於是:

關於l+r和b+t是怎麼計算的,可以參考下圖:

綜上所述,我們可以得到OpenGL投影矩陣的最終形式:

到此,我們就可以將這個矩陣的數據傳遞給PROJECTION矩陣了

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