NumPyでRGB画像の色チャンネルを分離して単色化、白黒化、色交換

Posted: | Tags: Python, NumPy, 画像処理

Python, NumPyを使った画像処理において、RGB画像は行(高さ) x 列(幅) x 色(3)の三次元の配列ndarray、白黒画像は行(高さ) x 列(幅)の二次元の配列ndarrayになる。

ただの配列なのでそれぞれの色チャンネルに対する処理も簡単。

  • 単色化
  • 白黒化(グレースケール化)
  • 色交換(色の入れ替え)

について説明する。

画像ファイルの読み込みや保存については以下の記事を参照。

単色化

他の色の値を0にして単色画像を生成する。さらに横に並べて結合する。

結合についての詳細は以下の記事参照。

from PIL import Image
import numpy as np

im = np.array(Image.open('data/src/lena_square.png'))

im_R = im.copy()
im_R[:, :, (1, 2)] = 0
im_G = im.copy()
im_G[:, :, (0, 2)] = 0
im_B = im.copy()
im_B[:, :, (0, 1)] = 0

# 横に並べて結合(どれでもよい)
im_RGB = np.concatenate((im_R, im_G, im_B), axis=1)
# im_RGB = np.hstack((im_R, im_G, im_B))
# im_RGB = np.c_['1', im_R, im_G, im_B]

pil_img_RGB = Image.fromarray(im_RGB)
pil_img_RGB.save('data/dst/lena_numpy_split_color.jpg')

NumPy画像処理 単色化

白黒化(グレースケール化)

ここでは輝度信号Yを計算して白黒画像(グレースケール画像)を生成する。Yの計算式については以下のページ参照。

im_gray = 0.299 * im[:, :, 0] + 0.587 * im[:, :, 1] + 0.114 * im[:, :, 2]

print(im.dtype)
print(im_gray.dtype)
# uint8
# float64

print(im.shape)
print(im_gray.shape)
# (512, 512, 3)
# (512, 512)

pil_img_gray = Image.fromarray(np.uint8(im_gray))
pil_img_gray.save('data/dst/lena_numpy_gray.jpg')

小数点を使った計算によって型dtypefloatになるので、Pillowでの保存時はuint8に変換する。

RGB画像(行(高さ) x 列(幅) x 色(3)の三次元の配列ndarray)から白黒画像(行(高さ) x 列(幅)の二次元の配列ndarray)を算出しているが、Pillowを使って保存saveすると、特に指定しなくても白黒画像として保存してくれる。

NumPy画像処理 白黒化

PillowやOpenCVの関数を使ってカラー画像を白黒画像に変換することもできる。以下の記事を参照。

色交換(入れ替え)

RとBを入れ替える。

im_swap = im.copy()
im_swap[:, :, 0], im_swap[:, :, 2] = im[:, :, 2], im[:, :, 0]

pil_img_swap = Image.fromarray(im_swap)
pil_img_swap.save('data/dst/lena_numpy_swap_color.jpg')

NumPy画像処理 色交換

関連カテゴリー

関連記事