2021年8月9日月曜日

【OpenCV】warpAffineによる画像の並進,回転

 画像処理ライブラリOpenCVで画像の並進(横移動)や回転を行うwarpAffineについて説明する。


OpenCVを使うには次のようにインポートが必要。
import cv2

例に用いる画像'girl.jpg'(幅600x高さ397ピクセル)は以下を使用(フリー写真素材ぱくたそより)




1. 書式

cv2.warpAffineの書式は以下の通り。

dst = cv2.warpAffine(src, M, dsize[, 
                     dst[, flags[, borderMode[, borderValue]]])
引数 意味
dst 変換後の画像
src 元画像
M 2x3の変換行列
dsize 変換後の画像サイズ。(幅, 高さ)のタプルで指定
flags interpolation(補完方法)の指定など


2. warpAffineによる画像の並進

 warpAffineの変換行列に幅方向、高さ方向の移動量を設定することで画像を並進移動(横移動)できる。

変換行列Mにより元画像に対して以下の操作が行われる。

\[ M = \begin{pmatrix} M_{11} & M_{12} & M_{13} \\ M_{21} & M_{22} & M_{23} \end{pmatrix} \] \[ dst = src(M_{11}x+M_{12}y+M_{13},\quad M_{21}x+M_{22}y+M_{23}) \]

 変換行列Mを以下のようにすることで画像の並進移動操作となる(方向に100px、高さ方向に50px移動する場合)。

\[ M = \begin{pmatrix} 1 & 0 & 100 \\ 0 & 1 & 50 \end{pmatrix} \] \[ dst = src(x+100,\quad y+50) \]

幅方向に100px、高さ方向に50px移動する場合。

import cv2
import numpy as np

img = cv2.imread('girl.jpg')
rows, cols, ch = img.shape

M = np.float32([[1, 0, 100], [0, 1, 50]])
dst = cv2.warpAffine(img, M, (cols, rows))

cv2.imwrite('affine.jpg', dst)

実行結果





3. getRotationMatrix2Dによる回転処理

 getRotationMatrix2Dにより回転および拡大縮小を含む変換行列を作成できる。
書式は

M = cv.getRotationMatrix2D(center, angle, scale)
引数 意味
center 回転中心座標。(x,y)のタプル
angle 回転角度(°)
scale 拡大縮小倍率


生成される変換行列Mは以下の通り。

\[ M = \begin{pmatrix} \alpha\quad & \beta\quad & (1-\alpha)\cdot center.x-\beta\cdot center.y \\ -\beta\quad & \alpha\quad & \beta\cdot center.x-(1-\alpha)\cdot center.y \end{pmatrix} \] \[ \alpha = scale\cdot cos(angle) \] \[ \beta = scale\cdot sin(angle) \]

これを用いてwarpAffineによりアフィン変換すると任意の座標を中心とした回転および拡大縮小が同時にできる。
画像の中心(画像幅、高さの半分)を回転中心として45°回転する例。拡大はしない。

import cv2
import numpy as np

img = cv2.imread('girl.jpg')
rows, cols, ch = img.shape

M = cv2.getRotationMatrix2D((cols/2, rows/2), 45, 1)
dst = cv2.warpAffine(img, M, (cols, rows))

cv2.imwrite('affine.jpg', dst)

実行結果





画像の中心(画像幅、高さの半分)を回転中心として45°回転させる例。画像を1.5倍に拡大。

import cv2
import numpy as np

img = cv2.imread('girl.jpg')
rows, cols, ch = img.shape

M = cv2.getRotationMatrix2D((cols/2, rows/2), 45, 1.5)
dst = cv2.warpAffine(img, M, (cols, rows))

cv2.imwrite('affine.jpg', dst)

実行結果





4. リファレンス

OpenCV > Geometric Image Transformations > warpAffine()
OpenCV > Geometric Image Transformations > getRotationMatrix2D()

使用したバージョン:Python 3.8.8 / OpenCV 4.0.1

0 件のコメント:

コメントを投稿