新しく作った画像なんだけど、左上に別画像のロゴを入れたい…。
OpenCVで別の画像を合成することはできないの?
できますよ!
では今回は、「OpenCVで画像合成する(重ねる)方法」を
できるだけわかりやすく解説いたします。
また、「前面の画像を透過して合成する方法」や
「複数の画像を一括処理する方法」も解説いたしますので、
ぜひ最後まで読んでいってください。
OpenCVで画像を合成する(重ねる)方法
まずは背景画像「input_img_back」の上にロゴ画像「input_img_front」を重ねてみましょう。
重ねる位置の「座標」と「input_img_front」のサイズを指定して重ねます。
ひとまず全コードと実行結果をお見せします。
解説は後ほど行います。
全コード
import cv2
input_img_front = cv2.imread('C:/Utatane/input_img_front.jpg')
input_img_back = cv2.imread('C:/Utatane/input_img_back.jpg')
height, width = input_img_front.shape[:2]
x, y = 10, 20
input_img_back[y:y+height, x:x+width] = input_img_front
cv2.imwrite('C:/Utatane/output_img.jpg', input_img_back)
height, width = input_img_front.shape[:2]
x, y = 10, 20
input_img_back[y:y+height, x:x+width] = input_img_front
実行結果
事前準備
- OpenCVのインストール
画像を加工したり編集したりするには「OpenCV」のインストールが必要です。
OpenCVを初めて使用する場合は、下記コードを入力・実行して、インストールしてください。
pip install opencv-python
※OpenCVを使用したことがある場合は、このインストール作業は不要です。
解説
※わかりやすさを重視しております。厳密には解釈が異なる場合がありますことをご了承ください。
インポートや画像の読み込み・保存方法の解説は、下記記事をご参考ください。
画像を合成する(重ねる)
height, width = input_img_front.shape[:2]
x, y = 10, 20
input_img_back[y:y+height, x:x+width] = input_img_front
上記コードにて、「input_img_back」の上に「input_img_front」を重ねることができます。
まずコードの6行目で「input_img_front」のサイズ(height:高さ, width:幅)を取得しています。
今回は「高さが80、幅が300px」のため、「heightには80」「widthには300」が入ります。
次に7行目で「重ねる位置の座標」を指定しています。
下図のように、「input_img_back」の画像の左上が(x=0, y=0)です。
今回は、「x方向(右)に10、y方向(下)に20px」の位置に重ねることにします。
最後に8行目で「input_img_back」の上に「input_img_front」を重ねる処理をしています。
6行目と7行目で取得した「input_img_frontのサイズ」と「重ねる位置の座標」をここで使用しています。
以上で画像の合成(重ねる)処理は完了です。
ロゴ画像を透過させて合成する(重ねる)方法★
上に重ねるロゴ画像「input_img_front」をうっすら透過させることもできます。
「社外秘」や「開発中」などの画像と合成するときに便利です。
import cv2
input_img_front = cv2.imread('C:/Utatane/input_img_front.jpg')
input_img_back = cv2.imread('C:/Utatane/input_img_back.jpg')
front_touka = 0.1
back_touka = 0.9
scalar = 0
output_img = cv2.addWeighted(input_img_front, front_touka, input_img_back, back_touka, scalar)
cv2.imwrite('C:/Utatane/output_img.jpg', output_img)
6・7行目の「front_touka」「back_touka」は画像の透明度です。
今回のように「後ろ側が0.9」「前側が0.1」くらいが適切かと思います。
8行目の「scalar」はスカラー値といって、数値が大きくなるほど画像全体が明るくなります。
基本的には「0」でOKです。
重ねた画像を透過させるには、いくつか注意点があります。
- 2つの画像「input_img_front」と「input_img_back」が同じサイズであること(今回は600×600px)
- 2つの透明度「front_touka」「back_touka」を合計で「1」になるようにする
複数の画像ファイルを一括で合成(重ねる)★
下記のコードを実行することで、「input」フォルダに入った画像全てにロゴ画像(input_img_front.jpg)を重ねることができます。
import cv2
import os
os.makedirs('C:/Utatane/output', exist_ok=True)
input_img_front = cv2.imread('C:/Utatane/input_img_front.jpg')
height, width = input_img_front.shape[:2]
x, y = 10, 20
for filename in os.listdir('C:/Utatane/input'):
if filename.endswith('.jpg') :
input_img_back = cv2.imread(os.path.join('C:/Utatane/input', filename))
input_img_back[y:y+height, x:x+width] = input_img_front
cv2.imwrite(os.path.join('C:/Utatane/output', filename), input_img_back)
前々項で紹介した方法をfor文で繰り返し、全ての画像に適用しています。
<コード4行目>
出力するフォルダを作成
<コード6行目~8行目>
6行目:ロゴ画像(重ねる画像)を取り込み
7行目:「input_img_front」のサイズを取得
8行目:重ねる位置を指定
<コード9行目~最後>
10行目:「input」フォルダ内の背景になる画像を取り込み
11行目:拡張子が「jpg」なら以下の操作を行う
12行目:「input」フォルダのパスとファイル名を連結(フルパスに)して取り込み
13行目:背景画像にロゴ画像を重ねる
14行目:出力フォルダパスとファイル名を連結(フルパスに)して出力
これで「input」フォルダ内のjpg画像を全て処理できます。
うまく動作しない場合の対処法
画像の読み込みができない
画像ファイルが存在しない場合や、ファイルが破損している場合などは画像の読み込みができません。
画像を読み込み・保存する方法の記事を参考に、再度確認してください。
画像が保存されない
存在しないフォルダを指定した場合、画像は保存されません。
画像を読み込み・保存する方法の記事を参考に、再度確認してください。
エラーが出る
No module named ‘cv2’
これは、OpenCVがインストールできていない場合に出るエラーです。
事前準備の項を参考に、OpenCVのインストールを完了させてください。
OpenCV(4.10.0) ~ img.empty() ~
画像の読み込みが正常に行えていない可能性があります。
画像を読み込み・保存する方法の記事を参考に、画像のパスや形式を確認してください。
○○ is not defined
今まで出てきていない変数などを処理しようとした時に出るエラーです。
変数名などが間違っていないかチェックしましょう。
詳しい解説は、下記記事をご参考ください。
その他のエラー
その他のエラーが出た場合は、エラー文をコピーしてNETで検索してみましょう。
最後に
OpenCVで画像を合成する(重ねる)方法を解説いたしました。
当ブログでは、Pythonに関する情報を配信しております。
この記事がわかりやすいと感じた方は、他の記事も読んでいってください。
挫折せずにPythonを独学で学習する方法は特におすすめです。
最後までお読みいただき、ありがとうございました。がんばってください!