PythonとOpenCVを用いて画像をRGBからHSVに変換する方法をソースコード付きで解説します。
【はじめに】HSV色空間とは
HSV色空間とは、「色相(Hue)」「彩度(Saturation)」「明度(Value)」の3つの組み合わせで色を表現する手法です。
– | 説明 |
---|---|
色相(H) | 色合い。(赤っぽい、青っぽいといった色のおおまかな違いのことで、赤なら0度、黄色なら 60度といったように角度で色合いが決まります) |
彩度(S) | 色の鮮やかさ。(色相が同じ場合でも、彩度が高ければ鮮やかに見え、低ければグレーに見える。彩度がゼロの場合は無彩色[黒、グレー、白]) |
明度(V) | 色の明るさ。(高いほど明るい色になる) |
HSV色空間は人間が色を知覚する方法と類似しているため、RGB色空間よりも人がイメージした通りの色を作りやすいという特徴があります。
この特徴から、画像処理でも色検出をおこなう場合などにHSV色空間が利用されています。
動画解説
本ページの内容は動画でも解説しています。
【換算式】RGB色空間からHSV色空間への変換
(R、G、B)の値が0.0(最小)から1.0(最大)の範囲にあるとします。
R,G,Bの3つの値のうち、最大のものをMAX、最小のものをMINとしたとき、色相(H)は以下の式で計算できます。
(1)
円錐モデルのときのS(色彩)は以下の式で計算できます。
(2)
円柱モデルのときのS(色彩)は以下の式で計算できます。
(3)
V(明度)は以下の式で計算できます。
(4)
色相が負の値になれば、360を加算して0~360の範囲内に収めます。
色彩と明度は0~1の範囲内に値が収まります。
– | 関連記事 |
---|---|
詳細① | 【画像処理】RGBからHSVへの変換 |
詳細② | 【画像処理】HSV色空間の原理・特徴・計算式 |
【実装】Python版OpenCVでRGBからHSV色空間に変換
画像をRGBからHSVに変換する計算式と原理については下記事で紹介しています。
また、OpenCVライブラリでは、cv2.cvtColorメソッドでRGBからHSVに変換できます。
書式
hsv = cv2.cvtColor(img, cv2.COLOR_BGR2HSV)
パラメータ名 | 説明 |
---|---|
img | 入力画像(RGB) |
hsv | 出力画像(HSV) |
※出力されたHSV画像のHueは[0,179], Saturationは[0,255],Valueは[0,255]の範囲の値をとります。
今回は、「変換アルゴリズムを自前で実装する方法」と「cvtColorメソッドを利用する方法」を両方試してみます。
ソースコード①
変換アルゴリズムを自前で実装した場合のソースコードです。
#-*- coding:utf-8 -*- import cv2 import numpy as np def rgb_to_hsv(src, ksize=3): # 高さ・幅・チャンネル数を取得 h, w, c = src.shape # 入力画像と同じサイズで出力画像用の配列を生成(中身は空) dst = np.empty((h, w, c)) for y in range(0, h): for x in range(0, w): # R, G, Bの値を取得して0~1の範囲内にする [b, g, r] = src[y][x]/255.0 # R, G, Bの値から最大値と最小値を計算 mx, mn = max(r, g, b), min(r, g, b) # 最大値 - 最小値 diff = mx - mn # Hの値を計算 if mx == mn : h = 0 elif mx == r : h = 60 * ((g-b)/diff) elif mx == g : h = 60 * ((b-r)/diff) + 120 elif mx == b : h = 60 * ((r-g)/diff) + 240 if h < 0 : h = h + 360 # Sの値を計算 if mx != 0:s = diff/mx else: s = 0 # Vの値を計算 v = mx # Hを0~179, SとVを0~255の範囲の値に変換 dst[y][x] = [h * 0.5, s * 255, v * 255] return dst # 入力画像の読み込み img = cv2.imread("C:\prog\python\\test\input.jpg") # 方法1(NumPyで実装) hsv = rgb_to_hsv(img) # 結果を出力 cv2.imwrite("C:\prog\python\\test\hsv.jpg", hsv)
ソースコード②
変換アルゴリズムをcv2.cvtColorメソッドで実装した場合のソースコードです。
#-*- coding:utf-8 -*- import cv2 import numpy as np # 入力画像の読み込み img = cv2.imread("C:\prog\python\\test\input.jpg") # 方法2(OpenCVで実装) hsv = cv2.cvtColor(img, cv2.COLOR_BGR2HSV) # 結果を出力 cv2.imwrite("C:\prog\python\\test\hsv.jpg", hsv)
実行結果
サンプルプログラムの実行結果です。
■左から入力画像(input.jpg)、出力画像(hsv2.jpg)
お借りした画像:プロ生ちゃん(暮井 慧)
- | 関連記事 |
---|---|
1 | PythonでOpenCV入門 サンプル集 |
2 | 【Python】画像処理プログラミング入門 |
3 | 【画像処理入門】アルゴリズム&プログラミング |
コメント
とても参考になりました。ありがとうございます。
誤植なのかなと思う点があるので、こちら修正よければお願いします。間違っていたら申し訳ないです。
1. HSV値のHを求めるところで、RGBの値のそれぞれどの値が最大なのかで3つの式に分かれると思うのですが、記事内の(1)の式で、MAX=BとMAX=Rの式が反対になっている気がします。
2. 上で指摘した式と同じところで、60*(G-R)/(MAX-MIN)+60 の式ですが、+60は必要ないように思います。
Pythonソースコードでは正しい式になっているため、おそらく誤植であろうと思い報告させていただきました。余計なおせっかいでしたら申し訳ないです。
以下、参考にしたOpenCVのリファレンスです。
https://docs.opencv.org/4.5.1/de/d25/imgproc_color_conversions.html#color_convert_rgb_hsv
ありがとうございます。修正しました。