note.nkmk.me

OpenCV, NumPyで画像を回転・上下左右反転(rotate, flipなど)

Date: 2019-06-20 / tags: Python, OpenCV, NumPy, 画像処理

PythonのOpenCVでは画像をNumPy配列ndarrayとして扱う。画像(= ndarray)を回転または上下左右に反転(ミラー反転)するための関数はOpenCVにもNumPyにもあり、どちらを使ってもよい。

ここでは以下の内容について説明する。

  • OpenCVで画像を回転: cv2.rotate()
  • OpenCVで画像を上下左右に反転: cv2.flip()
  • NumPyで画像を回転: np.rot90()
  • NumPyで画像を上下左右に反転: np.flip()

NumPyでの画像処理についての基本は以下の記事を参照。OpenCVを使わずにPillow(PIL)で画像ファイルを読み込んでndarrayに変換する方法や、ndarrayを画像ファイルとして保存する方法などもこちら。

OpenCVでの画像の読み書きについては以下の記事を参照。

また、Pillow(PIL)を使って画像の回転・反転をすることもできる。単純に既存の画像ファイルを読み込んで回転・反転して保存するだけならPillowが一番シンプルで簡単。90度刻みではなく任意の角度で回転可能。

サンプルコードでは以下の画像を例として使う。

lena

スポンサーリンク

OpenCVで画像を回転: cv2.rotate()

OpenCVで画像(= ndarray)を回転する関数はcv2.rotate()

第一引数に元のndarray、第二引数rotateCodeに回転の角度と方向を定数で指定する。

rotateCodeに指定できる定数は以下の三種類。

  • cv2.ROTATE_90_CLOCKWISE: 時計回りに90度
  • cv2.ROTATE_90_COUNTERCLOCKWISE: 反時計回りに90度
  • cv2.ROTATE_180: 180度

サンプルコードと結果は以下の通り。

import cv2

img = cv2.imread('data/src/lena.jpg')
print(type(img))
# <class 'numpy.ndarray'>

print(img.shape)
# (225, 400, 3)

img_rotate_90_clockwise = cv2.rotate(img, cv2.ROTATE_90_CLOCKWISE)
cv2.imwrite('data/dst/lena_cv_rotate_90_clockwise.jpg', img_rotate_90_clockwise)
# True

img_rotate_90_counterclockwise = cv2.rotate(img, cv2.ROTATE_90_COUNTERCLOCKWISE)
cv2.imwrite('data/dst/lena_cv_rotate_90_counterclockwise.jpg', img_rotate_90_counterclockwise)
# True

img_rotate_180 = cv2.rotate(img, cv2.ROTATE_180)
cv2.imwrite('data/dst/lena_cv_rotate_180.jpg', img_rotate_180)
# True

OpenCV rotate ROTATE_90_CLOCKWISE

OpenCV rotate ROTATE_90_COUNTERCLOCKWISE

OpenCV rotate ROTATE_180

90度刻みではなく任意の角度で回転したい場合はアフィン変換cv2.warpAffine()を使う。

OpenCVで画像を上下左右に反転: cv2.flip()

OpenCVで画像(= ndarray)を上下左右に反転する関数はcv2.flip()

第一引数に元のndarray、第二引数flipCodeに反転方向を示す値を指定する。

flipCodeの値によって以下のように反転する。

  • flipcode = 0: 上下反転
  • flipcode > 0: 左右反転
  • flipcode < 0: 上下左右反転

サンプルコードと結果は以下の通り。

import cv2

img = cv2.imread('data/src/lena.jpg')
print(type(img))
# <class 'numpy.ndarray'>

print(img.shape)
# (225, 400, 3)

img_flip_ud = cv2.flip(img, 0)
cv2.imwrite('data/dst/lena_cv_flip_ud.jpg', img_flip_ud)
# True

img_flip_lr = cv2.flip(img, 1)
cv2.imwrite('data/dst/lena_cv_flip_lr.jpg', img_flip_lr)
# True

img_flip_ud_lr = cv2.flip(img, -1)
cv2.imwrite('data/dst/lena_cv_flip_ud_lr.jpg', img_flip_ud_lr)
# True

OpenCV flip UP / DOWN

OpenCV flip LEFT / RIGHT

OpenCV flip UP / DOWN, LEFT / RIGHT

NumPyで画像を回転: np.rot90()

NumPyでndarrayを回転する関数はnp.rot90()

第一引数に元のndarray、第二引数に何回90度回転するかの値を指定する。

第二引数を省略した場合はデフォルトの反時計回りに90度回転となり、第二引数を2, 3とすると反時計回りに180度回転、270度回転となる。詳細は以下の記事を参照。

サンプルコードと結果は以下の通り。

import numpy as np
from PIL import Image

img = np.array(Image.open('data/src/lena.jpg'))
print(type(img))
# <class 'numpy.ndarray'>

print(img.shape)
# (225, 400, 3)

Image.fromarray(np.rot90(img)).save('data/dst/lena_np_rot90.jpg')

Image.fromarray(np.rot90(img, 2)).save('data/dst/lena_np_rot90_180.jpg')

Image.fromarray(np.rot90(img, 3)).save('data/dst/lena_np_rot90_270.jpg')

numpy rot90 image

numpy rot90 180 image

numpy rot90 270 image

なお、ここではPillow(PIL)を使って画像ファイルを読み書きしているが、あくまでもndarrayを回転しているだけなので、上の例のようにOpenCVで読み書きする場合にOpenCVの関数ではなくNumPyの関数を使って回転の処理を行うこともできる。次の反転の例でも同様。

NumPyで画像を上下左右に反転: np.flip()

NumPyでndarrayを上下左右に反転する関数はnp.flip()。さらに、上下に反転するnp.flipud()、左右に反転するnp.fliplr()もある。

np.flip()の引数を指定すれば上下反転も左右反転も可能だが、np.flipud(), np.fliplr()を使ったほうが簡単。上下左右どちらも反転したい場合はnp.flip()を使う必要がある。詳細は以下の記事を参照。

サンプルコードと結果は以下の通り。

import numpy as np
from PIL import Image

img = np.array(Image.open('data/src/lena.jpg'))
print(type(img))
# <class 'numpy.ndarray'>

print(img.shape)
# (225, 400, 3)

Image.fromarray(np.flipud(img)).save('data/dst/lena_np_flipud.jpg')

Image.fromarray(np.fliplr(img)).save('data/dst/lena_np_fliplr.jpg')

Image.fromarray(np.flip(img, (0, 1))).save('data/dst/lena_np_flip_ud_lr.jpg')

nupmy flipud image

nupmy fliplr image

nupmy flip image

スポンサーリンク
シェア
このエントリーをはてなブックマークに追加

関連カテゴリー

関連記事