アルファチャンネルつき png を透過画像で貼り付ける with Python/OpenCV
TL; DR
bg.jpg
の左上に、png_image.png
(アルファチャンネルつき画像)を重ねる場合のコードです。
import cv2
frame = cv2.imread("bg.jpg")
png_image = cv2.imread("alpha.png", cv2.IMREAD_UNCHANGED) # アルファチャンネル込みで読み込む
# 貼り付け先座標の設定。とりあえず左上に
x1, y1, x2, y2 = 0, 0, png_image.shape[1], png_image.shape[0]
# 合成!
frame[y1:y2, x1:x2] = frame[y1:y2, x1:x2] * (1 - png_image[:, :, 3:] / 255) + \
png_image[:, :, :3] * (png_image[:, :, 3:] / 255)
bg.jpg | alpha.png | result |
---|---|---|
簡単な解説
PNG ファイルには「アルファチャンネル」という各ピクセルの透明度を表すデータが入っています。値域は RGB と同じく 0-255 です。255 のときに 100% 有効で、0 のときに 0% (完全に透明)になります。
# 画像の読み込み
png_image = cv2.imread("alpha.png", cv2.IMREAD_UNCHANGED) # アルファチャンネル込みで読み込む
通常の cv2.imread()
では、[h, w, 3]
の numpy.ndarray
の形になりますが、 cv2.IMREAD_UNCHANGED
を指定して cv2.imread()
を呼び出すと、[h, w, 4]
の形になります。BGR
が BGRA
と、最後にアルファチャンネルがつきます。
画像を読み込めたら、合成します。といっても、NuPy の通常の行列演算で合成可能です。やっていることは、元々の背景画像・描画する画像を、それぞれアルファチャンネルの数値で配分して、足し合わせています。
# 合成!
frame[y1:y2, x1:x2] = frame[y1:y2, x1:x2] * (1 - png_image[:, :, 3:] / 255) + \
png_image[:, :, :3] * (png_image[:, :, 3:] / 255)
png_image[:, :, 3:]
がアルファチャンネルの取り出しです。アルファチャンネルの値域は 0-255 なので、255 で割って 0-1 の比率にします。描画する画像には計算した比率を掛け、背景のほうには比率の "残り" を掛けて、両者を足し合わせることで、最終的な画像を得ることが出来ます。
ちなみに、png_image[:, :, 3]
と書くと、行列のサイズが合わないと怒られるので注意してください(間違えた)。
余録
色々参考になるサイトはありつつ、そのものズバリなコードをうまく検索できなかったので、記事を作ってみました。(当たり前すぎてかえって書かなかったりするのかもしれませんね)
参考にさせてもらったサイト
画像は かわいいフリー素材集 いらすとや の素材を使わせてもらいました。
Author And Source
この問題について(アルファチャンネルつき png を透過画像で貼り付ける with Python/OpenCV), 我々は、より多くの情報をここで見つけました https://qiita.com/smatsumt/items/923aefb052f217f2f3c5著者帰属:元の著者の情報は、元のURLに含まれています。著作権は原作者に属する。
Content is automatically searched and collected through network algorithms . If there is a violation . Please contact us . We will adjust (correct author information ,or delete content ) as soon as possible .