はじめに
OpenCVは、画像処理における強力なツールですが、初めて使う人にとっては多くの機能があり、最初は戸惑うことがあります。この記事では、OpenCVの中でも基本的な機能であるcv2.resize
関数に焦点を当て、その使い方を解説します。
画像のサイズ変更
画像のサイズ変更はcv2.resize
関数を使います。
拡大・縮小のいずれも対応していて、補間方法を選択することも可能です。
変更するサイズの指定方法は縦横のサイズを指定する方法と縦横の倍率を指定する2通りの方法があります。
cv2.resize関数
引数
名称 | 説明 |
入力画像(必須) | 入力画像 |
dsize(必須) | 画像のサイズを(横サイズ, 縦サイズ)の様にタプルで指定。整数のみ。 |
dst(オプション) | 結果がこの変数に格納されます。指定しない場合は、入力画像と同じサイズ・型で新しい配列が作成されて結果が格納され、戻り値として取得できます。 |
fx(オプション) | 水平方向の倍率係数。0の場合はdsize値から自動計算されます。 |
fy(オプション) | 垂直方向の倍率係数。0の場合はdsize値から自動計算されます。 |
interpolation(オプション) | 補間方法(InterpolationFlags)の指定(デフォルト:cv2.INTER_LINEAR ) |
引数のInterpolationは以下の様に定義されています。
補間方法 | 説明 |
cv2.INTER_NEAREST | 最近傍法(ニアレストネイバー法) |
cv2.INTER_LINEAR | バイリニア補間法 |
cv2.INTER_CUBIC | バイキュービック補間法 |
cv2.INTER_AREA | ピクセル領域の関係を使用したリサンプリングを行います。 画像の縮小した場合にモアレのない結果となり、画像を拡大した場合には、cv2.INTER_NEARESTに似た結果となります。 |
cv2.INTER_LANCZOS4 | 8x8近傍に対するのLanczos補間法。 |
cv2.INTER_LINEAR_EXACT | Bit exact バイリニア補間法。 |
cv2.INTER_NEAREST_EXACT | Bit exact 最近傍法。この方法はPIL, scikit-imageまたはMatlabの最近傍法と同じ結果となります。 |
戻り値
サイズ変更後の画像データ(numpy.ndarray)
使い方
縦横のサイズを指定する方法
以下のコードでは横方向のサイズ取得して2倍にした値を設定し、横方向のサイズを変更します。
# 画像を読み込み image = cv2.imread("image.jpg") # 画像のサイズを取得 h, w = image.shape[:2] # 画像のサイズを指定:幅を2倍にリサイズ result = cv2.resize(image, (w * 2, h))
縦横の倍率を指定する方法
以下のコードでは縦方向の倍率を2倍に設定し、縦方向のサイズを変更します。
# 画像を読み込み image = cv2.imread("image.jpg") # 画像のサイズの倍率を指定:高さを2倍にリサイズ result = cv2.resize(image, None, fx=1, fy=2)
補間方法について
各種補完方法の差異について確認しました。以下に各補間方法の結果を示します。
縦横サイズを1/2に縮小した後、元のサイズに戻しています。
個人的な感想ですが、cv2.INTER_NEAREST
とcv2.INTER_NEAREST_EXACT
が画像の劣化が少ない様です。
cv2.INTER_NEAREST |
cv2.INTER_LINEAR |
cv2.INTER_CUBIC |
cv2.INTER_AREA |
cv2.INTER_LANCZOS4 |
cv2.INTER_LINEAR_EXACT |
cv2.INTER_NEAREST_EXACT |
サンプルコード
ここまでに紹介したリサイズ処理のすべてのサンプルコードは下になります。
import cv2 # 画像の読み込み image = cv2.imread("image.jpg") # 画像のサイズを指定:幅を2倍にリサイズ h, w = image.shape[:2] result = cv2.resize(image, (w * 2, h)) cv2.imwrite("画像のサイズを指定:幅を2倍.jpg", result) # 画像のサイズの倍率を指定:高さを2倍にリサイズ result = cv2.resize(image, None, fx=1, fy=2) cv2.imwrite("画像のサイズの倍率を指定:高さを2倍.jpg", result) # 補間方法の比較:縦横を1/2に縮小後、縦横を2倍に拡大して元のサイズに戻して補間方法の結果を確認 h, w = image.shape[:2] x_scale1 = 0.5 y_scale1 = 0.5 x_scale2 = 2.0 y_scale2 = 2.0 # INTER_NEAREST result = cv2.resize(image, None, fx=x_scale1, fy=y_scale1, interpolation=cv2.INTER_NEAREST) result = cv2.resize(image, None, fx=x_scale2, fy=y_scale2, interpolation=cv2.INTER_NEAREST) cv2.imwrite("resize_INTER_NEAREST.jpg", result) # INTER_LINEAR result = cv2.resize(image, None, fx=x_scale1, fy=y_scale1, interpolation=cv2.INTER_LINEAR) result = cv2.resize(image, None, fx=x_scale2, fy=y_scale2, interpolation=cv2.INTER_LINEAR) cv2.imwrite("resize_INTER_LINEAR.jpg", result) # INTER_CUBIC result = cv2.resize(image, None, fx=x_scale1, fy=y_scale1, interpolation=cv2.INTER_CUBIC) result = cv2.resize(image, None, fx=x_scale2, fy=y_scale2, interpolation=cv2.INTER_CUBIC) cv2.imwrite("resize_INTER_CUBIC.jpg", result) # INTER_AREA result = cv2.resize(image, None, fx=x_scale1, fy=y_scale1, interpolation=cv2.INTER_AREA) result = cv2.resize(image, None, fx=x_scale2, fy=y_scale2, interpolation=cv2.INTER_AREA) cv2.imwrite("resize_INTER_AREA.jpg", result) # INTER_LANCZOS4 result = cv2.resize(image, None, fx=x_scale1, fy=y_scale1, interpolation=cv2.INTER_LANCZOS4) result = cv2.resize(image, None, fx=x_scale2, fy=y_scale2, interpolation=cv2.INTER_LANCZOS4) cv2.imwrite("resize_INTER_LANCZOS4.jpg", result) # INTER_LINEAR_EXACT result = cv2.resize(image, None, fx=x_scale1, fy=y_scale1, interpolation=cv2.INTER_LINEAR_EXACT) result = cv2.resize(image, None, fx=x_scale2, fy=y_scale2, interpolation=cv2.INTER_LINEAR_EXACT) cv2.imwrite("resize_INTER_LINEAR_EXACT.jpg", result) # INTER_NEAREST_EXACT result = cv2.resize(image, None, fx=x_scale1, fy=y_scale1, interpolation=cv2.INTER_NEAREST_EXACT) result = cv2.resize(image, None, fx=x_scale2, fy=y_scale2, interpolation=cv2.INTER_NEAREST_EXACT) cv2.imwrite("resize_INTER_NEAREST_EXACT.jpg", result)
おわりに
画像のサイズ変更は比較的利用頻度が高い機能ではないでしょうか。
本記事では補完方法の違いについて画像を載せていますが、口元の白いヒゲの表現でそれらの違いがわかるのではないでしょうか。
個人的な感想ではcv2.INTER_LINEAR
とcv2.INTER_LINEAR_EXACT
はやや劣化しているように思いました。
また、画像の種類によってアルゴリズムの差が出にくいこともあるような気がします。
サンプルコードで使った、画像の書き出し方法についてはこちらの記事を参考にして下さい。
最後までご覧頂きありがとうございました。
■(広告)OpenCVの参考書としてどうぞ!■
参考リンク
OpenCV: Resize
Changes the number of matrix rows.