Pillow(PIL)

【Python/Pillow(PIL)】画像のヒストグラム取得、表示

Pillowで画像のヒストグラムを取得し、取得した画像データをmatplotlibで表示するには、とても簡単で以下のようにします。

import matplotlib.pyplot as plt # ヒストグラム表示用
from PIL import Image

# PIL.Imageで画像を開く
img = Image.open("./Mandrill.bmp")

# 画像の表示
img.show()

# ヒストグラムの取得
hist = img.histogram()

# ヒストグラムをmatplotlibで表示
plt.plot(range(len(hist)), hist)
plt.show()

(実行結果)

Python Pillow ヒストグラムの表示

ただし、カラー画像になると、こんな感じ↓になってしまいます。

Python Pillow ヒストグラムの表示

これは、取得したヒストグラムデータがR,G,Bのデータがつながって768個の一次元のリストに格納されてしまっているためで、具体的にはリストのインデックスで

    0~255:Rのヒストグラム
  256~511:Gのヒストグラム
  512~767:Bのヒストグラム
が格納されています。

Python Pillow ヒストグラムの表示

以上のことを考慮して、最初のプログラムを変更して、

import matplotlib.pyplot as plt # ヒストグラム表示用
from PIL import Image

# PIL.Imageで画像を開く
img = Image.open("./Mandrill.bmp")

# 画像の表示
img.show()

# ヒストグラムの取得
hist = img.histogram()

# 各色の名前を取得
# カラーのとき:('R', 'G', 'B')
# モノクロのとき:("L")
bands = img.getbands()

# チャンネル数
ch = len(bands)

# グラフの表示色
if (ch == 1):
    colors = ["black"]
else:
    colors = ["red", "green", "blue", "black"]

# ヒストグラムをmatplotlibで表示
x = range(256)
for col in range(ch):
    y = hist[256 * col : 256 * (col + 1)]
    plt.plot(x, y, color = colors[col], label = bands[col])

# 凡例の表示
plt.legend(loc=2)

plt.show()

のようにすると、モノクロ、カラーの両方に対応できます。

Python Pillow ヒストグラムの表示

コメント

  1. 通りすがり より:

    有用なコードを公開していただきありがとうございます。
    ただ、最後のモノクロ、カラーの両方のコードに関しては、カラー表示はバグっていませんか? そのままでは例通りには動きません。
    ご参考まで

    • Akira より:

      ご連絡ありがとうございます。
      手元のプログラムでは動作していたのですが、ブログのコードから張りなおすと確かにダメでした。
      誤)plt.plot(x, y, color = colors, label = bands)

      正)plt.plot(x, y, color = colors[c], label = bands[c])
      の部分だと思いますが、ブログの記事(原稿を書くエディタ)上では正しいのですが、ブログの表示で[c]の部分が消えていました。
      [c]が、どうやら特殊文字らしく、コードを表示しているグレーの部分の中では消えてしまうため、結局[col]にして修正しました。
      教えて頂き助かりました。
      ありがとうございます。

タイトルとURLをコピーしました