↓もし、良かったらSNSでの紹介よろしくお願いします。

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

bootstrap

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]) + new_background
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の逆の処理を行う関数です。