24bitsカラー画像をBGRカラープレーンに切り出す

24bitsBGRのカラー画像の Blue, Green, Red をそれぞれのカラープレーンとして切り出す方法を紹介します。

このビットマップを使ってテストします。B8G8R8の24bitsビットマップファイルです。

grad_bpp24.bmp

この画像を Blue, Green, Red でそれぞれ 8bits のグレースケール画像として色分解していきます。

from PIL import Image
import numpy as np
import matplotlib.pyplot as plt

filepath = "c:/tmp/grad_bpp24.bmp"
im = Image.open( filepath )
arr888 = np.array( im )

# 24ビット画像.
print( "---------------------" )
print( arr888.shape )
plt.imshow( arr888, cmap='gray')
plt.title( "24bitsBGR" )
plt.show()
print( "---------------------" )

# --------------------------------------------------
# カラープレーンに切り出す.
arr_b = arr888[:,:,2]
arr_g = arr888[:,:,1]
arr_r = arr888[:,:,0]
# タプルでイッキに書くならこちら.
# arr_b, arr_g, arr_r = arr888[:,:,2], arr888[:,:,1], arr888[:,:,0]
# --------------------------------------------------

# 青のプレーン.
print( "---------------------" )
print( arr_b.shape )
plt.imshow( arr_b, cmap='gray')
plt.title( "Blue" )
plt.show()
print( "---------------------" )

# 緑のプレーン.
print( "---------------------" )
print( arr_g.shape )
plt.imshow( arr_g, cmap='gray')
plt.title( "Green" )
plt.show()
print( "---------------------" )

# 赤のプレーン.
print( "---------------------" )
print( arr_r.shape )
plt.imshow( arr_r, cmap='gray')
plt.title( "Red" )
plt.show()
print( "---------------------" )

print( "finish." )

下記が実行結果です。

コンソールの出力結果はこうなります。

PS C:\tmp> python test.py
---------------------
(256, 512, 3)
---------------------
---------------------
(256, 512)
---------------------
---------------------
(256, 512)
---------------------
---------------------
(256, 512)
---------------------
finish.

ネットの記事では Red と Blue の成分の扱いが逆で、間違っているものも散見されます。

たぶん間違っている理由は Pillow と ndarray の関係においては並びが RGB であることに反して、OpenCV と ndarray の関係では BGR になっているから、そのあたりの行き来でごっちゃになっているのだと思います。ご注意ください。

本記事は Pillow から ndarray に変換してからの色分解の手法です。ここから ndarray を介して OpenCV の世界までは踏み込んでいませんので、本記事の並びは RGB の順になります。