【Python/OpenCV】画像のサイズ変更(バイリニア補間法)

この記事では、Python版OpenCVのcv2resizeでバイリニア補間法を実装し、画像のサイズを変更(拡大・縮小)する方法をソースコード付きで解説します。

画像のリサイズ(バイリニア補間法)

画像を拡大・縮小するときの画素の埋め方の1つに「バイリニア補間法」があります。
原理については「バイリニア補間法による画像拡大の原理」で紹介しています。

今回は、以下の2通りの方法で処理を実装してみました。

方法①・・・NumPyでアルゴリズムを書いて実装
方法②・・・OpenCV(cv2.resize)で実装

cv2.resize

dst = cv2.resize(src, dsize[, interpolation])
パラメータ名 説明
src 入力画像
dsize 変更後の画像サイズ
interpolation 補間法(バイリニア補間ならcv2.INTER_LINEAR)
dst 出力画像

ソースコード(Python3+OpenCV3)

サンプルプログラムのソースコードです。(画像サイズを2倍)

方法①

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

# バイリニア補間法でリサイズ
def resize_bilinear(src, hd, wd):

    # 出力画像用の配列生成(要素は全て空)
    dst = np.empty((hd,wd))

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

    # 拡大率を計算
    ax = wd / float(w)
    ay = hd / float(h)
    
    # バイリニア補間法
    for yd in range(0, hd):
        for xd in range(0, wd):
            x, y = xd/ax, yd/ay
            ox, oy = int(x), int(y)

             # 存在しない座標の処理
            if ox > w - 2: ox = w - 2
            if oy > h - 2: oy = h - 2
            
            # 重みの計算
            dx = x - ox
            dy = y - oy
            
            # 出力画像の画素値を計算
            dst[yd][xd] = (1 - dx) * (1-dy) * src[oy][ox] + dx * (1-dy) * src[oy][ox+1] + (1-dx) * dy * src[oy][ox+1] + dx * dy * src[oy+1][ox+1]
            
    return dst


def main():

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

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

    # 方法1(NumPy)
    dst1 = resize_bilinear(gray, gray.shape[1]*2, gray.shape[0]*2)

    # 結果を出力
    cv2.imwrite("output1.jpg", dst1)


if __name__ == "__main__":
    main()

方法②

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

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

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

    # 方法2(OpenCV)
    dst2 = cv2.resize(gray, (gray.shape[1]*2, gray.shape[0]*2), interpolation=cv2.INTER_LINEAR)

    # 結果を出力
    cv2.imwrite("output2.jpg", dst2)


if __name__ == "__main__":
    main()

※動作には、OpenCVライブラリのインストールが必要です。

実行結果

サンプルプログラムの実行結果です。
■入力画像(左)と出力画像(右)

最近傍補間法でリサイズした時に比べて輪郭のギザギザが滑らかになっていることがわかります。

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