matplotlib

matplotlibで画像データ(OpenCV,pillow,list)を表示する

スポンサーリンク

matplotlibを使って画像を表示すると、下図のように画像の画像の座標軸が表示され、右下にはマウスポインタの座標および、その位置の画像の輝度値が表示されるので便利です。

さらに矢印アイコンで、画像の移動、虫眼鏡アイコンで画像の領域を選択すると、その領域が拡大表示されます。

matplotlibを使って画像データ(OpenCV,Pillow,list)の表示

 

Pillow画像の表示

上図ではPillowで画像を開いて、matplotlibで表示しているのですが、そのプログラムは以下の通りです。

import matplotlib.pyplot as plt
from PIL import Image

# Pillow でカラー画像を読み込む
pil_image_color = Image.open("Parrots.bmp")
# matplotlibで表示
plt.imshow(pil_image_color)    
plt.show()

ただし、モノクロ画像を以下のようなプログラムで画像を表示すると、変な色合いになります。

import matplotlib.pyplot as plt
from PIL import Image

# Pillow でモノクロ画像を読み込む
pil_image_color = Image.open("Text.bmp")
# matplotlibで表示
plt.imshow(pil_image_color)    
plt.show()

matplotlibを使って画像データ(OpenCV,Pillow,list)の表示

 

モノクロのグレースケールで表示するには、imshowの引数にグレースケールの cmap(カラーマップ、カラーパレット) “gray” を指定して、以下のようにします。

import matplotlib.pyplot as plt
from PIL import Image

# Pillow でモノクロ画像を読み込む
pil_image_color = Image.open("Text.bmp", cmap = "gray")
# matplotlibで表示
plt.imshow(pil_image_color)    
plt.show()

matplotlibを使って画像データ(OpenCV,Pillow,list)の表示

 

このカラーマップ(cmap)にはデフォルトで “viridis” というものが設定されていて、下図のような色味になっています。

matplotlibを使って画像データ(OpenCV,Pillow,list)の表示

 

カラーマップは他にも hsv や rainbow, jet など様々用意されており、例えば、rainbowを使うと、下図のようになります。

matplotlibを使って画像データ(OpenCV,Pillow,list)の表示

 

カラーマップは色々用意されているので、モノクロ画像を疑似カラーで表示したい場合は、gray以外のものを使用するのも便利だと思います。

カラーマップの詳細については、以下のページで確認できます。

Colormap reference — Matplotlib 3.4.1 documentation

 

OpenCV画像の表示

matplotlibのimshow関数に指定する画像データはPillowの画像以外にも、OpenCVの画像データ(実態はnumpyのndarray)も指定可能です。

以下のようなプログラムを実行すると

import matplotlib.pyplot as plt

import cv2

# OpenCVでモノクロ画像を読み込む
cv_image_mono = cv2.imread("Text.bmp", cv2.IMREAD_UNCHANGED)
print(type(cv_image_mono))
print(cv_image_mono.shape)
# matplotlibで表示
plt.imshow(cv_image_mono, cmap = "gray")    
plt.show()

下図のようにモノクロ画像が表示されます。

matplotlibを使って画像データ(OpenCV,Pillow,list)の表示

さらにコマンドライン上には、OpenCVで読み込んだ画像の型が <class ‘numpy.ndarray>と表示されていることが確認でき、OpenCVの画像データがnumpyのndarrayそのものだという事がわかります。

matplotlibを使って画像データ(OpenCV,Pillow,list)の表示

画像データのサイズを shapeで表示していますが、モノクロ画像データの時は、二次元配列となっています。

 

同様にして、OpenCVのカラー画像を表示すると、

import matplotlib.pyplot as plt

import cv2

# OpenCVでカラー画像を読み込む
cv_image_color = cv2.imread("Parrots.bmp", cv2.IMREAD_UNCHANGED)
print(type(cv_image_color))
print(cv_image_color.shape)
# matplotlibで表示
plt.imshow(cv_image_color)    
plt.show()

プログラムの実行結果は下図のようになります。

