OpenCVでRGBとHSVのヒストグラムを取得する方法


#はじめに

画像を扱っていて、RGBやHSVのヒストグラムの情報を特徴量として使いたいと思いました。
そこで**OpenCV**を使ってヒストグラムを抽出してみました。
メモとして残しておきます。

#ヒストグラム

`ヒストグラムとは、画像中の画素値の全体的な分布を知るためのグラフやプロット`とみなせます。一般的に横軸に画素値、縦軸に画素値の出現頻度を載せるプロットです。ヒストグラムの可視化は画像を理解するための１つの方法です。
`
#RGBとHSVの違いは？

###RGB

RGBはそれぞれ赤(Red)、緑(Green)、青(Blue)の頭文字をとったもので、この３色は「光の３原色」と呼ばれており、ブラウン管、液晶モニター等で色を表現するための手法です。原色ひとつにつき、256段階の濃さを設定できるため、256の３乗の16,777,216通りの色を表現可能です。


###HSV

HSVは色を色相(Hue)、彩度(Saturation)、明度(Value・Brightness)の３要素で表現する方式です。
**色相**：色相環(色相の輪)　輪の形、もしくは0度～360度の範囲で表示されます
**彩度**：色の鮮やかさの度合い　数値が低いと彩度が低く、高いと彩度が上がります
**明度**：色の明るさの度合い　数値が低いと暗くなり、高いと明るくなります



#画像の読み込み

画像の読み込みの際の注意点です。

####1. OpenvCVでの読み込み
```.py
import cv2

img = cv2.imread("sample.jpg")
```
この場合imgは`BGR`となっています。
もし、`RGB`に変換したい場合は以下の方法で変換できます。

```.py
img_rgb = cv2.cvtColor(img, cv2.COLOR_BGR2RGB)
```

####2. pillowでの読み込み


```.py
from PIL import Image

img = Image.open("sample.jpg")
```

pillowでの読み込みでは、`RGB`で読み込めます。


#画像指定でRGBとHSVを返す関数

Pythonで画像を渡すとR,G,B,H,S,Vのヒストグラムを返す関数を実装しました。jupyterで実行した結果も載せておきました。

```.py

def show_img(path):

    img = cv2.imread(path)
    b, g, r = img[:,:,0], img[:,:,1], img[:,:,2]
    hist_b = cv2.calcHist([b],[0],None,[256],[0,256])
    hist_g = cv2.calcHist([g],[0],None,[256],[0,256])
    hist_r = cv2.calcHist([r],[0],None,[256],[0,256])
    plt.plot(hist_r, color='r', label="r")
    plt.plot(hist_g, color='g', label="g")
    plt.plot(hist_b, color='b', label="b")
    plt.legend()
    plt.show() 
    img2 = cv2.cvtColor(img, cv2.COLOR_BGR2HSV)
    h, s, v = img2[:,:,0], img2[:,:,1], img2[:,:,2]
    hist_h = cv2.calcHist([h],[0],None,[256],[0,256])
    hist_s = cv2.calcHist([s],[0],None,[256],[0,256])
    hist_v = cv2.calcHist([v],[0],None,[256],[0,256])
    plt.plot(hist_h, color='r', label="h")
    plt.plot(hist_s, color='g', label="s")
    plt.plot(hist_v, color='b', label="v")
    plt.legend()
    plt.show()
    
    return hist_r,hist_g, hist_b, hist_h, hist_s, hist_v
```

今回は以下の犬の画像でやってみます。
![dog.jpeg](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/223559/bb44c988-be92-6d67-04fa-31afbf028732.jpeg)


```.py
r,g,b,h,s,v = show_img("dog.jpeg")
```

![Screenshot from 2020-01-20 08-45-48.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/223559/ab71bc79-c56c-f1fc-bea1-7ce18bc332d8.png)



####ヒストグラムの計算について
OpenCVでは以下の関数を使用しヒストグラムを計算します。

`cv2.calcHist(images, channels, mask, histSize, ranges[, hist[, accumulate]])`

**images** : 入力画像です．画素値のデータ型はuint8かfloat32のどちらかです．記号[]を使って “[img]” のように指定します。
**channels** : ヒストグラムを計算する画像のチャンネルのインデックスです．入力画像がグレースける画像であれば[0]を指定します．カラー画像であればヒストグラムを計算するB,G,Rの色相に対応する[0]，[1]，[2]のどれかの値を指定します。
**mask** : マスク画像です．画像中の全画素のヒストグラムを計算する場合 “None” を指定します．画像中の特定領域のヒストグラムを計算する場合は特定領域を表すマスク画像を指定します(以下に例を示します)。
**histSize** : ビンの数です．この引数も記号[]を使って指定します．全画素値を対象とするのであれば [256] を指定します。
**ranges** : ヒストグラムを計測したい画素値の範囲を表す RANGE です．通常は [0,256] を指定します。



#参考文献

- [色におけるRGBとCMYKについて](https://www.sokupuri.jp/archives/366)

- [HSV色空間とは](https://www.peko-step.com/html/hsv.html)

- [ヒストグラム その1: 計算して，プロットして，解析する !!!](http://labs.eecs.tottori-u.ac.jp/sd/Member/oyamada/OpenCV/html/py_tutorials/py_imgproc/py_histograms/py_histogram_begins/py_histogram_begins.html)