【python】opencvライブラリで画像編集する方法

本ページには PR が含まれます。

この記事ではopencvライブラリを用いた画像編集の実装方法をわかりやすく解説します。

主に画像のリサイズ・トリミング・回転について詳しく解説していきます。

サンプルコードをコピペしながらサクサク処理を試せますので、 ぜひ活用してみてください。


opencvライブラリの基礎的な使い方についてはこちら

目次

画像の読み込み

まずはじめに編集する画像を読み込みます。

opencvライブラリにおける画像の読み込みはcv2.imread()メソッドを使用します。

# -*- coding: utf-8 -*-
import cv2

# 画像ファイル("mtrainier.jpg")を読み込み
img = cv2.imread("mtrainier.jpg")
画像ファイル"mtrainier.jpg"

今回は右図のような画像ファイルを読み込みます。


画像のリサイズ cv2.resize()

画像を拡大・縮小(リサイズ)するにはcv2.resize()メソッドを使用します。

cv2.resize(画像オブジェクト, リサイズ後の画像サイズ)

のように引数をそれぞれ指定して、画像サイズを拡大・縮小できます。


cv2.resize()メソッドの代表的な引数と意味は以下の通りです。

引数名意味指定する値の例
src入力画像numpy.ndarray型の画像
dsizeリサイズ後の画像サイズ(100, 500)などのタプル型(要素はint型)
fx水平方向の倍率0.3, 0.75, 1.2などのfloat型
fy垂直方向の倍率0.3, 0.75, 1.2などのfloat型
interpolation補完手法の種類cv2.INTER_LINEAR, cv2.INTER_NEAREST,
cv2.INTER_CUBIC, cv2.INTER_AREA,
cv2.INTER_LANCZOS4
# -*- coding: utf-8 -*-
import cv2

# 画像の読み込み
img = cv2.imread("mtrainier.jpg")

# 画像をリサイズ
img_resize1 = cv2.resize(img, dsize=(500, 700))
img_resize2 = cv2.resize(img, dsize=None, fx=0.75, fy=0.25)

# 画像を表示
cv2.imshow("Mt.rainier", img_resize1)
cv2.waitKey(0)
cv2.imshow("Mt.rainier", img_resize2)
cv2.waitKey(0)
# キーボードが押されたらウィンドウを閉じる
cv2.destroyAllWindows()

このように画像の大きさを変更することができます。


画像の方向を反転 cv2.flip()

画像の向きを垂直方向・水平方向に反転するにはcv2.flip()メソッドを使用します。

cv2.flip(画像オブジェクト, 反転方向)

のように引数をそれぞれ指定して画像をフリップ(反転)します。


反転方向の引数flipCodeに指定する値と意味は以下の通りです。なお、指定する値はint型です。

引数flipCode意味
0x軸周りで反転(上下を反転)
0より大きいy軸周りで反転(左右を反転)
0より小さい両方の軸周りで反転(上下左右を反転)
# -*- coding: utf-8 -*-
import cv2

# 画像の読み込み
img = cv2.imread("mtrainier.jpg")
img = cv2.circle(img, center=(int(img.shape[0]/8), int(img.shape[1]/8)), color=(125,0,255), radius=250, thickness=-1)

# 画像をフリップ
img_flip1 = cv2.flip(img, flipCode=0)
img_flip2 = cv2.flip(img, flipCode=1)
img_flip3 = cv2.flip(img, flipCode=-1)

# 画像を表示
cv2.imshow("Mt.rainier", img)
cv2.waitKey(0)
cv2.imshow("Mt.rainier", img_flip1)
cv2.waitKey(0)
cv2.imshow("Mt.rainier", img_flip2)
cv2.waitKey(0)
cv2.imshow("Mt.rainier", img_flip3)
cv2.waitKey(0)
# キーボードが押されたらウィンドウを閉じる
cv2.destroyAllWindows()
基準画像
flipCode=0
上下反転
flipCode=1
左右反転
flipCode=-1
上下左右反転

このように反転方向を指定して、画像をフリップすることができます。

画像を回転

画像を任意の角度だけ回転させるにはcv2.getRotationMatrix2D()メソッドとcv2.warpAffine()メソッドを組み合わせて使用します。

