Pythonでマスク画像を作る方法(3選)

Pythonを使って画像をマスクします。Pillowを使う方法とOpenCVを使う方法、およびOpenCVとNumPyを組み合わせる方法です。

目次

  1. サンプル
  2. Pillowでマスクする
  3. OpenCVでマスクする

サンプル

本ページで使用する画像は、次の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でマスクした画像

マスク部分を他の画像にする(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')

これを実行すると、このような画像が得られます。

Pillowで合成した画像

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でマスクした画像

マスク部分を他の画像にする(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)

これを実行すると、このような画像が得られます。

OpenCVで合成した画像

マスク部を単色にする(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)
NumPyでマスクした画像

広告

Pythonで画像処理カテゴリの投稿