ヒストグラム その3: 2次元ヒストグラム

目的

このチュートリアルでは2次元ヒストグラムを計算し可視化する方法を学びます.

イントロダクション

最初のチュートリアルで1次元ヒストグラムの計算方法及び描画方法を学びました.一つの特徴(グレースケール画像の画素値)しか見ていないために1次元とと呼んでいます.しかし2次元ヒストグラムを計算するためには二つの特徴について考えなければいけません.普通,各画素のHueとSaturationの二つの特徴を考えます.

pythonの公式サンプル にカラーヒストグラムの計算方法が含まれています.そのようなカラーヒストグラムを作成する方法を理解し,これ以降のトピックであるヒストグラムの逆投影法の理解にも有用であることを学びます.

OpenCVの2次元ヒストグラム

1次元ヒストグラムと同様 cv2.calcHist() 関数を使います.カラーヒストグラムを計算するために,カラー画像をBGRからHSVへと変換する必要があります(1次元ヒストグラムの計算をする時はBGRをグレースケールに変換しました).2次元ヒストグラムを計算するために,パラメータを以下のように変更します.:

  • channels = [0,1] HとSの二つの色成分を処理するため
  • bins = [180,256] Hの成分のために180,Sの成分のために256
  • range = [0,180,0,256] Hueの値は0から180まで,Saturation野値は0から256まで

コードは以下のようになります:

import cv2
import numpy as np

img = cv2.imread('home.jpg')
hsv = cv2.cvtColor(img,cv2.COLOR_BGR2HSV)

hist = cv2.calcHist([hsv], [0, 1], None, [180, 256], [0, 180, 0, 256])

以上です.

Numpyを使った2次元ヒストグラム

Numpyも2次元ヒストグラムの計算をするための関数を用意しています : np.histogram2d(). (1次元ヒストグラムを計算する関数は np.histogram() です).

import cv2
import numpy as np
from matplotlib import pyplot as plt

img = cv2.imread('home.jpg')
hsv = cv2.cvtColor(img,cv2.COLOR_BGR2HSV)

hist, xbins, ybins = np.histogram2d(h.ravel(),s.ravel(),[180,256],[[0,180],[0,256]])

第1引数はH成分,第2引数はS成分,第3引数は各成分のビンの数,第4引数は各成分の範囲を表します.

次に,計算したカラーヒストグラムの表示方法を確認します.

2次元ヒストグラムの可視化

方法1 : cv2.imshow()を使う

我々が取得した2次元配列のサイズは180x256です.いつも通りcv2.imshow()関数を使って可視化します.結果の可視化はグレースケール画像になります.異なる色のHueの値を知るまでどの色が何を意味するのかさほど重要ではないでしょう.

方法2 : Matplotlibを使う

matplotlib.pyplot.imshow() 関数を使って2次元ヒストグラムを異なるカラーマップで表示できます.異なる画素密度についてより良い結果を作れます.異なる色のHueの値を知るまではそれぞれが何を意味するのか理解できないでしょう.それでもまだ,単純なこの方法が好きです.

Note

この関数を使って良い結果を得るためには,内挿のフラグを nearest にしてください.

以下のコードを考えてみましょう:

import cv2
import numpy as np
from matplotlib import pyplot as plt

img = cv2.imread('home.jpg')
hsv = cv2.cvtColor(img,cv2.COLOR_BGR2HSV)
hist = cv2.calcHist( [hsv], [0, 1], None, [180, 256], [0, 180, 0, 256] )

plt.imshow(hist,interpolation = 'nearest')
plt.show()

以下に入力画像とそのカラーヒストグラムを示します.横軸がS成分,縦軸がH成分を表します.

2D Histograms

ヒストグラムを見ると,H = 100,S = 200の辺りに高い値を示しているのが分かります.これは空の青色に対応しています.もう一つのピークがH = 25,S = 100の辺りに見えます.これは宮殿の黄色に対応しています.GIMPなどの画像編集ソフトを使って確認できます.

方法3 : OpenCVのサンプル方式!!

OpenCV-Python2のサンプルコードの中に カラーヒストグラムを作成するサンプル が含まれています.コードを実行すると,ヒストグラムが対応する色も表示することが分かります.別の言い方をすると色でコード化されたヒストグラムと呼べるでしょう.結果はとてもいいものになります(数行のコードを追加する必要がありますが).

コード中で,作者はカラーマップをHSV空間で作成し,その後にBGR空間に変換しています.結果として得られるヒストグラムはカラーマップがかけられたような映像になります.良いヒストグラムを出力するために小さいプロットの塊を取り除くための前処理が必要になります.

コードの実行,解析,改造は皆さんが行ってください.上記の画像に対してコードを実行した結果をお見せします.:

2D Histograms using OpenCV-Python Samples

ヒストグラムのプロットに青や黄色に加えてチェスボードに由来する白色がつけられているのが分かるでしょう.

補足資料

課題