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()
(実行結果)
ただし、カラー画像になると、こんな感じ↓になってしまいます。
これは、取得したヒストグラムデータがR,G,Bのデータがつながって768個の一次元のリストに格納されてしまっているためで、具体的にはリストのインデックスで
0~255:Rのヒストグラム
256~511:Gのヒストグラム
512~767:Bのヒストグラム
が格納されています。
以上のことを考慮して、最初のプログラムを変更して、
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()
のようにすると、モノクロ、カラーの両方に対応できます。
有用なコードを公開していただきありがとうございます。
ただ、最後のモノクロ、カラーの両方のコードに関しては、カラー表示はバグっていませんか? そのままでは例通りには動きません。
ご参考まで
ご連絡ありがとうございます。
手元のプログラムでは動作していたのですが、ブログのコードから張りなおすと確かにダメでした。
誤)plt.plot(x, y, color = colors, label = bands)
↓
正)plt.plot(x, y, color = colors[c], label = bands[c])
の部分だと思いますが、ブログの記事(原稿を書くエディタ)上では正しいのですが、ブログの表示で[c]の部分が消えていました。
[c]が、どうやら特殊文字らしく、コードを表示しているグレーの部分の中では消えてしまうため、結局[col]にして修正しました。
教えて頂き助かりました。
ありがとうございます。