今回は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()
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には他にも様々なパラメータが用意されているので、余力のあるかたは是非公式ドキュメントをご参照ください。
それでは以上となります。
最後までご覧いただきありがとうございました。