回転の中心座標と回転角、拡大縮小倍率をあらかじめcv2.getRotationMatrix2D()メソッドで設定し、その戻り値をcv2.warpAffine()メソッドで適用して画像を回転させます。

画像回転の事前設定 cv2.getRotationMarix2D()

あらかじめ、回転に関する設定を

cv2.getRotationMatrix2D(center, angle, scale)

のように、それぞれ引数で指定して決定します。


引数の意味と指定する値の例は以下の通りです。

引数名意味指定する値の例
center回転の中心座標(100, 500)などのタプル型(要素はint型)
angle回転角[deg]45.0, 90などのfloat型
scale拡大縮小倍率1.0, 0.75, 1.5などのfloat型

画像回転を実装 cv2.wrapAffine()メソッド

画像回転はcv2.wrapAffine()メソッドを

cv2.wrapAffine(src, M, flags, borderMode, borderValue)

のように指定して、回転を実装します。


引数の意味と指定する値の例は以下の通りです。

引数名意味指定する値の例
src入力画像numpy.ndarray型の画像
M回転設定cv2.getRotationMatrix2D()メソッドの戻り値
flags補間処理の種類cv2.INTER_NEAREST, cv2.INTER_LINEAR(デフォルト),
cv2.INTER_CUBIC, cv2.INTER_LANCZOS4
borderMode画像領域外の処理の種類cv2.BORDER_CONSTANT(デフォルト), cv2.BORDER_REPLICATE,
cv2.BORDER_REFLECT, cv2.BORDER_WRAP,
cv2.BORDER_REFLECT_101, cv2.BORDER_TRANSPARENT
borderValue領域外の色(255, 0, 255)などのbgrタプル型(rbgでないことに注意)
※引数borderModecv2.BORDER_CONSTANTの場合のみ指定
# -*- coding: utf-8 -*-
import cv2

# 画像の読み込み
img = cv2.imread("mtrainier.jpg")

# 画像の回転設定
rotation_angle1 = cv2.getRotationMatrix2D(center=(int(img.shape[0]/2),int(img.shape[1]/2)), angle=45, scale=1)
rotation_angle2 = cv2.getRotationMatrix2D(center=(int(img.shape[0]/3),int(img.shape[1]/3)), angle=15, scale=0.25)
rotation_angle3 = cv2.getRotationMatrix2D(center=(int(img.shape[0]/2),int(img.shape[1]/5)), angle=75, scale=0.5)

