はじめに
PythonのPillowを使用して、画像の中心部分以外を円形にマスク処理するコードを紹介します。
使用する画像
この馬の顔部分以外をマスク処理で円形に黒く塗りつぶします。[馬の画像]
(https://pixabay.com/ja/photos/%E9%A6%AC-%E5%8B%95%E7%89%A9-%E4%B9%97%E3%82%8B-%E3%83%AC%E3%82%A4%E3%82%BF%E3%83%BC%E3%83%9B%E3%83%95-4847088/)
マスクに使用する画像はこの画像です。黒のマスク画像
マスク処理の流れ
- マスク部分(馬の顔以外)が白色で、マスク処理を適用しない部分(馬の顔部分)を黒色にしたパネルを生成する。画像の枠が白色で見えませんが、馬の画像と同じ画像サイズになっています。
- 馬の画像に、パネルでくり抜いたマスク画像を貼り付ける。
コード
プログラムの説明を簡単に行っていきます。
全体のプログラムは最後に記載しています。
マスク画像の読み込み
馬の画像の大きさに合わせて、マスク画像も読み込みます。
from PIL import Image,ImageDraw
# 馬の画像を読み込む
img = Image.open("horse.jpg")
# 馬の画像に合わせてマスク画像を読み込む
mask_width = img.size[0]
mask_height = img.size[1]
black_mask=Image.open("black.jpg").resize((mask_width,mask_height))
パネル作成
黒のマスク画像と同じサイズのパネル(circle_mask)作成し、そこに円を描画します。
パネルの作成時には、"L":8bitグレースケール画像を使用します。
マスク画像として使用できるのは、貼り付け画像と同じサイズでmodeが以下の三種類の場合。
1:1bit画像(二値画像)
L:8bitグレースケール画像
RGBA:アルファチャンネルを持った画像
マスク画像が8bitグレースケール(mode='L')の場合、0(黒)ではベース画像が100%、255(白)では貼り付け画像が100%、中間値では2つの画像が値に応じてブレンドされる。
# パネルに円を描画
circle_mask = Image.new("L", black_mask.size, 255)
draw = ImageDraw.Draw(circle_mask)
円を描画
円はellipseメソッドを使用して描画しますが、バウンディングボックスの座標(左下と右下)を渡すことに注意してください。
# 円のバウンディングボックスの座標
start_x = 600
start_y = 200
width = 900
height = 900 # 正円にするならwidthの同値
end_x = start_x + width
end_y = start_y + height
# 描画
draw.ellipse(((start_x, start_y),(end_x, end_y)), fill=0)
画像をくり抜いてマスク処理
# 円パネル(circle_mask)をマスクとし、黒のマスク画像(black_mask)を馬画像にペースト
img.paste(black_mask, (0, 0), circle_mask)
# 保存
img.save("horse_masked.jpg")
全体コード
from PIL import Image,ImageDraw
# 馬の画像を読み込む
img = Image.open("horse.jpg")
# 馬の画像に合わせてマスク画像を読み込む
mask_width = img.size[0]
mask_height = img.size[1]
black_mask=Image.open("black.jpg").resize((mask_width,mask_height))
# パネルに円を描画
circle_mask = Image.new("L", black_mask.size, 255)
draw = ImageDraw.Draw(circle_mask)
# 円のバウンディングボックスの座標
start_x = 600
start_y = 200
width = 900
height = 900 # 正円にするならwidthの同値
end_x = start_x + width
end_y = start_y + height
# 描画
draw.ellipse(((start_x, start_y),(end_x, end_y)), fill=0)
# 円パネル(circle_mask)をマスクとし、黒のマスク画像(black_mask)を馬画像にペースト
img.paste(black_mask, (0, 0), circle_mask)
# 保存
img.save("horse_masked.jpg")
参考URL
詳しい引数の説明が紹介されています。
note.nkmk.me