クライミング好きプログラマーのプログラミング日記

2009-03-26

ARToolKitのソースコードを読む_透視変換行列の作成_get_cpara関数

最近画像認識勉強中です。get_cparaについてちょっと迷ったのでメモ残します。

ARToolKitのget_cpara関数を読み解きます。

get_cpara関数はカメラで得られた四角形マーカーを射影投影で四角形に変換する

変換行列を取得する関数です。

詳しく具体的に書くと、カメラで正面ではなく斜め方向からマーカーを撮ると

マーカーは正方形というよりもゆがんだ四角形に見えると思います。

このゆがんだ四角形を正方形に直すための変換行列(透視変換行列というらしい)

を計算するための関数です。

射影投影については

http://www.teu.ac.jp/clab/kondo/research/cadcgtext/Chap5/Chap503.html

がわかりやすいと思います。

関数内で使用している行列↓がまとまっています。

http://d.hatena.ne.jp/nyatla/20090323/

というか同じタイミングでget_cparaを調べている人がいました。

しかもNyARToolkitを作成している方でした。

ではさっそくget_cparaを読み取ります。

なんか変数名のつけ方がa,b,cとかになっていますが、

aは8×8行列

bは8×1行列

cは8×1行列

です。でこのソースコードを見る限りaの行列がいきなり作られているため

いまいちよくわかりませんので、a行列を作成するためにちょいと計算をします。

まず引数にworldがありますが、これは

射影後の四角形の4つの頂点座標を示しています。

(100,100) (110,100) (110,110) (100,110)  ←A行列とする

カメラ画像で取得したマーカーの4つの頂点を

(x1,y1) (x2 ,y2) (x3, y3) (x4,y4) ←これは引数vertexです。B行列とする

この二つの座標を行列をそれぞれA行列、B行列とし、透視変換行列をPとすると

B=PA

という式が成り立ちます。このPを求める事がget_cparaの目的です。

A行列の座標からBの行列座標の求め方が

http://www.teu.ac.jp/clab/kondo/research/cadcgtext/Chap5/Chap503.html

に乗っています。

f:id:gac777:20090326193715j:image

この方程式のx'にA行列の座標を入れて計算してみます。まずは(100,100)の頂点を代入

f:id:gac777:20090326193716j:image

まだひとつの頂点しか書いていませんが、後は脳内計算と言うことで・・

次に行列を用いた連立方程式を考えます。

さっそく計算した2つの式(脳内では8つ)を行列に変換してみましょう。

f:id:gac777:20090326193717j:image

ここで行列に「脳」とかいている部分は脳内計算した部分です。

上の行列はまさにソースコードの「a」マトリックスになっているのが計算すれば

わかると思います。

最後に実際に(a0,b0,c0,a1,b1,c1,a2,b2)の求め方ですが、

これはaの逆行列を両辺にかける事で求まります。

(参考:http://www.geisya.or.jp/~mwm48961/kou2/linear_eq1.html)

get_cpara関数でいうと

arMatrixSelfInvで逆行列を求め、

arMatrixMulで両辺にaの逆行列をかけたものを計算しています。

これで(a0,b0,c0,a1,b1,c1,a2,b2)が求まりました。

参考OpenCV

http://opencv.jp/opencv-1.0.0/document/opencvref_cxcore_algebra.html#decl_cvPerspectiveTransform

画像処理はまだまだ勉強中の身で、間違いなどありましたらご指摘お願いします。

スパム対策のためのダミーです。もし見えても何も入力しないでください
ゲスト


画像認証

トラックバック - http://d.hatena.ne.jp/gac777/20090326/1238068882