Pythonでマスク画像を作る方法(3選)
Pythonを使って画像をマスクします。Pillowを使う方法とOpenCVを使う方法、およびOpenCVとNumPyを組み合わせる方法です。
目次
サンプル
本ページで使用する画像は、次の3つです。
オリジナル(カラー画像)

グレースケールに変換済みの画像
画像ソフトなどでグレースケールに変換してJPEGに保存したものです。

マスク画像
1ビットのビットマップ画像ファイルです。

Pillowでマスクする
Pillowのcompositeメソッドを使用してマスク画像を生成します。
composteメソッドは、マスク画像を用いて2つの画像を合成するメソッドです。
im = PIL.Image.composite(image1, image2, mask)
変数 |
型 |
内容 |
---|---|---|
image1 |
Image |
合成される画像。 |
image2 |
Image |
マスク部分に適用される画像。Image1と同じモードかつ同じサイズであること。 |
mask |
Image |
マスク画像。モードは1、L、RGBAのいずれか。サイズはImage1と同じであること。 |
im |
Image |
合成された画像。 |
マスク部を単色にする(Pillow)
オリジナル画像と同じモードで同じサイズの単色の画像を生成し、compositeメソッドを使ってオリジナル画像に合成します。
from PIL import Image
im_1 = Image.open('original.jpg')
im_mask = Image.open('mask.bmp')
im_2 = Image.new(mode=im_1.mode, size=im_1.size, color=(0,0,0))
im = Image.composite(im_1, im_2, im_mask)
im.save('out.png')
これを実行すると、このような画像が得られます。

マスク部分を他の画像にする(Pillow)
マスク部分を他の画像にします。ここでは、グレースケール画像を読み込んで、それをマスク部分に適用します。
from PIL import Image
im_1 = Image.open('original.jpg')
im_2 = Image.open('gray.jpg')
im_mask = Image.open('mask.bmp')
im = Image.composite(im_1, im_2, im_mask)
im.save('out.png')
これを実行すると、このような画像が得られます。

OpenCVでマスクする
OpenCVのビット演算(bitwise_and)を使ってマスクしてみます。
dst = cv2.bitwise_and(src1, src2, [dst], [mask])
変数 |
型 |
内容 |
---|---|---|
src1 |
array |
合成される画像。 |
src2 |
array |
合成する画像。またはマスク画像。 |
dst |
array |
合成結果の画像。 |
mask |
array |
省略可。マスク用画像。8ビットのシングルチャネルの画像であること。 |
例えばsrc1が3チャネルのカラー画像だとして場合、マスク画像をsrc1に指定するにはマスク画像のデータは3チャネルである必要があります。
もしマスク画像が1チャネルの画像データの場合は、src2にsrc1と同じ画像を指定して、maskに1チャネルのマスク画像を指定します。
マスク部を単色にする(OpenCV)
import cv2
im_1 = cv2.imread('original.jpg', cv2.IMREAD_COLOR)
im_mask = cv2.imread('mask.bmp')
im_out = cv2.bitwise_and(im_1, im_mask)
cv2.imwrite('out.png', im_out)
これを実行すると、このような画像が得られます。

マスク部分を他の画像にする(OpenCV)
マスク部分を他の画像にします。ここでは、グレースケール画像を読み込んで、それをマスク部分に適用します。
カラー部分用のマスクを読み込んだら、それをbitwise_notメソッドを使って色反転してグレースケール部分用のマスクを作ります。
そして、それぞれのマスクを使ってマスク化された画像を作り、bitwise_orメソッドを使って2つのマスク画像を合成します。
import cv2
im_1 = cv2.imread('original.jpg', cv2.IMREAD_COLOR)
im_2 = cv2.imread('gray.jpg', cv2.IMREAD_COLOR)
im_mask = cv2.imread('mask.bmp')
im_mask_inv = cv2.bitwise_not(im_mask)
im_c = cv2.bitwise_and(im_1, im_mask)
im_g = cv2.bitwise_and(im_2, im_mask_inv)
im_out = cv2.bitwise_or(im_c, im_g)
cv2.imwrite('out.png', im_out)
これを実行すると、このような画像が得られます。

マスク部を単色にする(NumPy)
NumPyのAdvanced Indexの機能を使って、マスク部分の色を行列の状態で変換します。単色のマスクであれば、これが便利です。ここの例では、マスク部分をグレーにします。
マスク用画像は1ビットのビットマップなのですが、imreadで読み込むとBGRカラーモードになります。そこで、splitメソッドでB要素だけ取り出してAdvanced Indexに適用するマスクにします。
import numpy as np
import cv2
im_1 = cv2.imread('original.jpg', cv2.IMREAD_COLOR)
im_mask, g_, r_ = cv2.split(cv2.imread('mask.bmp'))
im_1[im_mask==0] = [128,128,128]
cv2.imwrite('out.png', im_1)

公開日
広告
Pythonで画像処理カテゴリの投稿
- Python (Pillow)でグラデーション画像を作る
- PythonでGIFアニメを作る(PILでファイルをつなげる編)
- PythonでOpenCVの画像データをMatplotlibで表示する
- PythonでPDFを画像に変換する(Windows10)
- PythonでPSDファイルをJPEGやPNGに変換する
- Pythonでカラー画像をグレイスケールに変換する(OpenCV編)
- Pythonでフォルダ内に同じ画像がないか検索してみた
- Pythonでマスク画像を作る方法(3選)
- Pythonで図形の外接矩形を描く(OpenCV編)
- Pythonで図形の輪郭の大きさを調べる(OpenCV編)
- Pythonで画像の余白を削除する(OpenCV編)
- Pythonで画像の余白を削除する(Pillow編)
- Pythonで画像の大きさやフォーマットを調べる(Pillow編)
- Pythonで画像の減色をする
- Pythonで画像をトリミングする(Pillow編)
- Pythonで画像を他の画像にペーストする(Pillow編)
- Pythonで画像を回転する(Pillow編)
- Pythonで画像を拡大縮小(リサイズ)する(Pillow編)
- Pythonで画像を読み込み、表示し、保存する(OpenCV編)
- Pythonで画像を読み込み、表示し、保存する(Pillow編)
- Pythonで画像を2値化する(OpenCV編)
- Pythonで記号の輪郭を検出する(OpenCV編)
- PythonとOpenCVで画像をグレースケールに変換してみた
- PythonとOpenCVで画像をネガポジ反転してみた