例えば、下図のように2x2画素の画像を4x4の画像に拡大する場合、アフィン変換を使えばいいんでしょ!と、安易に考えていると、思わぬ落とし穴があったりもします。
大事なポイントとして、
●画像の座標の原点は左上の画素の中心が原点(0.0、0.0)となる。(例外もあります)
●アフィン変換の拡大縮小は原点を基準として拡大縮小される。
となります。
これを気にせず、ただ、アフィン変換で画像を2倍に拡大すると、左上の画素の中心を基点に画像が拡大されます。
これで、一見良さそうにも感じるのですが、拡大後の画像において、画素の中心が原点であることから、4x4画素の領域は下図の四角で示した領域であり、画像全体が左上に0.5画素ズレた状態になっていまいます。
アフィン変換で画像を拡大する時の変換前と変換後の状態は、以下のようになるのが正解です。
この変換をアフィン変換で実現するには以下のように行います。
変換前の状態
①画像全体を右下に(+0.5,+0.5)画素移動 | |
$$\begin{pmatrix} 1 & 0 & 0.5 \\ 0 & 1 & 0.5 \\ 0 & 0 & 1 \end{pmatrix}$$ | |
②画像を2倍に拡大 |
|
$$\begin{pmatrix} 2 & 0 & 0 \\ 0 & 2 & 0 \\ 0 & 0 & 1 \end{pmatrix}$$ | |
③画像全体を左上に(-0.5,-0.5)画素移動 |
|
$$\begin{pmatrix} 1 & 0 & -0.5 \\ 0 & 1 & -0.5 \\ 0 & 0 & 1 \end{pmatrix}$$ |
となります。
この一連の変換をアフィン変換行列であらわすと
$$\begin{pmatrix} { x }^{ ‘ } \\ { y }^{ ‘ } \\ 1 \end{pmatrix}=\begin{pmatrix} 1 & 0 & -0.5 \\ 0 & 1 & -0.5 \\ 0 & 0 & 1 \end{pmatrix}\begin{pmatrix} 2 & 0 & 0 \\ 0 & 2 & 0 \\ 0 & 0 & 1 \end{pmatrix}\begin{pmatrix} 1 & 0 & 0.5 \\ 0 & 1 & 0.5 \\ 0 & 0 & 1 \end{pmatrix}\begin{pmatrix} x \\ y \\ 1 \end{pmatrix}\\ \\ $$
$$\begin{pmatrix} { x }^{ ‘ } \\ { y }^{ ‘ } \\ 1 \end{pmatrix}=\begin{pmatrix} 2 & 0 & 0.5 \\ 0 & 2 & 0.5 \\ 0 & 0 & 1 \end{pmatrix}\begin{pmatrix} x \\ y \\ 1 \end{pmatrix}\\ \\ $$
となり、単に拡大のアフィン変換行列だけを掛ければOKでは無いことが分かります。
ちなみに、C#で2x2画素の画像をPictureBoxのSizeModeプロパティをZoomにして、ImageプロパティにBitmapを設定すると、このようになります。
なんとなく、画像が左上にズレているようで、なんか怪しい!!
【関連記事】
←画像処理のためのC#へ戻る