画像処理はじめました。

AI/AR/VRという近未来的な言葉に惹かれ、その技術分野に参戦するために立ち上げたブログです。日々の格闘結果を記録に残してゆこうと思います。

1-3 「グレー化処理」

モチベーション

  • 被写体の形状だけを確認したい場合はグレースケールで事足りる
  • カラー画像(3チャンネル)に比べて扱う情報が1/3となるメリットあり

やり方

カラー画像をグレースケールへ変換する方法にはいくつかありますが、ここでは、以下を紹介します。

  • PILライブラリを使用し、グレースケールで画像を読み込む
  • 平均化法でグレースケールを作成
  • YUVのY画像(輝度情報)でグレースケールを作成

プログラム

カラー画像をPILで取得し、Numpy配列化してから色情報を変更しています。

#!/usr/bin/python
# -*- coding: utf-8 -*-

# グレー化処理

from PIL import Image 
import numpy as np
from matplotlib import pylab as plt

# 画像の読み込み
im = np.array(Image.open('input.bmp'))
print(im.shape, im.dtype)
# ((640L, 960L, 3L), dtype('uint8'))

# 画像の表示
plt.title("before")
plt.imshow(im)
plt.show()

####################################
# グレースケールで画像を読み込む

img = np.array(Image.open('input.bmp').convert('L'))
print(img.shape, img.dtype)
#((640L, 960L), dtype('uint8'))

# 画像の表示
plt.title("after gray")
plt.imshow(img)
plt.show()

#保存
Image.fromarray(img).save('output_gray.bmp')

#
####################################

####################################
# 平均化法でグレースケールを作成

# B/G/R各チャンネルの平均値を計算
s = (0.333 * im[:,:,0] + 0.333 * im[:,:,1] + 0.333 * im[:,:,2])

# 出力画像を保存する配列を作成 
im_gray1 = im.copy()

# グレー画像(B/G/Rの平均値を各色へ代入する)
im_gray1[:,:,0] = s  # Red
im_gray1[:,:,1] = s  # Green
im_gray1[:,:,2] = s  # Blue

print(im_gray1.shape, im_gray1.dtype)
#((640L, 960L, 3L), dtype('uint8'))

# 画像の表示
plt.title("after gray ave")
plt.imshow(im_gray1)
plt.show()

#保存
Image.fromarray(im_gray1).save('output_gray_ave.bmp')

#
####################################

####################################
# YUVのY画像(輝度情報)でグレースケールを作成
# 

# RGBカラーから輝度値へ変換する
# 参考: Wiki YUV https://ja.wikipedia.org/wiki/YUV 
im_gray2 = 0.299 * im[:, :, 0] + 0.587 * im[:, :, 1] + 0.114 * im[:, :, 2]

print(im_gray2.shape, im_gray2.dtype)
#((640L, 960L), dtype('float64'))

# imshowで画像を表示する場合は、
# float型をuint8型へ変換する必要がある。
im_gray2 = np.uint8(im_gray2)
print(im_gray2.shape, im_gray2.dtype)
#((640L, 960L), dtype('uint8'))

# 画像の表示
plt.title("after gray y")
plt.imshow(im_gray2)
plt.show()

#保存
# float型は、uint8へ変換する必要がある
Image.fromarray(im_gray2).save('output_gray_y.bmp')

#
####################################

実行結果

f:id:genetaka1810:20191102163616p:plain


グレースケール画像は、ぱっと見どれも同じようですが、「PILライブラリを使用し、グレースケールで画像を読み込む」と「YUVのY画像(輝度情報)でグレースケールを作成」により作成された画像を比較すると、差分が確認されました。

どのグレースケール画像が良いのかは、用途によるのかな?

f:id:genetaka1810:20191102163753p:plain
差分を、オレンジ色で示しています。