ステレオビジョンにおける行列のあれこれ
こんにちは~
今日はまたまた理論編です。プロジェクタとカメラを同軸にするために使うホモグラフィ行列?プロジェクション行列?内部パラメータ行列?と混乱してきたので一気にまとめたいなと思いました~
ホモグラフィ行列
カメラとプロジェクタを同軸にする時、ホモグラフィ行列を使います。
前回の記事から、ホモグラフィ行列は対応点が4つ以上あれば求まるということが分かっていますね。
つまりカメラからの画像座標4点とプロジェクタから見た画像座標4点が必要になります。
プロジェクタで4点以上の座標に投影して、カメラで撮影します。投影座標がカメラから分かるので、投影した場所の座標を求めることが出来、それが対応点になります。
これで画像座標を求めることが出来、無事ホモグラフィを求めることが出来ます。プロジェクタの投影画像を生成することが出来ますね。
(この理解で合っているのでしょうか…良い参考サイトがなくて自己流の理解なので自信ない…)
内部パラメータ行列
内部パラメータとは、カメラによって決まるパラメータのことで、焦点距離、画像の中心座標(Cx,Cy)、画素間の距離(x,y方向)の5つのパラメータです。
これが分かると内部パラメータ行列を定義することが出来、カメラ座標から画像座標に変換することが出来ます。
内部パラメータ行列は以下の形をしていますね。
fx, fyは歪みなどを考慮された値となっていて、理想はfx, fyが同じ値になるのですが、厳密にはそれぞれ独立した値を持ちます。なのでx方向y方向の焦点距離を要素として持っています。(おそらく画素間の距離が関係してくる)
Cx, Cyで平行移動をすることで画像中心分だけずれるので、画像座標系に変換することが出来ます。
外部パラメータ行列(位置姿勢)
外部パラメータは、x, y, z方向の回転、x, y, z方向の平行移動の6つのパラメータで表されます。カメラの位置姿勢を決めるものです。
外部パラメータ行列は回転行列Rと併進行列tで表せます。[R|t]の形ですね。
これによって3D座標をカメラ座標に変換することが出来ます。t分平行移動して、R分回転してカメラ座標に合わせます。つまりz軸を真ん中にします。
基礎行列
2つのカメラがあってどちらも別方向から1つの物体を映している時に、2つのカメラの物体のカメラ座標と基礎行列の関係は次のようになる。
この関係式の意味することは、片方のカメラ座標と基礎行列が分かれば、もう片方のカメラ座標が分かるということですね。もしくは二つの画像があれば、その間の回転行列と併進行列を求めることが出来ます。
また、内部パラメータに依存しないという特徴があります。
基本行列
基本行列は基礎行列に内部パラメータの情報も持たせたものです。上の関係式のカメラ座標を画像座標に変えた時に、真ん中にくる行列となります。
ホモグラフィのお話で、内部パラメータ行列が分かればカメラ座標を画像座標に変換することが出来ると言いました。この関係式を使って、カメラ座標を内部パラメータ行列と画像座標を使って表します。具体的な関係式は調べてみてください。
つまり、片方の画像と基本行列が分かれば、もう片方の画像を求めることが出来るということですね。
モデル行列、ビュー行列、プロジェクション行列
これらの行列は、3Dモデルをレンダリングする際に使う行列です。レンダリングとは、一言でまとめるとモデルを画像で表すことです。
モデル行列
モデルを3D座標に変換する行列です。モデル中心を原点としているので、ワールド座標系にします。
ビュー行列
3Dオブジェクトを3D座標系からカメラ座標系に変換する行列です。
では、透視投影の時の外部パラメータ行列と同じ?となるかもしれませんが、それぞれ異なるものです。以下の式の関係があります。
つまり、外部パラメータ行列の逆行列がビュー行列ということになりますね。
カメラの外部パラメータを基に、カメラからの3Dオブジェクトの見え方、座標を決定します。
透視投影の時には、ワールド座標をカメラの位置姿勢に合わせる処理をしていました。つまり現実にある3Dの座標をカメラのある位置に重ねるという感じです。しかし今回は、3D座標を動かすことはせず、原点をカメラとした時の座標を決定するだけです。カメラからみたときにどう見えるかを決めるものがビュー行列です。
プロジェクション行列
カメラ座標から画像座標に変換する行列です。内部パラメータを基に、遠くのものは小さく、近くのものは大きく変換するような処理を行います。
これらの行列は、一つ一つ適用させるものではなく、MVP行列を作成して適用させます。モデルの中心を原点としたモデル座標系→ワールド座標系→カメラからどうみえるか(カメラを原点とする)→遠近感を出すといった感じの処理をしています。
適用させる時には、右からかけていくようにします。つまりこういうことです。
glm::mat4 MVP = Projection * View * Model;
gl_Position = MVP * v;
参考
http://marupeke296.com/DXG_No72_ViewProjInfo.html
終わりに
疲れました…特に透視投影の式を追った後にMVP行列の概念が出てきたので、混乱しましたね。この違いを理解するには、CG空間と現実空間の違いを理解する必要があります。
この理解で合っているかも分からんので、ちょっと違うよ~みたいなのがあればコメントお願いします(泣)
あまり式はいれていないので、MVP行列の求め方などをみたい場合はぜひ参考文献をチェックしていただけたらと思います。
ではまた~