Python(OpenCV)透明画像の重ね合わせ

OpenCVで透明画像の重ね合わせ

===================

今回やること

左の “background.png” 画像に透明チャンネル付き “penguin.png” 画像を貼り付けて、下のような画像を作る。

background penguin
result

サンプルコード

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

def clip_alpha_image(x, y):
    # x, yで貼り付け位置を選択
    f_h, f_w, _ = foreground.shape
    # 透明部分が0、不透明部分が1のマスクを作る
    alpha_mask = np.ones((f_h, f_w)) - np.clip(cv2.split(foreground)[3], 0, 1)
    # 貼り付ける位置の背景部分
    target_background = background[y:y+f_h, x:x+f_w]
    # 各BRGチャンネルにalpha_maskを掛けて、前景の不透明部分が[0, 0, 0]のnew_backgroundを作る
    new_background = cv2.merge(list(map(lambda x: x * alpha_mask, cv2.split(target_background))))
    # BGRAをBGRに変換した画像とnew_backgroundを足すと合成できる
    background[y:y + f_h, x:x+f_w] = cv2.merge(cv2.split(foreground)[:3])

background = cv2.imread("background.png")
foreground = cv2.imread("penguin.png", -1)
clip_alpha_image(600, 250)
cv2.imwrite("result.png", background)

関数の説明

np.clip(array, min, max)

np.clip は array の値で min より小さい値は min に、 max より大きな値は max に変換した array を返します。

BGR = cv2.split(img)

cv2.split は img をチャンネル分解する関数です。 img が BGR (青緑赤) 画像のとき、 BGR[0] は青チャンネル、 BGR[1] は緑チャンネル、 BGR[2] は赤チャンネルとなるようなリストを返します。 RBG ではなく BGR となるところに注意が必要です。

img = cv2.merge(BGR)

cv2.merge は cv2.split の逆の処理を行う関数です。

コメント

タイトルとURLをコピーしました