Python-OpenCVでのRGBからHSVに変換

画像解析一覧

画像解析では、画像の色空間を変換することは一般的な操作になります。OpenCVは150種類以上の色空間の変換を用意しているが,その中で最も広く使われている変換方法は、BGR からGrayに変換とBGRから HSVに変換であります。今回の記事はBGRから HSVに変換する方法を解説します。

目次

1. 色空間とは
1.1 RGB色空間モデル
1.2 HSV色空間モデル
2. RGBからHSVに変換の換算式
3. PythonのOpenCVコード:RGBからHSVに変換
3.1データロード
3.2 RGBの画像を可視化
3.3 HSVに変換
3.4 HSVの画像を可視化

1. 色空間とは

色空間(カラースペース)とは色を定量的に表現方法です。代表的な色空間にはRGBがあるが、これは、赤(Red)、緑(Green)、青(Blue)の光の3原色を利用した色空間であり、コンピュータのモニタへの出力や、アプリケーション上の色設定などでよく用いられます。他には、テレビで用いられているYCbCr/YPbPr、印刷分野で主流であるCMYKやDICなどがあります。

1.1 RGB色空間モデル

コンピュータやテレビの映像表示に使われるディスプレイでは、色を区別する方法として RGB モデル(RGB model)が広く使われています。それに合わせて、Webサイトを制作する際に色を指定する場合にも RGB にもとづく色表記が使われます。赤(red)、緑(green)、青(blue)の 3 つであり、これらを総称して原色(primary colors)と呼びます。それぞれの要素の明度を最小の 0 から最大の 255 の間に置きます。すべての原色が混ざると白(white)になります。他方で、すべての原色が欠けると黒(black)になります。

1.2 HSV色空間モデル

HSV モデル(HSV model)とは、色相(hue)・明度(lightness)・彩度(saturation)の 3 つの基準から色を分類するモデルです。HSV モデルにおいて使われる 3 つの基準を総称して色の三属性(three attributes of color)と呼びます。HSV モデルは人間が色を知覚する方法と似ていることからデザイナーの間で広く使われています。
カラーピッカーにおいて色相は 0 度から 359 度までの数値として、彩度と明度はそれぞれ 0 から 100 までの数値として表されます。つまり、それぞれの色は 3 つの値の組み合わせとして表現されます。

2. RGBからHSVに変換の換算式

(R、G、B)の値が0.0(最小)から1.0(最大)の範囲に標準化します。
R,G,Bの3つの値のうち、最大のものをMAX、最小のものをMINとしたとき、
色相(H)は以下の式で計算できます。

円錐モデルのときのS(色彩)は以下の式で計算できます。

V(明度)は以下の式で計算できます。

色相Hが負の値になれば、360を加算して0~360の範囲内に収めます。色彩Sと明度Vは0~1の範囲内に値が収まります。

3. PythonのOpenCVコード:RGBからHSVに変換

環境:
Google Colab
Runtime: Python3 GPU

Wikipediaから画像を保存します。

import urllib 
img_src = 'https://upload.wikimedia.org/wikipedia/commons/thumb/0/0d/Great_Wave_off_Kanagawa2.jpg/330px-Great_Wave_off_Kanagawa2.jpg'
img_path = '/kanagawa.jpg'
urllib.request.urlretrieve(img_src, img_path)

(‘/kanagawa.jpg’, <http.client.HTTPMessage at 0x7f4cebfb4da0>)

画像をロードします。

# 画像を表示
from google.colab.patches import cv2_imshow
import cv2

img = cv2.imread(img_path)
cv2_imshow(img)

RGBを可視化します。

import matplotlib.pyplot as plt
import numpy as np
from mpl_toolkits.mplot3d import Axes3D
from matplotlib import cm
from matplotlib import colors

r, g, b = cv2.split(img)
fig = plt.figure(figsize=(10, 9))
axis = fig.add_subplot(1, 1, 1, projection="3d")

pixel_colors = img.reshape((np.shape(img)[0]*np.shape(img)[1], 3))
norm = colors.Normalize(vmin=-1.,vmax=1.)
norm.autoscale(pixel_colors)
pixel_colors = norm(pixel_colors).tolist()

axis.scatter(r.flatten(), g.flatten(), b.flatten(), facecolors=pixel_colors, marker=".")
axis.set_xlabel("Red")
axis.set_ylabel("Green")
axis.set_zlabel("Blue")
plt.show()

HSVに変更します。

# HSV画像を表示

HSV_img = cv2.cvtColor(img,cv2.COLOR_BGR2HSV)
cv2_imshow(HSV_img)

HSV画像を可視化します。

import matplotlib.pyplot as plt
import numpy as np
from mpl_toolkits.mplot3d import Axes3D
from matplotlib import cm
from matplotlib import colors

h, s, v = cv2.split(HSV_img)
fig = plt.figure(figsize=(10, 9))
axis = fig.add_subplot(1, 1, 1, projection="3d")

axis.scatter(h.flatten(), s.flatten(), v.flatten(), facecolors = pixel_colors, marker=".")
axis.set_xlabel("Hue")
axis.set_ylabel("Saturation")
axis.set_zlabel("Value")
plt.show()

参照:

https://algorithm.joho.info/programming/python/opencv-rgb-to-hsv-color-space/#RGBHSV