Z軸まわりの回転φ(ロール)、新しいY軸まわりの回転θ(ピッチ)、新しいX軸まわりの回転ψ(ヨー)の3段階の回転で実現できる。写真から作る3次元CGでは、最後の回転がZになっています。これだとオイラー角と同じなので、最後はXが正しい。
Iterative minimization method
Multiple View Geometry in Computer Vision Second Edition4章から。
直接線形方程式を解くDLTアルゴリズムに比べた、イテレーティブに最小値を求める方法の特徴。
仕事で使っている感覚から行くと、適切な初期値と適切な終了条件があればDLTよりは速い。終了条件はどうしても現物あわせになってしまう。例えばGoogleの最小二乗法ライブラリCERESでもイテレーションの終了条件を細かく指定できる。裏返すと、一般的な終了条件というのが設定しにくいと言うこと。
イテレーションは次のステップで行われる。
Direct Linear Transform アルゴリズムを使って、投影変換の行列Hを計算する。
Multiple View Geometry in Computer Vision Second Edition4章から。
対応する4つの点を使って、投影変換を表す行列Hの計算します。Direct Linear Transform (DLT) とたいそうな名前がついていますが、点同士の制約から最小二乗法を用いて行列を求めるアルゴリズムです。
入力データ
Gauche-CVで投影変換Hを求めるのデータをそのまま使います。
xi | x'i |
---|---|
(5,5) | (20,15) |
(15,5) | (25,20) |
(15,15) | (25,25) |
(5,15) | (15,20) |
点の数は計算が一番楽な4点を使います。
DLTアルゴリズム
STEP1 それぞれの対応する点について、Ai行列を計算する
投影変換の式(i=1,2,3,4)
この式は外積を使った表現と同じである。
xi, Hxiをこのように表現する。(h^1T の1は添字でTは転置の意味)
Hxiに代入すると
hの表現を変え、Hxi を使って x'i × Hxi = 0 を書き換えると、
Hは等倍しても等価なので最後のrowは削除でき、Aih=0の形にできる。このときのAiはこの式で表現できる。
(x'i, y'i, w'i)は同次座標なのでw'i = 1に取れる。このときx'i, y'iは実際の座標系の値をそのまま使用できる。次にxiも同次座標系(xi, yi, wi)を使って表現し、行列の要素を書き出すと、2x9の行列が求まる。
Aih=0を同じように表現すると、
STEP2 n個の2x9行列を一つの2nx9の行列Aにする。
STEP1で計算したAiをi=1,2,3,4として4つ並べる。
wi=1として、実際のx'i 等の値を代入する。
STEP3 AのSVD (singular value decomposition, 特異値分解) を行う
STEP2で求めたAから、M=AA^T N=A^TAを求める。ここから数値計算ソフト使ってます。
Nの固有値と固有ベクトルを計算する。ここも数値計算ソフトで計算しています。Nの固有値は、大きい順に λ=929719.210541631, 80711.1190674933, 898.252012306525, 342.925445638261, 105.025927146904, 5.46731883242974, 0.91432069525331, 0.0853662562132915, 3.25254551524502E-13 となる。
それぞれの固有値に対応する固有ベクトルを並べるとこうなる。
行列全体はこちら。
一番小さい固有値 3.25254551524502E-13 に対応する固有ベクトルは、上の行列の一番右のcolumnで表されている。
右端のcolumn { 0.0859683627249945 -0.0614059733758339 0.859683627267237 -0.0736871680499479 0.0245623893504672 -0.49124778701298 0.0024562389349873 -0.00245623893503336 0.0491247787008782} が求める行列Hの要素である。
STEP4 SVDの結果からHを決定する。
{ 0.0859683627249945 -0.0614059733758339 0.859683627267237 -0.0736871680499479 0.0245623893504672 -0.49124778701298 0.0024562389349873 -0.00245623893503336 0.0491247787008782} を行列の形式に並び替える。
投影変換を表す行列Hはスカラー倍に対して等価なので、右下の要素が1になるように、 0.0491247787008782の逆数を全要素にかけると、Gauce-CVで求めた結果とほぼ同じになる。
リファレンス
- DLTのアルゴリズムは Multiple View Geometry in Computer Vision Second Editionを参考にしました。
- SVD (singular value decomposition, 特異値分解)に関しては、これなら分かる応用数学教室―最小二乗法からウェーブレットまでに大変わかりやすく説明がありました。以前にこれなら分かる応用数学教室にも書きましたが、この本は本当にお勧めです。
- 行列の計算と数式のTEXへのエクスポートは、株式会社シンプレックスのカルキングを使いました。
Gauche-CVで投影変換Hを求める
投影変換Hを求めるのに必要な条件の続き。
つまり4つの点の対応が分かれば、投影変換を表す行列Hは計算できます。
この図のような変換を使って実験してみます。(変換は青→黄)
座標の対応はこのようになります。
xi | x'i |
---|---|
(5,5) | (20,15) |
(15,5) | (25,20) |
(15,15) | (25,25) |
(5,15) | (15,20) |
この4点の対応を引数にcv-get-perspective-transformを呼ぶと、投影変換を表すHが計算できます。
(use srfi-1) (use cv) (require "../proj2d/proj2d") (import proj2d) (load "../cvutil/cvutil.scm") ;; 変換元の4角形 (define src-rect '((5 5) (15 5) (15 15) (5 15))) ;; 行列Hの計算 (define pts-src (map (lambda (p) (make-cv-point-2d32f (first p) (second p))) src-rect)) (define pts-dst (map (lambda (p) (make-cv-point-2d32f (first p) (second p))) '((20 15) (25 20) (25 25) (15 20)))) (define H (make-cv-mat 3 3 CV_32F)) (cv-get-perspective-transform pts-src pts-dst H) ;; 結果の確認と表示 (format #t "Projective matrix H~%") (print-2d-matrix H) (define display-transform (lambda (H) (lambda (x) (let ((xh (make-hm-point-2d (first x) (second x)))) (let ((xdash (transform H xh))) (format #t "~A -> ~A~%" x xdash)))))) (map (display-transform H) src-rect)
計算した行列Hの中身はこうなります。
[ [ 1.75 -1.25 17.5 ] [ 1.5 -0.5 10.0 ] [ 0.05000000074505806 -0.05000000074505806 1.0 ]]
この投影変換Hを使って、もとの点を変換してみると、全ての点が正しく変換されていることがわかります。
(5 5) -> (20.0, 15.0)
(15 5) -> (25.0, 20.0)
(15 15) -> (25.0, 25.0)
(5 15) -> (15.0, 20.0)
ソースはこちら
https://github.com/natsutan/computervision/blob/master/mvg/chap4/perspective-transform.scm
2章 練習問題
写真から作る3次元CGの2章練習問題。
問題1
D^-1を求めよ。D^-1はDの逆運動である。
答
Dは剛体変換(rigid transformation)で、回転行列Rと並進行列tを使って以下のように表現できる。Dの定義は投射行列、もしくは2次元変換の階層のClass I Isometries transformations に。
逆運動であるD'=D^-1も同じく剛体変換なので同じように表現できる。
ここでDD'は何もしない(変換を元に戻す)ので、
ここから
Rは回転行列なので以下の式を満たす。
よって、次の2式からD'が求められる。
問題3
Paを任意のアフィン投影行列とするとき、APaDもアフィン投影行列であることを確かめよ。
答
カメラ内部行列A、剛体変換行列Dは、共にアフィン投射行列である。アフィン投射行列の積は、またアフィン投射行列である。
問題4
Mi, i=1, ... n は3次元空間のn点であり、mi, i=1,... nは、それぞれのアフィン投影である。sm~ = PaM~ を照明せよ。m~ は、mi, i=1 ... nの重心であり、M~は、Mi, i=1 ... nの重心である。
答
3次元アフィン変換では、面の平行関係、体積比、重心は不変量。よって、Mの重心のアフィン投影は、mの重心に等しい。ただし、定数倍は等価。