スポンサーリンク
スポンサーリンク

【OpenCV】行列を用いた幾何学変換【Python】

[mathjax]

見習い

行列を用いた幾何学変換ってなんですか?

管理人

簡単に説明するのは難しいのですが、幾何学変換を使えば「画像の拡大・縮小」や「画像の回転」などが実現できるようになります。

管理人

まずは簡単な基礎前提を紹介し、「画像の拡大・縮小」を例として、使い方をみていきます。

基礎前提

変換行列

前提として、画像の幾何学変換では以下の数式が成り立ちます。

\(\begin{bmatrix} x’ \\ y’ \end{bmatrix} = \begin{bmatrix} a & b \\ c & d \end{bmatrix}\begin{bmatrix} x \\ y \end{bmatrix}\)

「x’」「y’」は変換後の画像における座標で、「x」「y」は元画像の座標を表し、「a, b, c, d」の行列は変換行列を表します。

今回行う幾何学変換において、この変換行列というのは重要で、この変換行列に特定の値を設定することで「拡大・縮小」や「回転」などの操作ができます。

計算方法

では、変換行列を用いて、画像を幾何学変換する計算方法を紹介します。

この計算方法は、変換の種類によらず、基本的には同じ計算方法になります。

前提として、変換行列を

\(\begin{bmatrix} a & b \\ c & d \end{bmatrix}\)

とします。

まずAの逆行列を生成します。

逆行列(inverse matrix)とは、ある行列と掛け算した結果が、単位行列になるものを指します。

\(\begin{bmatrix} 1 & 0 \\ 0 & 1 \end{bmatrix} = \begin{bmatrix} a & b \\ c & d \end{bmatrix} \begin{bmatrix} ia & ib \\ ic & id \end{bmatrix}\)

非常に面倒くさい計算と思うかもしれませんが、逆行列を生成する公式は存在するので、その公式を使って逆行列を生成していきます。

逆行列を求める公式

\(\begin{bmatrix} ia & ib \\ ic & id \end{bmatrix} = \displaystyle \frac{1}{ad – bc} \begin{bmatrix} d & -b \\ -c & a \end{bmatrix}\)

逆行列を求めたら、この行列の値を使って、抽出画素を計算します。

この抽出画素というのは、縮小変換の例でいうと、以下の画像のような画素を指します。

そして、抽象された画素を「変換後の画像を保存する配列」に代入します。

拡大・縮小の変換行列

「拡大・縮小」は、以下の変換行列を用います。

\(A = \begin{bmatrix} Sx & 0 \\ 0 & Sy \end{bmatrix}\)

例えば、幅・高さをそれぞれ2倍に拡大するなら、こうなります。

\(A = \begin{bmatrix} 2.0 & 0 \\ 0 & 2.0 \end{bmatrix}\)

逆に、\(\frac{1}{2}\)倍に縮小させる場合は、こうなります。

\(A = \begin{bmatrix} 0.5 & 0 \\ 0 & 0.5 \end{bmatrix}\)

それでは、先ほど紹介した計算方法を元に、変換後の画像を生成していきます。

プログラム(拡大)

結果

マーカー部分が変換行列の設定をしている部分です。

プログラム(縮小)

結果

プログラムは「変換行列」の設定を変えるだけです。

今回は「0.5」を設定したので、幅・高さがそれぞれ\(\frac{1}{2}\)のサイズに縮小されました。

回転の変換行列

「回転」は、以下の変換行列を用います。

\(A = \begin{bmatrix} \cos \theta & – \sin \theta \\ \sin \theta & \cos \theta \end{bmatrix}\)

\(\theta\)の値は、回転角度です。

結果

原点(左上座標)を中心に「\(\pi / 6\)(30°)」時計回りに回転しています。

線対称の変換行列

「線対称変換」は、以下の変換行列を用います。

・X軸に対する線対称変換の場合

\(A = \begin{bmatrix} 1 & 0 \\ 0 & -1 \end{bmatrix}\)

・Y軸に対する線対称変換の場合

\(A = \begin{bmatrix} -1 & 0 \\ 0 & 1 \end{bmatrix}\)

プログラム(X軸に対して)

結果

まるで裏返したかのように、上下反転させることができました。

プログラム(Y軸に対して)

結果

Y軸に対して線対称変換を行うと、左右反転を行うことができます。

コメント