【入門】アフィン変換のプログラミングに向けて【数値計算】

【入門】アフィン変換のプログラミングに向けて【数値計算】 数値計算
【入門】アフィン変換のプログラミングに向けて【数値計算】

MATLAB、Python、Scilab、Julia比較ページはこちら
https://www.simulationroom999.com/blog/comparison-of-matlab-python-scilab/

はじめに

の、

MATLAB,Python,Scilab,Julia比較 第3章 その71【アフィン変換⑮】
MATLAB,Python,Scilab,Julia比較 第3章 その72【アフィン変換⑯】

を書き直したもの。

アフィン変換の続き。
今回は、プログラミングに向けての話。

アフィン変換のプログラミングに向けて

アフィン変換のプログラミングを行うにあたって
おおよその情報がそろった状態になる。

よって、そろそろプログラミングし始めても良いレベルだろう。
しかし、事前に何をどのようにやるかの確認は必要。

まずは処理の流れの確認。
以下の流れを想定している。

  • 画像サイズの取得
  • 中心を0とした座標系の生成
    • X軸、Y軸ともに-1~1の範囲の座標系として扱う
  • 座標\(x\prime,y\prime,1\)の3次元ベクトル配列の生成。
    • ※ 全座標に対して一括でアフィン逆変換を実施するため。
  • 変換元座標の算出(アフィン逆変換)
  • 画像と同一形状の2次元配列に変換元座標配列を生成。
  • 変換元の座標系-1~1をピクセル位置に変換。
  • 元画像と変換元座標を元に変換先へコピー。

予想よりもやること多く感じるかもしれないが、
変換前の準備と後処理がいろいろ入ってるため。

画像サイズの取得と中心を0とした座標系の生成

画像サイズの取得はわかると思うが、、
中心を0とした座標系の生成が良くわからないだろう。

画像の中心を原点とした回転をしたいが、原点が中心じゃないと困る。
画像で示すとこんな感じになる。

中心を0とした座標系の生成、本来であれば、Y軸(縦軸)の上を1、下を-1としたいが、左上を座標最小値にしておいた方が、座標→ピクセル位置に変換する時に楽。このような座標系と解釈し直す。

とりあえず、ピクセル座標からいい感じに座標を置き換えるってことになる。

座標の3次元ベクトル配列の生成。

その次の
「座標\(x\prime,y\prime,1\)の3次元ベクトル配列の生成。」
のもわかりにくいだろう。

各ピクセルの座標を作った段階では2次元配列になるのだが、
それを1次元配列的な形に変形するって話になる。
まず、座標配列である、2次元グリッドを作る。
だいたいどのツール、言語でもmashgridという関数があるから、これを使用すると簡単に作れる。

座標系の生成方法、X軸の等差数列、Y軸の等差数列

そして、このままだと2次元配列なので、1元配列な構成に変更。
reshapeや行列の数列展開を使用すると実現できる。

3次元ベクトル配列の生成

しかし、なぜこのようなことをするのだろうか?

変換元座標の算出(アフィン逆変換)

先ほどの答えは、
「アフィン逆変換を一括でやるため」

まずアフィン逆変換の式を再掲する。

\(
\begin{bmatrix}
x\\
y\\
1
\end{bmatrix}=
\begin{bmatrix}
a & b & T_x\\
c & d & T_y\\
0 & 0 & 1
\end{bmatrix}^{-1}
\begin{bmatrix}
x\prime\\
y\prime\\
1
\end{bmatrix}\\
\)

これだと一つずつのピクセルの座標変換しかできない。
これを一括で出来るように式を拡張する。

\(
\begin{eqnarray}
\begin{bmatrix}
x_{(-1,-1)} & \dots & x_{(0,0)} & \dots & x_{(1,1)} \\
y_{(-1,-1)} & \dots & y_{(0,0)} & \dots & y_{(1,1)} \\
1 & 1 & 1 & 1 & 1
\end{bmatrix}=\\
\begin{bmatrix}
a & b & T_x\\
c & d & T_y\\
0 & 0 & 1
\end{bmatrix}^{-1}
\begin{bmatrix}
-1 & -0.9 & \dots & 0 & \dots & 0.9 & 1\\
-1 & -1 & \dots & 0 & \dots & 1 & 1\\
1 & 1 & 1 & 1 & 1 & 1 & 1
\end{bmatrix}\\
\end{eqnarray}
\)

入力ベクトル、出力ベクトルが列ベクトルなのを拡張して、
入力ベクトル群としての行列、出力ベクトル群としての行列にしている。

1ベクトル単位でfor文で回しても良いのだが、
数式の段階で解決してしまった方が楽だろう。

次のページへ

コメント

タイトルとURLをコピーしました