色空間
Color Spaces
色空間とは
色空間(Color Space)は、色を数値で表現するための座標系である。目的に応じて様々な色空間が使い分けられる。
RGB色空間
RGB色空間は、赤(Red)、緑(Green)、青(Blue)の3原色の加法混色で色を表現する。
RGB立方体
加法混色
R, G, B ∈ [0, 255] (8bit) 総色数: 256³ ≈ 1677万色
光の三原色と色の三原色
色の混合には2つの方式がある。
| 特性 | 加法混色(光の三原色) | 減法混色(色の三原色) |
|---|---|---|
| 原色 | R(赤)、G(緑)、B(青) | C(シアン)、M(マゼンタ)、Y(イエロー) |
| 混ぜると | 明るくなる(全部混ぜると白) | 暗くなる(全部混ぜると理論上黒) |
| 原理 | 光を足す(発光) | 光を吸収する(反射光から引く) |
| 用途 | ディスプレイ、照明、カメラ | 印刷(CMYK)、絵の具 |
| 関係 | C = G+B(赤を引く)、M = R+B(緑を引く)、Y = R+G(青を引く) 加法と減法の原色は補色の関係にある |
|
印刷では CMY だけでは完全な黒が出ないため、黒インク(K: Key)を追加した CMYK が使われる。 コンピュータビジョンでは主に加法混色の RGB を扱う。
注意: OpenCVでは画像をBGR順序で扱う。RGB画像を読み込む際は変換が必要。
HSV/HSL色空間
HSV(Hue, Saturation, Value)は人間の色の知覚に近い表現で、色の選択や抽出に適している。
HSVの各成分
- H(Hue)色相: 色の種類。0°〜360°で表現(赤=0°, 緑=120°, 青=240°)
- S(Saturation)彩度: 色の鮮やかさ。0〜1(0=灰色、1=純色)
- V(Value)明度: 明るさ。0〜1(0=黒、1=最大輝度)
RGB → HSV 変換
$$M = \max(R, G, B), \quad m = \min(R, G, B), \quad C = M - m$$ $$V = M, \quad S = \frac{C}{M} \quad (M \neq 0)$$ $$H = 60° \times \begin{cases} (G-B)/C \bmod 6 & \text{if } M=R \\ (B-R)/C + 2 & \text{if } M=G \\ (R-G)/C + 4 & \text{if } M=B \end{cases}$$用途: 色によるオブジェクト検出、肌色検出、背景除去など。 例えば赤色検出は H: 0°〜10° または 350°〜360° の範囲を指定する。
OpenCV固有の注意: OpenCVでは Hue の範囲は 0〜179(360°を半分にして8ビットに収める)、Saturation と Value は 0〜255 である。 数式の値から変換する際は H を半分にする必要がある。
YUV / YCbCr 色空間
輝度(Y)と色差を分離した色空間である。人間の視覚が輝度に敏感で色差に鈍感であることを利用して、色差を間引くことでデータ量を削減できる。
YUV と YCbCr の違い
| 特性 | YUV | YCbCr |
|---|---|---|
| 由来 | アナログテレビ(PAL / NTSC) | デジタル映像規格 |
| 値の範囲 | 連続値(アナログ信号) | 0〜255 に量子化(デジタル) |
| 用途 | アナログ放送、ビデオ信号 | JPEG, H.264, MPEG, HDMI |
| 変換係数 | 規格により異なる(BT.601: SD, BT.709: HD, BT.2020: 4K/8K) | |
多くの文献やライブラリで YUV と YCbCr は混同されているが、
OpenCV では COLOR_BGR2YUV と COLOR_BGR2YCrCb は異なる変換を行う。
現代のコンピュータビジョンでは主に YCbCr(デジタル版)を扱う。
RGB → YCbCr 変換(BT.601)
$$\begin{pmatrix} Y \\ C_b \\ C_r \end{pmatrix} = \begin{pmatrix} 0.299 & 0.587 & 0.114 \\ -0.169 & -0.331 & 0.500 \\ 0.500 & -0.419 & -0.081 \end{pmatrix} \begin{pmatrix} R \\ G \\ B \end{pmatrix} + \begin{pmatrix} 0 \\ 128 \\ 128 \end{pmatrix}$$YCbCrの値域: ビデオ規格では通常、Y は 16〜235、Cb/Cr は 16〜240 の「スタジオスイング」範囲を使用する。
ただし、OpenCV の cvtColor はフルレンジ(0〜255)で変換する。
Lab色空間(CIELAB)
Lab は人間の知覚に合わせて設計された知覚均等な色空間である。ユークリッド距離が知覚的な色差とよく相関するため、色差評価やカラーマネジメントに広く使われる。
Lab の各成分
- L: 明度(0=黒、100=白)
- a: 緑(−)〜 赤(+)軸
- b: 青(−)〜 黄(+)軸
RGB → Lab 変換の流れ
RGB → XYZ(デバイス非依存の中間色空間)→ Lab
XYZ から Lab への変換には非線形関数を用いる:
$$L^* = 116\,f\!\left(\frac{Y}{Y_n}\right) - 16, \quad a^* = 500\left[f\!\left(\frac{X}{X_n}\right) - f\!\left(\frac{Y}{Y_n}\right)\right], \quad b^* = 200\left[f\!\left(\frac{Y}{Y_n}\right) - f\!\left(\frac{Z}{Z_n}\right)\right]$$ここで $f(t) = t^{1/3}$($t > \delta^3$ のとき)、$\delta = 6/29$。$X_n, Y_n, Z_n$ は白色点の三刺激値。
用途: 色差計算($\Delta E$)、カラーキャリブレーション、画像セグメンテーション。 $\Delta E = \sqrt{(\Delta L^*)^2 + (\Delta a^*)^2 + (\Delta b^*)^2}$ が知覚的な色の違いの指標となる。
グレースケール変換
カラー画像をグレースケールに変換する方法はいくつかある:
輝度法(Luminosity Method) - 最も一般的
$$Y = 0.299R + 0.587G + 0.114B$$人間の目の感度に基づいた重み付け
平均法(Average Method)
$$Y = \frac{R + G + B}{3}$$明度法(Lightness Method)
$$Y = \frac{\max(R,G,B) + \min(R,G,B)}{2}$$コード例(Python)
import cv2
import numpy as np
# 画像読み込み(BGR)
img_bgr = cv2.imread('image.jpg')
# 色空間変換
img_rgb = cv2.cvtColor(img_bgr, cv2.COLOR_BGR2RGB)
img_hsv = cv2.cvtColor(img_bgr, cv2.COLOR_BGR2HSV)
img_ycrcb = cv2.cvtColor(img_bgr, cv2.COLOR_BGR2YCrCb)
img_gray = cv2.cvtColor(img_bgr, cv2.COLOR_BGR2GRAY)
img_lab = cv2.cvtColor(img_bgr, cv2.COLOR_BGR2LAB)
# HSVで特定の色を抽出(例:赤色)
lower_red = np.array([0, 100, 100])
upper_red = np.array([10, 255, 255])
mask = cv2.inRange(img_hsv, lower_red, upper_red)
result = cv2.bitwise_and(img_bgr, img_bgr, mask=mask)
# グレースケール手動計算(輝度法)
b, g, r = cv2.split(img_bgr)
gray_manual = (0.299 * r + 0.587 * g + 0.114 * b).astype(np.uint8)
まとめ
- RGB: ディスプレイ表示の標準、加法混色
- HSV/HSL: 人間の知覚に近い、色抽出に適する
- YUV/YCbCr: 輝度と色差の分離、動画圧縮に使用
- Lab: 知覚均等、色差計算やカラーマネジメントに最適
- グレースケール: 輝度のみ、多くの画像処理の前処理として使用