# 画像を回転(補間方法を設定)
img_affine1 = cv2.warpAffine(img, M=rotation_angle1, dsize=(img.shape[0], img.shape[1]), borderValue=(200, 255, 0))
img_affine2 = cv2.warpAffine(img, M=rotation_angle2, dsize=(img.shape[0], img.shape[1]), borderMode=cv2.BORDER_WRAP)
img_affine3 = cv2.warpAffine(img, M=rotation_angle3, dsize=(img.shape[0], img.shape[1]), borderMode=cv2.BORDER_TRANSPARENT, dst=img//4)

# 画像を表示
cv2.imshow("Mt.rainier", img_affine1)
cv2.waitKey(0)
cv2.imshow("Mt.rainier", img_affine2)
cv2.waitKey(0)
cv2.imshow("Mt.rainier", img_affine3)
cv2.waitKey(0)
# キーボードが押されたらウィンドウを閉じる
cv2.destroyAllWindows()
基準画像
背景色あり
画像を連結して補間
背景画像で陰影

画像を回転させつつ、背景の設定や補間設定を指定することができます。


画像を透視投影

画像の透視投影にはcv2.getPerspectiveTransform()メソッドとcv2.warpPerspective()メソッドを組み合わせて使用します。

あらかじめcv2.getPerspectiveTransform()メソッドで透視変換の設定を行い、その戻り値を用いてcv2.warpPerspective()メソッドで透視投影を行います。

透視変換の事前設定 cv2.getPerspectiveTransform()

透視変換を設定するには

cv2.getPerspectiveTransform(src, dst)

のように、それぞれに引数を指定します。


引数の意味と指定する値の例は以下の通りです。

引数名意味指定する値の例
src入力画像の4頂点座標[[0,0], [1000,0], [1000,1500], [0,1500]]などのnumpy.ndarray配列
(要素数4)
dst出力画像の4頂点座標[[0,0], [100,0], [100,500], [0,500]]などのnumpy.ndarray配列
(要素数は4)

透視投影を実装 cv2.warpPerspective()

透視投影はcv2.wrapPerspective()メソッドを

cv2.wrapAffine(src, M, flags, borderMode, borderValue)

のように指定して、回転を実装します。


引数の意味と指定する値の例は以下の通りです。

引数名意味指定する値の例
src入力画像numpy.ndarray型の画像
M透視変換設定cv2.getPerspectiveTransform()メソッドの戻り値
flags補間処理の種類cv2.INTER_NEAREST, cv2.INTER_LINEAR(デフォルト),
cv2.INTER_CUBIC, cv2.INTER_LANCZOS4
borderMode画像領域外の処理の種類cv2.BORDER_CONSTANT(デフォルト), cv2.BORDER_REPLICATE,
cv2.BORDER_REFLECT, cv2.BORDER_WRAP,
cv2.BORDER_REFLECT_101, cv2.BORDER_TRANSPARENT
borderValue領域外の色(255, 0, 255)などのbgrタプル型(rbgでないことに注意)
※引数borderModecv2.BORDER_CONSTANTの場合のみ指定
# -*- coding: utf-8 -*-
import cv2
import numpy as np

# 画像の読み込み
img = cv2.imread("mtrainier.jpg")

x0 = img.shape[0]/6
x1 = img.shape[0]*4/6
y0 = img.shape[1]/6
y1 = img.shape[1]*4/6

x_margin = img.shape[0]/8
y_margin = img.shape[1]/8
input_corner = np.float32([[x0,y0], [x0,y1], [x1,y1], [x1,y0]])

# 透視変換
output_corner = np.float32([[x0,y0], [x0,y1], [x1-x_margin,y1-y_margin], [x1-x_margin,y0+y_margin]])
pers = cv2.getPerspectiveTransform(src=input_corner, dst=output_corner)

# 画像を透視投影
img_pers1 = cv2.warpPerspective(img, M=pers, dsize=(img.shape[0], img.shape[1]), borderValue=(200, 255, 0))
img_pers2 = cv2.warpPerspective(img, M=pers, dsize=(img.shape[0], img.shape[1]), borderMode=cv2.BORDER_WRAP)
img_pers3 = cv2.warpPerspective(img, M=pers, dsize=(img.shape[0], img.shape[1]), borderMode=cv2.BORDER_TRANSPARENT, dst=img//4)

# 画像を表示
cv2.imshow("Mt.rainier", img_pers1)
cv2.waitKey(0)
cv2.imshow("Mt.rainier", img_pers2)
cv2.waitKey(0)
cv2.imshow("Mt.rainier", img_pers3)
cv2.waitKey(0)
# キーボードが押されたらウィンドウを閉じる
cv2.destroyAllWindows()
背景色あり
画像を連結して補間
背景画像で陰影

背景の補間方法を指定して、画像を透視投影することができます。


画像をトリミング

画像をトリミングするには画像のnumpy.ndarray配列の要素の範囲を指定します。

img[縦方向の範囲, 横方向の範囲]

のように配列のスライスを使って画像範囲を指定します。

# -*- coding: utf-8 -*-
import cv2

# 画像の読み込み
img = cv2.imread("mtrainier.jpg")

x0 = int(img.shape[0]/6)
x1 = int(img.shape[0]*4/6)
y0 = int(img.shape[1]/6)
y1 = int(img.shape[1]*4/6)

# 画像をトリミング
img_trim = img[y0:y1, x0:x1]

# 画像を表示
cv2.imshow("Mt.rainier", img_trim)
cv2.waitKey(0)
# キーボードが押されたらウィンドウを閉じる
cv2.destroyAllWindows()
基準画像
トリミング後

任意の画像領域をトリミングすることができます。


まとめ

今回はpythonのopencvライブラリを使った画像編集の方法を具体的に紹介しました。

他にもopencvライブラリに関する記事がありますのでぜひ参考にしてみてください。

よかったらシェアしてね!
目次