今回は、画像位置合わせに用いられるアフィン変換を紹介します。
アフィン変換とは、2つの画像における座標の線形変換を意味しており、拡大縮小、回転、平行移動を組み合わせた位置合わせに用いられます。
アフィン変換において、変換前の座標 (x_n, y_n) と変換後の座標 (X_n, Y_n) の関係は以下のように表されます。


この式を行列で表すと・・

このように、変換後行列は、アフィン変換行列と変換前行列の積としてと表わされます。
また、アフィン変換行列は、λ(拡大縮小率)、θ(回転角度)、(T_x),(T_y)(平行移動距離)を用いて上式のように表すことができます。
ここで、それぞれの行列の形や順番を入れ替えると、上と同じ意味の行列の関係式が下のように表せます(ここでは、特徴点4点を用いた変換を考えました)。形や順番は違えど、上式と同じことを表していることが確認できます。

では、図1のような正方形の変換を考えてみましょう。
変換前(黒)がアフィン変換によって変換後(赤)になったとします。ただし、いずれも正方形の4つの頂点(特徴点)の座標しかわからず、どのような変換を施したのか分かりません。さて、どのような変換をしたのか、上の式を用いて解いていきましょう。

まず、上の行列に、変換前と後の正方形の座標の値を代入します。すると、下のようになります。

ここで、特異値分解と呼ばれる操作を施し、変換前行列 A を以下のように3つの行列の積に分解します(行列の計算や特異値分解についての詳細はこちら:http://www.iedu.i.kyoto-u.ac.jp/uploads/20141022.pdf)。

実際に、変換前行列 A を特異値分解した結果、それぞれの行列は下のようになりました(計算プログラムは後述)。

最初の関係式 AX=B を、 A の特異値分解によって得られた3つの行列 U, D, Vを用いて下のように同値変換していくと、最終的に、U, D, V の逆行列と変換後行列 B を用いてアフィン変換行列 X を表すことができます。(U, D, V は、ユニタリ行列と呼ばれ、逆行列=転置行列になります)


このように、6行1列のアフィン変換行列 X が得られました。
この値を元のアフィン変換行列の形に書き換えてみると、下式のようになります。


上式を解くと、λ ≃ 1.2、θ = 30°となります。
つまり、元の正方形を1.2倍に拡大し、反時計回りに30°回転させ、X方向に+0.6, y方向に+0.4平行移動させる、という変換を行ったことが分かりました。
このように、変換前と後の特徴点の座標の情報からアフィン変換行列求めることによって、施された変換の内容を明らかにすることができます。さらに、その変換行列を用いて画像全体の位置合わせが可能となります。
今回、アフィン変換行列を求めるプログラムをpythonで書きましたので参考にしてみてください。

ちなみに、OpenCVにはアフィン変換行列を求める関数が用意されており、下記のように、変換前後の4点の座標を指定すれば、直ちにアフィン変換行列が求められます。(もちろん、内部では特異値分解を行っています)
