Pynote

Python、機械学習、画像処理について

OpenCV - アルファブレンドで画像を合成する方法

アルファブレンドとは

アルファブレンド とは、2枚の画像を係数 \alpha を用いて、以下の式で合成する処理をいう。

 dst = src1 * \alpha + src2 * (1 - \alpha)

つまり、2枚の入力画像 src1, src2 の各画素値を \alpha : 1 - \alpha の割合で配合し、出力画像の画素値を生成する。
加算を行うので、2枚の入力画像の形状は同じでなければならない。

OpenCV を利用したアルファブレンド

OpenCV では、addWeighted() を利用する。

dst = cv2.addWeighted(src1, alpha, src2, beta, gamma[, dst[, dtype]])

この関数は以下の計算を行う。

dst = \verb|saturate_cast|(src1 * alpha + src2 * beta + gamma)

pynote.hatenablog.com

この関数で先程のアルファブレンドの式を計算するには、引数を alpha = \alpha, beta = 1 - \alpha, gamma = 0 とすればよい。

サンプルコード

使用する画像

import cv2
import matplotlib.pyplot as plt
import numpy as np

# 入力画像を読み込む。
img1 = cv2.imread('image1.jpg')
img2 = cv2.imread('image2.jpg')
# img1, img2 は同じ形状でなければならない。
print('img1.shape', img1.shape)  # img1.shape (500, 500, 3)
print('img2.shape', img2.shape)  # img2.shape (500, 500, 3)

alpha = 0.4
blended = cv2.addWeighted(img1, alpha, img2, 1 - alpha, 0)  # img1 * 0.4 + img2 * 0.6

plt.imshow(cv2.cvtColor(blended, cv2.COLOR_BGR2RGB))
plt.axis('off')
plt.show()

2枚の画像の画素が混合されていることがわかる。

矩形外をグレーアウトする。

アルファブレンドの応用例として、画像の注目領域以外をグレーアウトする例を示す。
先程の lena の画像を使用する。

import cv2
import numpy as np
import matplotlib.pyplot as plt

img = cv2.imread('image2.jpg')

入力画像の残す画素、グレーアウトする画像を定義するマスクを作成する。

# 入力画像の残す画素を (255, 255, 255), グレーアウトする画素を
# (0, 0, 0) で表したマスクを作成する。
mask = np.zeros_like(img)
cv2.rectangle(mask, (200, 200), (350, 400), (255, 255, 255), -1)

plt.imshow(mask)
plt.axis('off')
plt.show()

入力画像とマスクをアルファブレンドすることにより、グレーアウトする領域はマスクの黒と混合し、暗くなる。
一方、残したい領域はマスクの白と混合し、白くなってしまっている。

# 入力画像とマスクをアルファブレンドする。
blended = cv2.addWeighted(img, 0.4, mask, 0.3, 0)

plt.imshow(cv2.cvtColor(blended, cv2.COLOR_BGR2RGB))
plt.axis('off')
plt.show()

白くなってしまった画素だけ元の入力画像の画素を入れる。

# np.where() は、mask の値が255の要素 (残したい画素) は img の値、
# そうでない値 (グレーアウトしたい画素) は blended の値を返す。
result = np.where(mask == 255, img, blended)

plt.imshow(cv2.cvtColor(result, cv2.COLOR_BGR2RGB))
plt.axis('off')
plt.show()