カメラパラメータを考慮した透視投影

実際のカメラパラメータで透視変換したくなったので調べてみた.

{\bf X}=\(X,Y,Z,1\)^T, {\bf x}=\(x,y,z,1\)をそれぞれカメラ座標系, 正規化デバイス座標系での同次座標とする. また, 内部行列をAとする. ここで, fは焦点距離, k_u,k_vは1画素の物理的なサイズの逆数, u_0,v_0は画像中心である.
A=\(\begin{matrix}fk_u&0&u_0\\0&fk_v&v_0\\0&0&1\end{matrix}\)
OpenGLの透視変換行列PはglFrustum()で設定でき, その内容は以下のとおり. Pによりカメラ座標系から正規化デバイス座標系に変換される.
P=\(\begin{matrix}\frac{2n}{r-l}&0&\frac{r+l}{r-l}&0&\\0&\frac{2n}{t-b}&\frac{t+b}{t-b}&0\\0&0&\frac{-\(F+N\)}{F-N}&\frac{-2FN}{F-N}\\0&0&-1&0\end{matrix}\)
ここで, \(l,t\),\(r,b\),N,FはそれぞれNear平面の左上, 右下, Near平面までの距離, Far平面までの距離.
正規化デバイス空間は{\bf x} \in \left[-1,1\right]\times\left[-1,1\right]\times\left[-1,1\right]で定義される.

カメラパラメータを考慮した場合, 以下の行列P_{GL}でカメラ座標系から正規化デバイス座標系に変換できることがわかる.
P_{GL}=\(\begin{matrix}\frac{fk_u}{u_0}&0&0&0\\0&\frac{fk_v}{v_0}&0&0\\0&0&\frac{-\(F+N\)}{F-N}&\frac{-2FN}{F-N}\\0&0&-1&0\end{matrix}\)
なぜなら, \lambda {\bf x} = P {\bf X}より,


x=\frac{1}{\lambda}\frac{fk_u}{u_0}X \\
y=\frac{1}{\lambda}\frac{fk_v}{v_0}Y \\
z=\frac{1}{\lambda}\(\frac{-\(F+N\)}{F-N}Z+\frac{-2FN}{F-N}\) \\
\lambda=-Z
となり, まとめると


x=-\frac{1}{u_0}k_u f\frac{X}{Z}=-\frac{1}{u_0}u\\
y=-\frac{1}{v_0}k_v f\frac{Y}{Z}=-\frac{1}{u_0}v\\
z=\frac{F+N}{F-N}+\frac{2FN}{F-N}\frac{1}{Z}

u,vは画像中心を原点とした場合の画像座標なので, -u_0 \leq u \leq u_0, -v_0 \leq v \leq v_0となる(クリッピングを考慮). よって, -1\leq x\leq1,-1\leq y\leq1となる. また, -F\leq Z\leq-Nであることから, -1\leq z\leq 1であることもわかる. よって, P_{GL}でカメラ座標系から正規化デバイス座標系へ座標変換可能.

行列スタック




カウンタ -
最終更新:2010年06月25日 17:33