内部行列を考慮した透視投影

OpenGLによる内部行列を考慮した透視投影を考えてみる.

{\bf X}=\left(X,Y,Z,1\right)^T, {\bf x}=\left(x,y,z,1\right)^Tをそれぞれカメラ座標系, 正規化デバイス座標系での同次座標とする. また, 内部行列をAとする.

A=\left( \begin{array}{ccc}  fk_u & 0 & u_0 \\  0 & fk_v & v_0 \\  0 & 0 & 1  \end{array} \right)

ここで, fは焦点距離, k_u,k_vは1画素の物理的なサイズの逆数, u_0,v_0は画像中心である.

OpenGLの透視変換行列PはglFrustum()で設定でき, その内容は以下のとおり. Pによりカメラ座標系から正規化デバイス座標系に変換される.

P=\left(\begin{array}{cccc}  \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{-\left(F+N \right)}{F-N} & \frac{-2FN}{F-N} \\  0 & 0 & -1 & 0  \end{array} \right)

ここで, \left(l,t \right),\left(r,b \right),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}=\left(\begin{array}{cccc}  \frac{fk_u}{u_0} & 0 & 0 & 0 \\  0 & \frac{fk_v}{v_0} & 0 & 0 \\  0 & 0 & \frac{-\left(F+N\right)}{F-N} & \frac{-2FN}{F-N} \\  0 & 0 & -1 & 0  \end{array}\right)

なぜなら, \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}\left(\frac{-\left(F+N\right)}{F-N}Z+\frac{-2FN}{F-N}\right) \\  \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}によりカメラ座標系から正規化デバイス座標系へ座標変換可能.

OpenGL Programming Guide
OpenCV Wiki

広告
カテゴリー: Computer Vision, OpenGL パーマリンク

コメントを残す

以下に詳細を記入するか、アイコンをクリックしてログインしてください。

WordPress.com ロゴ

WordPress.com アカウントを使ってコメントしています。 ログアウト /  変更 )

Google フォト

Google アカウントを使ってコメントしています。 ログアウト /  変更 )

Twitter 画像

Twitter アカウントを使ってコメントしています。 ログアウト /  変更 )

Facebook の写真

Facebook アカウントを使ってコメントしています。 ログアウト /  変更 )

%s と連携中