Pythonで画像処理をしていると、画像データの扱いは各ライブラリによって、NumPyのndarrayかPillowのPIL.Imageのどちらかになる場合が多いかと思います。
そこで NumPyとPillowの画像データの相互変換をまとめておきます。
NumPy -> Pillowへの変換
NumPy からPillowへの変換は Pillowの fromarray関数を用います。
from PIL import Image
pil_image = Image.fromarray(numpy_image)
Pillow -> NumPyへの変換
PillowからNumPyへの変換は NumPyの array関数を用います。
import numpy as np
numpy_image = np.array(pil_image)
array関数と似たものにasarray関数がありますが、このasarrayで変換されたNumPyの配列(ndarray)は読み取り専用となり、値の参照はできますが、値を設定することはできません。
import numpy as np
numpy_image = np.asarray(pil_image) # numpy_imageは読み取り専用となる
変換サンプル
NumPyとPillowの画像データを相互変換したサンプルを示します。
import numpy as np
from PIL import Image
# Pillow でモノクロ画像を読み込む
pil_image_mono = Image.open("image_mono.bmp")
print(type(pil_image_mono)) # <class 'PIL.BmpImagePlugin.BmpImageFile'>
print(pil_image_mono.mode) # L
print(pil_image_mono.size) # (400, 300)
# Pillow でカラー画像を読み込む
pil_image_color = Image.open("image_color.bmp")
print(type(pil_image_color)) # <class 'PIL.BmpImagePlugin.BmpImageFile'>
print(pil_image_color.mode) # RGB
print(pil_image_color.size) # (400, 300)
# Pillow -> NumPyへ変換(モノクロ画像)
ndarray_mono = np.array(pil_image_mono)
print(type(ndarray_mono)) # <class 'numpy.ndarray'>
print(ndarray_mono.dtype) # uint8
print(ndarray_mono.shape) # (300, 400)
# Pillow -> NumPyへ変換(カラー画像)
ndarray_color = np.array(pil_image_color)
print(type(ndarray_color)) # <class 'numpy.ndarray'>
print(ndarray_color.dtype) # uint8
print(ndarray_color.shape) # (300, 400, 3)
# NumPy -> Pillowへ変換(モノクロ画像)
pil_image_mono = Image.fromarray(ndarray_mono)
print(type(pil_image_mono)) # <class 'PIL.Image.Image'>
print(pil_image_mono.mode) # L
print(pil_image_mono.size) # (400, 300)
# NumPy -> Pillowへ変換(カラー画像)
pil_image_color = Image.fromarray(ndarray_color)
print(type(pil_image_color)) # <class 'PIL.Image.Image'>
print(pil_image_color.mode) # RGB
print(pil_image_color.size) # (400, 300)
ここで注意しておきたいのが、
Pillowのモノクロ画像をNumPyへ変換したときは
[画像の高さ, 画像の幅]
の順の二次元配列となります。
Pillowのカラー画像をNumPyへ変換したときは
[画像の高さ, 画像の幅, 色(R, B, Gの順)]
の順の三次元配列となります。
NumPyのカラー画像をPillowへ変換する場合は、カラーデータの並びが R,G,B である必要があります。
OpenCVの画像データもNumPyのndarrayで扱われますが、OpenCVの場合、カラーデータの並びが
B,G,Rとなるため、OpenCVからPillowの画像データへ変換する場合は、cvtColor関数を使って、R,G,Bに変換しておく必要があります。
コード例
image_color = cv2.cvtColor(image_color, cv2.COLOR_BGR2RGB)
(参考)