« 2013年12月 | メイン | 2014年04月 »

2014年01月 アーカイブ

2014年01月02日

長方形を任意の四角形に変換する行列

この前、長方形の画像を、任意の4頂点からなる凸四角形に変形して表示したくなった。

長方形を、2x2の行列による一次変換や、それに平行移動を加えた3x3のアフィン変換で、任意の凸四角形に移すことは不可能である。これらの一次変換では、長方形を平行四辺形に変換することはできるが、台形には変換できないからである。

しかし、変換行列を任意の3x3行列とし、変換後のベクトルの3番目の要素を拡大係数として斉次座標系を構成する、アフィン変換を拡張したものとも言える、射影変換(perspective transform)なら、それは可能である。

可能なはずなのだが、Webを検索しても、具体的な変換行列の数式が意外と見つからない。筆者の検索方法が悪いからだとは思うが、どうにも見つけられなかったので、自分で計算してみた。

0≦x≦W, 0≦y≦Hの領域にある長方形を0≦x≦1, 0≦y≦1の正方形に移す射影行列は自明(diag(1/W,1/H,1)である)なので、(0,0),(1,0),(0,1),(1,1)の4点を(Px,Py),(Qx,Qy),(Rx,Ry),(Sx,Sy)に移す射影変換を考える。

(≡は列ベクトルが斉次座標(homogeneous coordinate)として等価であることを表す)を満たすsx〜w2があるかどうかを考える。

上の合同式を展開する。

射影変換の斉次座標の定義より、(x y w)T≡(x/w y/w 1)Tなので、上の合同式は

という等式にできる。つまり、

という連立方程式であり、これを解くと、

と求まる。(力づくで解くなら、tx,tyの次にw0,w1をまとめて求めると良い。)(一見複雑だが、分母は全て同じ)
従って、w2=SxQy-SyQx+QxRy-QyRx+RxSy-RySxとすると、(0,0),(W,0),(0,H),(H,H)の4点を(Px,Py),(Qx,Qy),(Rx,Ry),(Sx,Sy)に移す射影変換は、

である。

■テストプログラム
Javaアプレットの起動用のページ
ソースコード
・使い方
 四角形の頂点の赤い丸をドラッグすると、イメージがそれに合わせて変形します。
 四角形に凹みができる(鈍角の内角ができる)と、正しく動作しません。

続きを読む "長方形を任意の四角形に変換する行列" »

About 2014年01月

2014年01月にブログ「Weblog on mebius.tokaichiba.jp」に投稿されたすべてのエントリーです。過去のものから新しいものへ順番に並んでいます。

前のアーカイブは2013年12月です。

次のアーカイブは2014年04月です。

他にも多くのエントリーがあります。メインページアーカイブページも見てください。

Powered by
Movable Type 3.35