【Python】Matplotlibで画像を読み込んでプロットする


投稿日 2021年2月2日 >> 更新日 2023年3月1日

今回はPython外部ライブラリのMatplotlibで画像をプロットしていきたいと思います。

Matplotlibだけで画像のプロットを行うこともできますが、画像処理モジュールのPIL(pillow)から開いた画像データもそのままプロットすることができます。

例えば、LinuxやWSL(Windows Subsystem for Linux)環境下の場合PILモジュールのImage.show()を実行しても画像が表示されないといったケースがあります。

表示させるには「Imagemagick」などのフリーソフトをシステムに構築する必要があったりなかったり...

この記事では画像の描画だけに留めていますが、画像処理を施した後の確認でMatplotlibに渡せば簡単に結果を得られることができます。

実行環境&使用ライブラリ

実行環境
Windows Subsystem for Linux
Python 3.6.9
pip 9.0.1
使用ライブラリ ライセンス
matplotlib==3.1.1 PSF
Pillow==6.1.0 HPND

画像を読み込んでプロット

インストールはpipで行います。

$ pip install matplotlib pillow

Matplotlibで画像をプロットするには、「imread」メソッドで画像ファイルを読み込んでから「imshow」メソッドにより描画を実行します。

※ここではカレントディレクトリに「cat_1.jpg」という画像ファイルがあるとします。

import matplotlib.pyplot as plt
from matplotlib.image import imread, imsave

# fname=画像ファイル、format=画像ファイルの拡張子
# formatを指定しない場合は、推測により決定し、推測できない場合はPNGとなる
img = imread(fname='cat_1.jpg', format='jpg')
# img = plt.imread('cat_1.jpg') # pyplotからでも呼び出せる
print(img)
# <class 'numpy.ndarray'>

plt.imshow(
    img,
)
plt.show()

imreadで読み込んだ画像ファイルはnumpy配列として結果が格納され、プロットするimshowではPILデータもしくわ配列のようなデータを渡すことによって実行することできます。

imreadで読み込んだ画像ファイルを「imsave」によって保存することもできます。

imsaveは「plt.savefig()」とは違いプロットされた図を保存するのではなく画像その物を保存します。


import matplotlib.pyplot as plt
from matplotlib.image import imread, imsave

img = imread('cat_1.jpg')
imsave('return_cat_1.jpg', img) # imgのイメージを保存

plt.imshow(
    img,
)
plt.axis('off') # 縦軸と横軸のメモリを無くす
plt.savefig('plot_cat_1.jpg') # プロットされた図を保存
plt.show()

PILデータをプロット

imshowメソッドは画像処理ライブラリのPILデータもそのまま渡すことで簡単にプロットできます。

import matplotlib.pyplot as plt
from PIL import Image

im = Image.open('cat_1.jpg')

plt.imshow(im)
plt.title('Image form PIL')
plt.show()

imreadメソッドやPILモジュールで読み込まれた画像の色は「RGB(R:赤・G:緑・B:青の情報)」となっています。

img_arr = imread('cat_1.jpg') # Matplotlibモジュール
img_pil_1 = Image.fromarray(img_arr) # numpy配列をPILデータに戻す
img_pil_2 = Image.open('cat_1.jpg') # PILモジュール

print('imread: {}'.format(img_pil_1.mode))
print('PIL: {}'.format(img_pil_2.mode))
# imread: RGB
# PIL: RGB

RGBだとMatplotlibのカラーマップで色の変更が行えないので、PILモジュールの「convert」メソッドでグレースケール(白と黒の間で表現される色)に変換し、imshowメソッドでプロットしてみたいと思います。


import matplotlib.pyplot as plt
from PIL import Image

imgs = ['cat_1.jpg', 'cat_2.jpg', 'cat_3.jpg']
cmap = ['gray', 'cool', 'hot'] # カラーマップの色

fig, axs = plt.subplots(1, 3, figsize=(10, 5))

for i, im, cmp in zip(range(len(axs)), imgs, cmap):
    img = Image.open(im).convert("L") # グレースケールに変換
    axs[i].imshow(img, cmap=cmp) # cmap=カラーマップの選択
    axs[i].set_title(im)
    axs[i].axis('off')

plt.show()

カラーマップのカラーは様々な色を選択することができるので以下のドキュメントから確認することができます。

カラーマップが適用されると、そのカラーマップがカバーする範囲(色の段階)を指定することができます。

デフォルトではimshow(X, cmap='viridis', vmin=0, vmax=255)となっており0から255の段階によるカラーマップ色が適用されています。

以下の場合は50から100の範囲に絞ったカラーマップをプロットしています。


import matplotlib.pyplot as plt
from PIL import Image

imgs = ['cat_1.jpg', 'cat_2.jpg', 'cat_3.jpg']
cmap = ['gray', 'cool', 'hot']

fig, axs = plt.subplots(1, 3, figsize=(10, 5))

for i, im, cmp in zip(range(len(axs)), imgs, cmap):
    img = Image.open(im).convert("L")
    axs[i].imshow(img, cmap=cmp, vmin=50, vmax=100) # vmin=最小値、vmax=最高値
    axs[i].set_title(im)
    axs[i].axis('off')

plt.show()

最後にPILモジュールresizeメソッドで画像のピクセル数を変更してプロットしていきたいと思います。


import matplotlib.pyplot as plt
from PIL import Image

img = Image.open('cat_1.jpg')
img_size = [10, 20, 30, 40, 50] # 画像サイズの値
fig, axs = plt.subplots(1, 5, figsize=(15, 8))

for i, siz in zip(range(len(axs)), img_size):
    im = img.resize((siz, siz)) # 流れてくる画像サイズを順番に渡す
    axs[i].imshow(im)
    axs[i].set_title('size: '+str(siz))

plt.show()

imshowには他にも様々なパラメータが用意されているので、余力のあるかたは是非公式ドキュメントをご参照ください。

それでは以上となります。

最後までご覧いただきありがとうございました。