【Python/OpenCV】アフィン変換で画像の回転

この記事では、Python版OpenCVとNumPyを用いてアフィン変換を実装し、画像を回転させる方法をソースコード付きで解説します。

アフィン変換で画像の回転

アフィン変換とは、平行移動と線形変換を組み合わせた変換です。
つまり、アフィン変換で画像の拡大・縮小、回転、移動などを行うことができます。
今回はPython + OpenCV + NumPyでアフィン変換を実装し、画像を回転させてみました。

関連記事
原理の詳細 【画像処理】アフィン変換による回転の原理・計算式
OpenCVの導入方法 【Python3】OpenCV3をインストール
Python版OpenCVまとめ Python版OpenCV入門 サンプル集
Pythonで画像処理まとめ 【Python】画像処理プログラミング入門
画像処理の原理まとめ 【画像処理入門】アルゴリズム&プログラミング

ソースコード(Python3+OpenCV3)

サンプルプログラムのソースコードです。

方法①NumPyで実装

# -*- coding: utf-8 -*-
import cv2
import numpy as np

# アフィン変換で画像配列の回転
def rotate_affine(src, theta, tx=0, ty=0):

    # 元画像のサイズを取得
    h, w = src.shape[0], src.shape[1]

    # 出力画像用の配列生成(要素は全て0)
    dst = np.zeros((h,w))
    
    # degreeかrradianに変換
    rd = np.radians(theta)
    
    # アフィン変換
    for y in range(0, h):
        for x in range(0, w):
            xi = (x - tx)*np.cos(rd) - (y - ty)*np.sin(rd) + tx
            yi = (x - tx)*np.sin(rd) + (y - ty)*np.cos(rd) + ty
            xi = int(xi)
            yi = int(yi)

            # 変換後の座標が範囲外でなければ出力画像配列に画素値を代入
            if yi < h - 1 and xi < w -1 and yi > 0 and xi > 0:
                dst[y][x] = src[yi][xi]

    return dst


def main():
    # 入力画像の読み込み
    img = cv2.imread("input.png")

    # グレースケール変換
    gray = cv2.cvtColor(img, cv2.COLOR_BGR2GRAY)

    theta = 45 # 回転角

    # 画像の中心座標
    oy, ox = int(gray.shape[0]/2), int(gray.shape[1]/2)

    # 方法1(NumPy)
    dst = rotate_affine(gray, theta, ox, oy)

    # 結果を出力
    cv2.imwrite("output.png", dst1)


if __name__ == "__main__":
    main()

方法②OpenCVで実装

# -*- coding: utf-8 -*-
import cv2
import numpy as np

def main():
    # 入力画像の読み込み
    img = cv2.imread("input.png")

    # グレースケール変換
    gray = cv2.cvtColor(img, cv2.COLOR_BGR2GRAY)

    theta = 45 # 回転角
    scale = 1.0    # 回転角度・拡大率

    # 画像の中心座標
    oy, ox = int(gray.shape[0]/2), int(gray.shape[1]/2)

    # 方法2(OpenCV)
    R = cv2.getRotationMatrix2D((ox, oy), theta, scale)    # 回転変換行列の算出
    dst = cv2.warpAffine(gray, R, gray.shape, flags=cv2.INTER_CUBIC)    # アフィン変換

    # 結果を出力
    cv2.imwrite("output.png", dst)


if __name__ == "__main__":
    main()

実行結果

サンプルプログラムの実行結果です。

■入力画像(左)と出力画像(右)

関連記事
1 PythonでOpenCV入門 サンプル集
2 【Python】画像処理プログラミング入門
3 【画像処理入門】アルゴリズム&プログラミング

シェア&フォローお願いします!