アルファチャンネルを使い輪郭と輪郭以外の画像を作りました。
今回はその二つの画像を重ね合わせて元画像にしてみたいと思います。
Python画像にアルファチャンネルを追加してみる。
Laplacianフィルタで輪郭を抽出してみました。こちらの画像をアルファチャンネルとして元の画像と重ね合わせてみます。#!/usr/bin/env python3# coding: utf8# 画像にアルファチャンネルを追加import ...
今回はその二つの画像を重ね合わせて元画像にしてみたいと思います。
#!/usr/bin/env python3
# coding: utf8
# 2つの画像を重ね合わせる
import cv2
import numpy as np
# 画像ファイルを読み込む(32bitRGBA)
im = cv2.imread('rgba.png', cv2.IMREAD_UNCHANGED)
# 画像ファイルを読み込む(32bitRGBA)
im2 = cv2.imread('rgba2.png', cv2.IMREAD_UNCHANGED)
# 重ね合わせ
rgb = im[:,:,:3]
a = im[:,:,3:]
rgb2 = im2[:,:,:3]
a2 = im2[:,:,3:]
dst = rgb * (a/255) + rgb2 * (a2/255)
# 結果を保存
cv2.imwrite('logo_dst.png', dst)
アルファチャンネルの値が0(透明)と255(不透明)だったので、255で割り、RGBに掛けることで不透明はそのままで、透明部分が0になります。両画像ファイルに同様の計算を施し、加算することで互いの透明部分(0)が補完されるようになります。
これだけだとアルファチャンネルを削除しても同じ結果になるので、少し色をいじってみます。
#!/usr/bin/env python3
# coding: utf8
# 2つの画像を重ね合わせる
import cv2
import numpy as np
# 画像ファイルを読み込む(32bitRGBA)
im = cv2.imread('rgba.png', cv2.IMREAD_UNCHANGED)
# 画像ファイルを読み込む(32bitRGBA)
im2 = cv2.imread('rgba2.png', cv2.IMREAD_UNCHANGED)
# 重ね合わせ
rgb = im[:,:,:3]
rgb = np.where(rgb == 0, 127, rgb) # 灰色
a = im[:,:,3:]
rgb2 = im2[:,:,:3]
rgb2[:,:,(0,1)] = np.where(rgb2[:,:,(0,1)] == 0, 200, rgb2[:,:,(0,1)]) # 水色
a2 = im2[:,:,3:]
dst = rgb * (a/255) + rgb2 * (a2/255)
# 結果を保存
cv2.imwrite('logo_dst.png', dst)
OpenCVのライブラリも強力なのですが、Numpyで配列に対し演算を簡潔に記述できる点が素晴らしいです。
Numpyなどのライブラリが無い場合ピクセル単位にアクセスして演算を施すわけですが、基本的にメモリの走査をすることになります。
そういった処理では、コンピュータよりのコードを生成できるC言語などで作成すると高速に処理できますが、スクリプト言語や中間コードで実行するタイプのプログラミング言語では実用的な速度を担保するのが難しいジャンルになります。
その点スクリプト言語でありながら高速な処理を担保しつつ完結に記述できるNumpyが使えるPythonが画像加工でよく使われる理由ではないかと考えます。
個人的にはC#とかでも使えるとよいのですが…
コメント