今でもちょいちょい見られている投稿のようなので、少々更新します。
以下のリポジトリで画像重ね合わせ用のクラスを公開しています。
元投稿の処理では全範囲の貼り付けを行っており処理が重いため、
該当部分のコピーのみに処理を変更しています。
当時の投稿は以下に残しています。
もはや、タイトルが詐欺くさい気がしないでもないです(第2弾
⇒第1弾:【OpenCV】【Python】画像上に日本語のテキストを描画
OpenCV単体だと、ちょっとだけ面倒なのでPillow(PIL)を利用しております。
画像に透過付き画像を重ねたいことが、ちょいちょいあるのですが、
パッと思いつく範囲で以下のような対応があります(大変な順に。。。
・αチャンネルを元にマスク画像を生成し、マスク画像で切り抜いた画像を重ねる
・Pillow等の他ライブラリを用いて画像を重ねる
今回はパッと表示したいだけだったので、Pillowを利用します。
ソースコードは以下。
CvOverlayImage.py
#!/usr/bin/env python
# -*- coding: utf-8 -*-
import cv2 as cv
import numpy as np
from PIL import Image
class CvOverlayImage(object):
"""
[summary]
OpenCV形式の画像に指定画像を重ねる
"""
def __init__(self):
pass
@classmethod
def overlay(
cls,
cv_background_image,
cv_overlay_image,
point,
):
"""
[summary]
OpenCV形式の画像に指定画像を重ねる
Parameters
----------
cv_background_image : [OpenCV Image]
cv_overlay_image : [OpenCV Image]
point : [(x, y)]
Returns : [OpenCV Image]
"""
overlay_height, overlay_width = cv_overlay_image.shape[:2]
# OpenCV形式の画像をPIL形式に変換(α値含む)
# 背景画像
cv_rgb_bg_image = cv.cvtColor(cv_background_image, cv.COLOR_BGR2RGB)
pil_rgb_bg_image = Image.fromarray(cv_rgb_bg_image)
pil_rgba_bg_image = pil_rgb_bg_image.convert('RGBA')
# オーバーレイ画像
cv_rgb_ol_image = cv.cvtColor(cv_overlay_image, cv.COLOR_BGRA2RGBA)
pil_rgb_ol_image = Image.fromarray(cv_rgb_ol_image)
pil_rgba_ol_image = pil_rgb_ol_image.convert('RGBA')
# composite()は同サイズ画像同士が必須のため、合成用画像を用意
pil_rgba_bg_temp = Image.new('RGBA', pil_rgba_bg_image.size,
(255, 255, 255, 0))
# 座標を指定し重ね合わせる
pil_rgba_bg_temp.paste(pil_rgba_ol_image, point, pil_rgba_ol_image)
result_image = \
Image.alpha_composite(pil_rgba_bg_image, pil_rgba_bg_temp)
# OpenCV形式画像へ変換
cv_bgr_result_image = cv.cvtColor(
np.asarray(result_image), cv.COLOR_RGBA2BGRA)
return cv_bgr_result_image
使用例は以下。
例では、いらすとや様の画像を使用しております。
if __name__ == '__main__':
cv_background_image = cv.imread("bg_takeyabu_layer2.jpg")
cv_overlay_image = cv.imread(
"ninja_hashiru.png",
cv.IMREAD_UNCHANGED) # IMREAD_UNCHANGEDを指定しα込みで読み込む
cv_overlay_image = cv.resize(cv_overlay_image, (100, 100))
point = (550, 250)
image = CvOverlayImage.overlay(cv_background_image, cv_overlay_image,
point)
cv.imshow("sample", image)
cv.waitKey(0)
以上。