よちよちpython

独習 python/Qpython/Pydroid3/termux/Linux

【Pillow】画像にマスク処理する

画像にマスクを掛けます。コロナの防衛策です。

巷でアベノマスクを私以外していないのはどういうことなのか。



目次




作業環境


  • Android
  • termux
  • Python3.8
  • JupyterNotebook
  • 外部ライブラリ
    • pillow 画像処理用
    • matplotlib 画像表示用



マスク処理ってなに?


元画像の




f:id:chayarokurokuro:20200815114356j:plain



f:id:chayarokurokuro:20200815114423j:plain


になる。

その方法を見ていきます。
(もしかしたら全部同じに見えるかも)



元画像


# pillowとmatplotlibをインポート
from PIL import Image
import matplotlib.pyplot as plt

# 画像ファイルパス
filename = "noumen.JPG"

# pillowで取り込み
im = Image.open(filename)

# 画像のフォーマットとサイズとモード表示
print("フォーマット",im.format)
print("サイズ",im.size)
print("モード",im.mode)

# matplotlibで画像表示
plt.imshow(im)
フォーマット JPEG
サイズ (320, 320)
モード RGB





<matplotlib.image.AxesImage at 0x79a4017760>

この画像に円と楕円のマスク処理を施します。



円のマスク


円のマスク画像描画

# 図形描写用ライブラリのインポート
from PIL import ImageDraw

# マスク画像作成、元画像サイズで
mask = Image.new("L", im.size, 0)
# 画像描画の準備
draw = ImageDraw.Draw(mask)
# 描画
draw.ellipse((0, 0, 320, 320), fill=255)

# マスク画像のサイズとモード表示
print("サイズ",mask.size)
print("モード",mask.mode)

# pillowでマスク画像の保存
mask.save("noumen_mask.jpg")

# matplotlibで画像イメージの表示
plt.imshow(mask)
サイズ (320, 320)
モード L





<matplotlib.image.AxesImage at 0x79a4146eb0>

20200815114855

【説明】

  • Image.new(モード, 画像サイズ, 描画のRGBの各色)
    • モード : L 白黒
    • サイズ : 元画像(能面)と同じ
    • RGBの色 : 0指定で黒ベタ塗り


  • draw.ellipse((左上x座標 , 左上y座標, 右下x, 右下y), RGB各色指定)
    • 座標(0, 0, 320, 320) : 左上原点と右下に収まる範囲に円が描かれる
    • 色指定 : fill=255で白の描画がなされる



元画像に円のマスク処理

# 元画像オブジェクトのコピー
im_masked = im.copy()

# マスク画像でalpha値指定しRGBAに変換
im_masked.putalpha(mask)

# pillowで画像保存
im_masked.save("noumen_masked1.png")

# matplotlibで画像イメージ表示
plt.imshow(im_masked)
<matplotlib.image.AxesImage at 0x79a411f9a0>

20200815114356

【説明】

  • 元イメージ.putalpha(マスク画像イメージ)
    • 元イメージに、マスク画像に従ったアルファチャンネルが追加される。円のマスク描画の白い部分だけが残り、黒い部分(色=0)は透過性100%に処理され背景が透けるようになる。

詳しくは、Numpyで行うマスク処理の方法が参考になると思う。

note.nkmk.me numpy マスク処理



  1. マスク画像の色データ(白=RGBの全てが255, 黒=RGBの全てが0)を一旦255で割ると、色データが1と0に変換される。
  2. この1か0のデータを元画像に掛け合わせる。
    1. 1が掛けられた元データはそのまま残る。
    2. 0が掛けられた元データは0になり黒に変換される。



楕円のマスク


楕円のマスク画像描画

座標の指定を変えることで楕円になることを確かめます。

# 描画用ライブラリのインポート
from PIL import ImageDraw

# マスク画像作成
mask_2 = Image.new("L", im.size, 0)
# 描画準備
draw = ImageDraw.Draw(mask_2)
# 楕円を描画(座標の指定はだいたい)
draw.ellipse((50, 20, 270, 310), fill=255)

# pillowで画像保存
mask_2.save("noumen_mask2.jpg")

# matplotlibで画像表示
plt.imshow(mask_2)
<matplotlib.image.AxesImage at 0x79a40f9f10>

20200815115013

楕円のマスク処理

# 元画像のコピー
masked_2 = im.copy()

# 楕円マスク画像でアルファチャンネル追加
masked_2.putalpha(mask_2)

# pillowで画像保存
masked_2.save("noumen_masked2.png")

# matplotlibで画像表示
plt.xticks([]), plt.yticks([]) #目盛りを消す
plt.imshow(masked_2)
<matplotlib.image.AxesImage at 0x79a40a03a0>

20200815114423


↓のような画像が表示される筈だがブログに上げると上手くいかない…

f:id:chayarokurokuro:20200815123947j:plain



【参考】
Python, Pillowで透過png画像を作成するputalpha | note.nkmk.me