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

MATLAB,Python,Scilab,Julia比較 第3章 その71【アフィン変換⑮】 数値計算
MATLAB,Python,Scilab,Julia比較 第3章 その71【アフィン変換⑮】

バックナンバーはこちら。
https://www.simulationroom999.com/blog/compare-matlabpythonscilabjulia3-backnumber/

はじめに

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

登場人物

博識フクロウのフクさん

指差しフクロウ

イラストACにて公開の「kino_k」さんのイラストを使用しています。
https://www.ac-illust.com/main/profile.php?id=iKciwKA9&area=1

エンジニア歴8年の太郎くん

技術者太郎

イラストACにて公開の「しのみ」さんのイラストを使用しています。
https://www.ac-illust.com/main/profile.php?id=uCKphAW2&area=1

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

太郎くん
太郎くん

もう必要な情報はそろったでしょー。

フクさん
フクさん

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

太郎くん
太郎くん

まずは処理の流れの確認だねー。

フクさん
フクさん

以下の流れを想定している。

  • 画像サイズの取得
  • 中心を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}
\)

太郎くん
太郎くん

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

フクさん
フクさん

そうそう。
まぁfor文で回しても良いのだけどね。
数式の段階で解決してしまった方が楽だろう。

まとめ

フクさん
フクさん

まとめだよ。

  • アフィン変換のプログラムの流れを確認。
  • 中心を0とした座標系の生成。
  • 3次元ベクトル配列の生成。
    • アフィン変換を一括で行うため。

バックナンバーはこちら。

コメント

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