2008年12月11日木曜日

画像処理 #10 回転

今回は回転について.
回転は,Exp.1の式で表されます.

Exp.1 回転(rotation)

この変換では,原点を中心にθ回転します.一般的な画像の表現は,左上を原点,x軸が右方向へ正,y軸が下方向へ正,ですので単純に回転させると次の様になります.


Fig.1 単純に回転させた場合

この処理でも問題はありませんが,画像の中心(w/2, h/2)を回転の中心にしたい場合(星がクルクル回るとか)は困ります.つまり,次のようにしたい,ということもあるかと思われます.


Fig.2 上手い回転

ということで,以降にこの変換の方法を記します(と,言っても単純な平行移動です).

元画像に対応する点をv1,回転画像に対応する点をv2とし,
v1=(x1, y1)t
v2=(x2, y2)t
とおいた時.v2からv1を出すのが目標です.

元画像fを考えます.fの幅をw,高さをhとします.
回転後の画像をgとします,まず,gのサイズを決定します.gはfを回転させたものなので,fのサイズと同一にはなりません.
サイズは回転する角度によります.角度によって,サイズを変えるのは変なので,一括して最大となる値に固定してしまいます.
幅が最大というのは,画像の対角線が丁度水平の時です.ですので,幅の最大値は,対角線の長さ√(w^2+h^2)です.
高さが最大の時も同様ですので,結局,一辺が√(w^2+h^2)の正方形で十分です.
r=√(w^2+h^2)とします.

f,gそれぞれの(x, y)の変域は次のようになっています.
f
x1 -> [0,w]
y1 -> [0,h]

g
x2 -> [0,r]
y2 -> [0,r]

それぞれ,画像の中心を回転の中心としたいので,

x1'=x1-w/2 (x1 -> [-w/2,w/2])
y1'=y1-h/2 (y1 -> [-h/2,h/2])

x2'=x2-r/2 (x2 -> [-r/2,r/2])
y2'=y2-r/2 (y2 -> [-r/2,r/2])

とします.

v1=(x1, y1)t
v2=(x2, y2)t
であるので,
w1=v1-(w/2, h/2)t=(x1', y1')t
w2=v2-(r/2, r/2)t=(x2', y2')t

とすれば,Aをdeg°回転の表現行列とした時,

w1=A^(-1)w2

となりめでたくゴールです.v2からv1が求められます.ちなみにv1が(w, h)tの範囲外にあることがありますので,その辺は適宜調整しましょう.

まとめ

パラメータ
画像f - 元画像
幅 - w
高さ - h
画像g - 回転画像
幅 - r
高さ - h
r=√(w^2+h^2)
元画像に対応する点 - v1=(x1, y1)t
回転画像に対応する点 - v2=(x2, y2)t
行列A - deg°回転させる行列

手順
1.(r, r)の画像を用意
2.w1=v1-(w/2, h/2)t
w2=v2-(r/2, r/2)t とする
3.w1=A^(-1)w2でv2からv1を求める
4.(v1がf内にあるとき)v2に対応するピクセルにv1に対応するピクセル値を書き込む

では,実際の変換例を.
今回はFig.3の画像を回転させます.エッシャーの作品です.


Fig.3
Relativity
M. C. Escher, 1953

Fig.4が95°,Fig.5が320°回転させたものです.


Fig.4 95°回転


Fig.5 320°回転

安定して回転出来ていると思います.

では,今回はこんな処で.

0 件のコメント: