投稿日:2019年10月25日
この記事ではRGB画像をpython3.6のライブラリPillowを使ってグレーまたはモノクロにする方法について詳しく解説します。
この記事ではPython3.7でPillowを使ってRGB画像をグレー・モノクロ画像にする方法について解説します。環境は以下の通りです。
まずはPillowのインストールをします。
$ pip install Pillow==6.2.1
from PIL import Image
img = Image.open("./jerry_beans.jpg") # 読み込み
img_g = img.convert(mode="L") # 変換
img_g.save("./jerry_beans_gray.jpg") # 変換した画像の保存
変換した画像をみてみましょう!
「いや、知ってるよ!!」って方、申し訳ありません。飛ばしてください。僕はこの違い知らなかつたので説明しておきます(笑)。白黒画像は0(白)と1(黒)の2つの値のみで色を表します。それに対し、グレースケールは色を0~255の値で表すのです。白黒は一つの画素を2bit(0と1)で表しますが、グレースケールは8bit(0~255)で表すためデータ容量にも差が生まれます。
そしてさらに大きく変わるのがその見た目でしょう。ディスプレイで確認するとわかりやすいのですが、白黒(モノクロ)画像は白と黒の中間色をドットの間隔で表しているのがわかります。
したがモノクロの画像を生成するコードです。
from PIL import Image
img = Image.open("./jerry_beans.jpg")
img_g = img.convert(mode="1") # 白黒の場合はmodeを"1に"
img_g.save("./jerry_beans_bin.jpg")
並べて見ると一目瞭然ではないですか?
convert(mode="L")でグレーにされるときの計算方法について、単純にRGBを足して1/3しているのではなく、ITU-R Rec BT.601という以下の計算が適用されていることを心にとどめておいてください。
R * 299/1000 + G * 587/1000 + B * 114/1000
赤、青、緑のそれぞれの値と人間が感じる明るさには差があるそうです。そのため、RGBをそのまま足して1/3のような計算をしてしまうと思った色と違ってしまうのです。それを解決するためにバイアスをかけて計算する方法の一つが上のITU-R Rec BT.601というわけです。最後にRGBの和の1/3でグレー画像を生成する方法と、それぞれの画像の比較を載せて終了にします。
from PIL import Image
img = Image.open("./jerry_beans.jpg")
size = img.size
img_g = Image.new("L",size) # からのグレー画像を用意
def calculate_pixel(r,g,b):
"""
グレーを単純にRGBの和の3分の1で計算
"""
grey = int((r + g + b) / 3)
if grey > 255:
return 255
else:
return grey
# オリジナル画像のすべての画素に対して
# (R + G + B) / 3の計算をし空のグレー画像のpixelを埋める
for x in range(size[0]):
for y in range(size[1]):
r,g,b = img.getpixel((x, y))
img_g.putpixel( (x,y) ,calculate_pixel(r,g,b))
# 生成したグレー画像を保存
img_g.save("./jerry_beans_grey_splitted.jpg")