[Matplotlib] 画像の作成・読み込み・保存

[Matplotlib] 画像の作成・読み込み・保存

画像の作成・読み込み・保存

画像と配列

 Scikit-image というパッケージには、色々な画像データが収められています。その中から chelsea (チェルシー) という可愛い「にゃんこ」の画像を読み込んでみましょう。

# IMG_01-1

import numpy as np
import matplotlib.pyplot as plt

# Scikit-imageから猫の画像データを取得
from skimage.data import chelsea

# 画像表示用のFigureとAxesを作成
fig = plt.figure()
ax = fig.add_subplot(111)

# 配列に画像データを格納
img = chelsea()

# 画像を表示
ax.imshow(img)

 Scikit-image chelsea

 matplotlib.axes.Axes.imshow() はデータを画像に変えて表示する関数ですが、元の画像データはどのような形式で記述されているのでしょうか?

 print() 関数でデータの大きさと中身を表示してみます。

# IMG_01-2

print("データの形状:\n{}".format(img.shape))
print(img)
データの形状:
(300, 451, 3)

[[[143 120 104]
  [143 120 104]
  [141 118 102]
  ...
  [ 45  27  13]
  [ 45  27  13]
  [ 45  27  13]]

 [[146 123 107]
  [145 122 106]
  [143 120 104]
  ...
  [ 46  29  13]
  [ 45  29  13]
  [ 47  30  14]]

 このように、画像データは三次元配列として格納されています。

 データの意味を理解するために、小さな配列を作成して「配列から画像を生成する」という逆手順を実行してみます。

# IMG_01-3

# FigureとAxesを作成
fig = plt.figure()
ax = fig.add_subplot(111)

# 乱数シードを設定
np.random.seed(0)

# ランダム配列を生成
data_r = np.random.randint(0, 255, (3, 3))
print("data_r:\n{}".format(data_r))

# データを赤単色画像に変換
ax.imshow(data_r, "Reds")
data_r:
[[172  47 117]
 [192  67 251]
 [195 103   9]]

 Python 赤単色画像

 imshow() のカラーマップに "Reds" を指定して、配列を赤単色画像に変換しています。
 配列の各要素はマス目 (ピクセル) ごとの濃淡を 0 ~ 255 の数値で表しています。
 同じようにして、緑単色画像を作成します。

# IMG_01-4

fig = plt.figure()
ax = fig.add_subplot(111)

np.random.seed(1)
data_g = np.random.randint(0, 255, (3, 3))
print("data_g:\n{}".format(data_g))

img = np.array(data_g)
ax.imshow(img, "Greens")
data_g:
[[ 37 235 140]
 [ 72 137 203]
 [133  79 192]]

 Python 緑単色画像

 最後に青単色画像です。

# IMG_01-5

fig = plt.figure()
ax = fig.add_subplot(111)

np.random.seed(2)
data_b = np.random.randint(0, 255, (3, 3))
print("data_b:\n{}".format(data_b))

img = np.array(data_b)
ax.imshow(img, "Blues")
data_b:
[[168  15 237]
 [ 72  22  43]
 [210  75 104]]

 Python 青単色画像

 赤 (R)、緑 (G)、青 (B) の 3 原色の組み合わせ (RGB) によって、他の色を作り出すことができます。上で作成した 3 種類の画像データを numpy.dstack() で重ね合わせてみましょう。

# IMG_01-6

# 3枚の画像データを重ねる
data = np.dstack((data_r, data_g, data_b))

print(data)
[[[172  37 168]
  [ 47 235  15]
  [117 140 237]]

 [[192  72  72]
  [ 67 137  22]
  [251 203  43]]

 [[195 133 210]
  [103  79  75]
  [  9 192 104]]]

 配列の最初の要素 [172 37 168] は左上のピクセルが (赤 172, 緑 37, 青 168) の割合で混ぜ合わされた色であることを意味しています。imshow() に 3 次元配列を渡すと、自動的に色を重ね合わせた画像を表示ます。

# IMG_01-7

fig = plt.figure()
ax = fig.add_subplot(111)

# 画像データを作成
img = np.array(data)

# 画像を表示
ax.imshow(img, vmin=0, vmax=255)

plt.savefig("color_image.png", bbox_inches = "tight")

 Python 色の重ね合わせ

画像を作成する

 matplotlib.axes.Axes.imshow() の詳細を解説します。この関数を使って、NumPy の配列の各要素をピクセルとする画像を作ることができます。imshow() の最も簡単な使い方は、配列とカラーマップ (cmap) を指定する方法です。この場合、渡した配列によって、カラーマップは自動的に正規化されます。

# IMG_02

# モジュールをインポート
import numpy as np
import matplotlib.pyplot as plt

# FigureとAxesを作成
fig = plt.figure()
ax = fig.add_subplot(111)

# NumPyの配列で色を指定
img = np.array([[0, 1, 2],
                [3, 4, 5],
                [6, 7, 8]])

# 配列の各要素をピクセルとする画像を表示
ax.imshow(img, "Reds")

imshow 画像作成

 カラーマップを自分で規格したい場合は、vmin と vmax を指定します。

# FigureとAxesを作成
fig = plt.figure()
ax = fig.add_subplot(111)

# NumPyの配列で色を指定
img = np.array([[10, 20, 30],
                [40, 50, 60],
                [70, 80, 90]])

# 配列の各要素をピクセルとする画像を表示
ax.imshow(img, "Reds", vmin = 0, vmax = 255)

imshow 画像作成02

画像を読み込む

 plt.imread() を使うと、外部の画像ファイルを読み込んで配列に格納することができます。たとえば、カレントディレクトリに BlogCat.jpg というファイルがある場合、次のコードで画像を表示させることができます。

# IMG_03

# FigureとAxesを作成
fig = plt.figure()
ax = fig.add_subplot(111)

# 画像を読み込んで配列に格納
img = plt.imread("BlogCat.jpg")

# 画像を表示
ax.imshow(img)

BlogCatのプロフィール写真
 

見て試してわかる機械学習アルゴリズムの仕組み 機械学習図鑑

新品価格
¥2,894から
(2019/8/6 11:45時点)

画像を保存する

 savefig()関数を使うと、Matplotlib で作成した図をファイルに出力することができます。第 1 引数には保存先のファイル名を指定します。ファイル名には .png, .jpeg, .svg などの拡張子を添えて保存形式を決めます。パスを指定しなければ、ファイルはカレントディレクトリに保存されます。
 他にも dpi(解像度)や facecolor(塗り潰しの色)、edgecolor(枠線の色) などを指定することができます。tight_layout に True を渡すと余白を最小限にして出力します。

# IMG_04

# 3次関数のグラフ (cubic.pngに保存)

# 必要なモジュールをインポート
import numpy as np
import matplotlib.pyplot as plt

# Figureを設定
fig = plt.figure(figsize = (6, 6))

# Axesを追加
ax = fig.add_subplot(111)

# Axes(サブプロット)のタイトルを設定
ax.set_title("Cubic Function", size = 16)

# x軸の範囲を設定
ax.set_xlim(-2, 10)
ax.set_ylim(-100, 75)

# xのデータを作成
x = np.arange(-2, 10, 0.1)

# yのデータを作成
f = x**3 - 9*x**2 + 4*x + 1

# 軸ラベルの設定
ax.set_xlabel("x", size = 14)
ax.set_ylabel("y", size = 14)

# 目盛線(グリッド)の表示
ax.grid()

# データをプロット
ax.plot(x, f, color = "darkblue")

# 保存先のファイル名(PNG形式)
fname = "cubic.png"

# ファイルを保存
plt.savefig(fname, dpi = 64,
            facecolor = "lightgray", tight_layout = True)

 
 実行結果として表示される図は次のようになります。

 Python savefig()による画像ファイルの出力と保存

 ファイルに出力されるグラフは次のようになります。

 Python savefig()による画像ファイルの出力と保存②
 [参考文献] PythonユーザのためのJupyter[実践]入門