matplotlibを使って画像データ(OpenCV,Pillow,list)の表示

matplotlibを使って画像データ(OpenCV,Pillow,list)の表示

OpenCVのカラー画像をmatplotlibで表示すると、モノクロの時のように、また、変な色になってしまいます。

これは、OpenCVのカラー画像のデータの並びが B, G, R, B, G, R ・・・となっているのですが、matplotlibへは R, G, B, R, G, B ・・・の並びのデータで渡す必要があり、OpenCVのカラー画像をmatplotlibで表示するには、RGBのデータの並びを逆にする必要があります。

また、 shapeの結果が (256, 256, 3) と表示されているように、カラー画像の場合、三次元配列である事が確認できます。

 

BGRのデータをRGBのデータへ変換するには、OpenCVのcvtColor関数を使い

cv_image_color = cv2.cvtColor(cv_image_color, cv2.COLOR_BGR2RGB)

のように、2番目の引数にcv2.COLOR_BGR2RGBを指定し、RGBの並びを逆にします。

import matplotlib.pyplot as plt

import cv2

# OpenCVでカラー画像を読み込む
cv_image_color = cv2.imread("Parrots.bmp", cv2.IMREAD_UNCHANGED)

# BGR から RGB へ変換
cv_image_color = cv2.cvtColor(cv_image_color, cv2.COLOR_BGR2RGB)
#cv_image_color = cv_image_color[:, :, ::-1] # numpyのndarrayに対してスライスを使って反転
# matplotlibで表示
plt.imshow(cv_image_color, cmap = "gray")    
plt.show()

matplotlibを使って画像データ(OpenCV,Pillow,list)の表示

 

OpenCVの画像データはnumpyのndarrayなので、スライスを使って、BGRからRGBへ変換することも可能です。

cv_image_color = cv_image_color[:, :, ::-1]

ただし、この場合、カラー画像データが32bitの場合、OpenCVのカラーデータの並びはB, G, R, A となっているため、このまま並びを反転すると A, R, G, B となり、matplotlibで表示すると、変な色になってしまいます。

32bitのカラー画像をmatplotlibへ渡すには、R, G, B, A の順になっている必要があるため、numpyで並びを逆にしたい場合は

cv_image_color = cv_image_color[:, :, [2, 1, 0, 3]]

とする必要があり面倒なので、OpenCVを使っている場合、cvtColorを使った方がよさそうです。

ちなみに、OpenCVで32bitのカラー画像の並びを反転させるには、本来であれば、

cv_image_color = cv2.cvtColor(cv_image_color, cv2.COLOR_BGRA2RGBA)

もしくは

cv_image_color = cv2.cvtColor(cv_image_color, cv2.COLOR_BGRA2RGB)

とすべきなのですが、

cv_image_color = cv2.cvtColor(cv_image_color, cv2.COLOR_BGR2RGB)

としても、 cv2.COLOR_BGRA2RGBと同じ動き(32bitBGRAから24bitRGBへの変換)となっていました。

 

listデータの表示

matplotlibのimshowで表示する画像データは、ここ↓のページ

matplotlib.pyplot.imshow — Matplotlib 3.4.1 documentation

を見ても分かるように、配列かPIL Imageを渡す事ができます。

この配列の値は 0~1のfloatの値か、もしくは 0~255のintの値であれば、表示することが可能です。

という事は、Deep Learningでは画像データの0~255を0~1へ変換することが多いので、便利そうです。

また、配列はnumpyのndarrayだけでなく、Pythonのlistも渡す事ができ、以下にサンプルを示します。

import matplotlib.pyplot as plt

list_data = [list(range(256)) for i in range(256)]
plt.imshow(list_data, cmap = "gray")    
plt.show()

matplotlibを使って画像データ(OpenCV,Pillow,list)の表示

 

参考

matplotlib.pyplot.imshow — Matplotlib 3.4.1 documentation
Colormap reference — Matplotlib 3.4.1 documentation

コメント

タイトルとURLをコピーしました