RGBをxyYに変換


## 概要

RGBで表される色をxyYに変換する。

まず、各変数等を定義する。つぎにRGBからXYZへの変換行列を導出し、xyYへ変換する。最後に代表的な色空間での変換行列を記載する。

## 前提条件

```math
R, G, B \in [0,1]
```

## 色域と白色点の定義

RGBからxyYへの変換の際には色域と白色点が必要になる。

RGBの色を$\boldsymbol{C}_{\rm RGB} = \left[R, G, B\right]^T$、

xyYの色を$\boldsymbol{C}_{\rm xyY} = [x,y,Y]^T$とおき、

RGBからxyYへの変換を

```math
\boldsymbol{C}_{\rm xyY} = f_{\rm xyY}(\boldsymbol{C}_{\rm RGB})
```
とする。

色域は、xy平面上のつぎの座標を頂点とする三角形で表される。

```math
\begin{align}
& \boldsymbol{C}_{\rm xyY}^{\rm R} = f_{\rm xyY}\left([1,0,0]^T\right),\\
& \boldsymbol{C}_{\rm xyY}^{\rm G} = f_{\rm xyY}\left([0,1,0]^T\right),\\
& \boldsymbol{C}_{\rm xyY}^{\rm B} = f_{\rm xyY}\left([0,0,1]^T\right).
\end{align}
```

また、白色点はつぎのとおりである。

```math
\boldsymbol{C}_{\rm xyY}^{\rm W} = f\left([1,1,1]^T\right).
```

## XYZ, xyYへの変換

RGBからXYZへ変換し、XYZからxyYへ変換する。

XYZはRGBと同様に3つの色(光)の足し合わせで色を表現する方法である。まず、RGBそれぞれのXYZをつぎのとおり定義する。RGBからXYZへの変換を

```math
\boldsymbol{C}_{\rm XYZ} = f_{\rm XYZ}(\boldsymbol{C}_{\rm RGB})
```
とする。

```math
\begin{align}
& \boldsymbol{C}_{\rm XYZ}^{\rm R} = f_{\rm XYZ}\left([1,0,0]^T\right),\\
& \boldsymbol{C}_{\rm XYZ}^{\rm G} = f_{\rm XYZ}\left([0,1,0]^T\right),\\
& \boldsymbol{C}_{\rm XYZ}^{\rm B} = f_{\rm XYZ}\left([0,0,1]^T\right),\\
& \boldsymbol{C}_{\rm XYZ}^{\rm W} = f_{\rm XYZ}\left([1,1,1]^T \right).
\end{align}
```

これらの足し合わせによって色を表現するため、あるRGBのとき、XYZでの色はつぎのとおりとなる。

```math
\begin{align}
\boldsymbol{C}_{\rm XYZ} & = \boldsymbol{C}_{\rm XYZ}^{\rm R}R + \boldsymbol{C}_{\rm XYZ}^{\rm G}G + \boldsymbol{C}_{\rm XYZ}^{\rm B}B,\\
& = [\boldsymbol{C}_{\rm XYZ}^{\rm R}, \boldsymbol{C}_{\rm XYZ}^{\rm G}, \boldsymbol{C}_{\rm XYZ}^{\rm B}]\boldsymbol{C}_{\rm RGB}.
\end{align}
```

また、XYZとxyYの関係から、

```math
\begin{align}
&\displaystyle \left[x^{\rm R},y^{\rm R}, 1-x^{\rm R} - y^{\rm R}\right]^T = \left[ \frac{X_{\rm R}}{X_{\rm R} + Y_{\rm R} + Z_{\rm R}}, \frac{Y_{\rm R}}{X_{\rm R} + Y_{\rm R} + Z_{\rm R}}, \frac{Z_{\rm R}}{X_{\rm R} + Y_{\rm R} + Z_{\rm R}} \right]^T,\\
&\displaystyle \left[x^{\rm G},y^{\rm G}, 1-x^{\rm G}-y^{\rm G}\right]^T = \left[ \frac{X_{\rm G}}{X_{\rm R} + Y_{\rm R} + Z_{\rm R}}, \frac{Y_{\rm G}}{X_{\rm R} + Y_{\rm R} + Z_{\rm R}}, \frac{Z_{\rm G}}{X_{\rm G} + Y_{\rm G} + Z_{\rm G}} \right]^T,\\
&\displaystyle \left[x^{\rm B},y^{\rm B},1-x^{\rm B}-y^{\rm B}\right]^T = \left[ \frac{X_{\rm B}}{X_{\rm R} + Y_{\rm R} + Z_{\rm R}}, \frac{Y_{\rm B}}{X_{\rm R} + Y_{\rm R} + Z_{\rm R}}, \frac{Z_{\rm B}}{X_{\rm B} + Y_{\rm B} + Z_{\rm B}} \right]^T.
\end{align}
```

となる。

これらから、$\boldsymbol{C}_{\rm XYZ}$はつぎのとおりとなる。

```math
\boldsymbol{C}_{\rm XYZ} = \left[
\begin{matrix}
x^{\rm R}\left(X_{\rm R} + Y_{\rm R} + Z_{\rm R}\right) & 
x^{\rm G}\left( X_{\rm G} + Y_{\rm G} + Z_{\rm G} \right) & 
x^{\rm B}\left(X_{\rm B} + Y_{\rm B} + Z_{\rm B}\right) \\
y^{\rm R}\left(X_{\rm R} + Y_{\rm R} + Z_{\rm R}\right)  &
y^{\rm G}\left( X_{\rm G} + Y_{\rm G} + Z_{\rm G} \right) & 
y^{\rm B}\left(X_{\rm B} + Y_{\rm B} + Z_{\rm B}\right) \\
\left(1-x^{\rm R} - y^{\rm R}\right)\left(X_{\rm R} + Y_{\rm R} + Z_{\rm R}\right) &
\left(1-x^{\rm G} - y^{\rm G}\right)\left(X_{\rm G} + Y_{\rm G} + Z_{\rm G}\right) & 
\left(1-x_{\rm B}-y_{\rm B} \right)\left( X_{\rm B} + Y_{\rm B} + Z_{\rm B} \right)
\end{matrix}
\right]\boldsymbol{C}_{\rm RGB}.
```

さらに整理して、

```math
\boldsymbol{C}_{\rm XYZ}  = \left[
\begin{matrix}
x^{\rm R} & x^{\rm G} & x^{\rm B}\\
y^{\rm R} & y^{\rm G} & y^{\rm B}\\
\left(1 - x^{\rm R} - y^{\rm R}\right) & \left(1 - x^{\rm G} - y^{\rm G}\right) & \left(1 - x^{\rm B} - y^{\rm B}\right)\\
\end{matrix}
\right]
\left[
\begin{matrix}
X_{\rm R} + Y_{\rm R} + Z_{\rm R} & 0 & 0 \\
0 & X_{\rm G} + Y_{\rm G} + Z_{\rm G} & 0 \\
0 & 0 & X_{\rm B} + Y_{\rm B} + Z_{\rm B} \\
\end{matrix}
\right]
\boldsymbol{C}_{\rm RGB}.
```

となる。ここで、$X_{\ast} + Y_{\ast} + Z_{\ast} = A_{\ast}$とおくと、変数が3つに減る。これらを求めれば良い。

白色点から、つぎの関係が得られる。

```math
\left[X_{\rm W}, Y_{\rm W}, Z_{\rm W}\right]^T = 
\left[
\begin{matrix}
x^{\rm R} & x^{\rm G} & x^{\rm B}\\
y^{\rm R} & y^{\rm G} & y^{\rm B}\\
\left(1 - x^{\rm R} - y^{\rm R}\right) & \left(1 - x^{\rm G} - y^{\rm G}\right) & \left(1 - x^{\rm B} - y^{\rm B}\right)\\
\end{matrix}
\right]
\left[ A_{\rm R}, A_{\rm G}, A_{\rm B} \right]^T.
```

したがって、$A_{\rm R}, A_{\rm G}, A_{\rm B}$はつぎのとおり求められる。

```math
\left[A_{\rm R}, A_{\rm G}, A_{\rm B}\right]^T = 
\left[
\begin{matrix}
x^{\rm R} & x^{\rm G} & x^{\rm B}\\
y^{\rm R} & y^{\rm G} & y^{\rm B}\\
\left(1 - x^{\rm R} - y^{\rm R}\right) & \left(1 - x^{\rm G} - y^{\rm G}\right) & \left(1 - x^{\rm B} - y^{\rm B}\right)\\
\end{matrix}
\right]^{-1}
\left[ X_{\rm W}, Y_{\rm W}, Z_{\rm W} \right]^T.
```

また、白色点では、輝度を表す$Y_{\rm W}$を1となる前提を置くと、

```math
\begin{align}
& \displaystyle x_{\rm W} = \frac{X_{\rm W}}{X_{\rm W} + 1 + Z_{\rm W}},\\
& \displaystyle z_{\rm W} = \frac{Z_{\rm W}}{X_{\rm W} + 1 + Z_{\rm W}}.
\end{align}
```

となり、$X_{\rm W}, Z_{\rm W}$について解くとつぎのとおりとなる。

```math
\begin{align}
\left[X_{\rm W}, Y_{\rm W}, Z_{\rm W}\right]^T
& \displaystyle = \left[\frac{x_{\rm W}}{1 - x_{\rm W} - z_{\rm W}}, 1, \frac{z_{\rm W}}{1 - x_{\rm W} - z_{\rm W}}\right]^T,\\
& \displaystyle = \left[ \frac{x_{\rm W}}{y_{\rm W}}, 1, \frac{1-x_{\rm W}-y_{\rm W}}{y_{\rm W}} \right]^T.
\end{align}
```

したがって、RGBからxyYへの変換は、

```math
\left[A_{\rm R}, A_{\rm G}, A_{\rm B}\right]^T = 
\left[
\begin{matrix}
x^{\rm R} & x^{\rm G} & x^{\rm B}\\
y^{\rm R} & y^{\rm G} & y^{\rm B}\\
\left(1 - x^{\rm R} - y^{\rm R}\right) & \left(1 - x^{\rm G} - y^{\rm G}\right) & \left(1 - x^{\rm B} - y^{\rm B}\right)\\
\end{matrix}
\right]^{-1}
\displaystyle\left[ \frac{x_{\rm W}}{y_{\rm W}}, 1, \frac{1-x_{\rm W}-y_{\rm W}}{y_{\rm W}} \right]^T,
```

および

```math
\left[X, Y, Z \right]^T  = \left[
\begin{matrix}
x^{\rm R} & x^{\rm G} & x^{\rm B}\\
y^{\rm R} & y^{\rm G} & y^{\rm B}\\
\left(1 - x^{\rm R} - y^{\rm R}\right) & \left(1 - x^{\rm G} - y^{\rm G}\right) & \left(1 - x^{\rm B} - y^{\rm B}\right)\\
\end{matrix}
\right]
\left[
\begin{matrix}
A_{\rm R} & 0 & 0 \\
0 & A_{\rm G} & 0 \\
0 & 0 & A_{\rm B} \\
\end{matrix}
\right]
\boldsymbol{C}_{\rm RGB},
```

によって$X, Y, Z$を得て、

$$
\left[x, y, Y\right]^T = \left[ \frac{X}{X + Y + Z}, \frac{Y}{X + Y + Z}, Y \right]^T,
$$
で得られる。

## 変換行列まとめ

主な色空間の色域・白色点と変換行列をまとめる。変換行列はつぎのとおり。

```math
T = \left[
\begin{matrix}
x^{\rm R} & x^{\rm G} & x^{\rm B}\\
y^{\rm R} & y^{\rm G} & y^{\rm B}\\
\left(1 - x^{\rm R} - y^{\rm R}\right) & \left(1 - x^{\rm G} - y^{\rm G}\right) & \left(1 - x^{\rm B} - y^{\rm B}\right)\\
\end{matrix}
\right]
\left[
\begin{matrix}
A_{\rm R} & 0 & 0 \\
0 & A_{\rm G} & 0 \\
0 & 0 & A_{\rm B} \\
\end{matrix}
\right].
```

### sRGB

|  |x  |y  |
|---|---|---|
|R  |0.64  |0.33  |
|G  |0.3  |0.6  |
|B  |0.15  |0.06  |
|W  |0.3127  |0.3290  |

```math
T = \left[
\begin{matrix}
0.412391 & 0.357584 & 0.180481\\
0.212639 & 0.715169 & 0.0721923\\
0.0193308 & 0.119195 & 0.950532
\end{matrix}\right].
```

### AdobeRGB

|  |x  |y  |
|---|---|---|
|R  |0.64  |0.33  |
|G  |0.21  |0.71  |
|B  |0.15  |0.06  |
|W  |0.3127  |0.3290  |

```math
T = \left[
\begin{matrix}
0.576669 & 0.185558 & 0.188229\\
0.297345 & 0.627364 & 0.0752915\\
0.0270314 & 0.0706889 & 0.991338
\end{matrix}\right].
```

### NTSC

|  |x  |y  |
|---|---|---|
|R  |0.67  |0.33  |
|G  |0.21  |0.71  |
|B  |0.14  |0.08  |
|W  |0.3101  |0.3161  |

```math
T = \left[
\begin{matrix}
0.606698 & 0.173565 & 0.200135\\
0.298822 & 0.586816 & 0.114363\\
0.000000 & 0.0661201 & 1.11504
\end{matrix}\right].
```

### ITU-R BT.2020

|  |x  |y  |
|---|---|---|
|R  |0.708  |0.292  |
|G  |0.170  |0.797  |
|B  |0.131  |0.046  |
|W  |0.3127  |0.3290  |

```math
T = \left[
\begin{matrix}
0.636958 & 0.144617 & 0.168881 \\
0.2627 & 0.677998 & 0.0593017 \\
0.00000 & 0.0280727 & 1.06099
\end{matrix}\right].
```


## 実装

```cpp
#include<iostream>
#include<Eigen/Core>
#include<Eigen/LU>

using namespace std;
using namespace Eigen;

void clip(VectorXd& input, double min, double max){
	
	for(int i = 0;i < input.size();i++){
		input(i) = ( (input(i) < min) ? (min) : ( (input(i) > max) ? (max) : (input(i)) ) );
	}
	
}

int main(){
	
	//initialize
	VectorXd Evec_xy_white = VectorXd::Zero(2);
	MatrixXd Emat_xy_rgb = MatrixXd::Zero(3,3);
	
	VectorXd Evec_A = VectorXd::Zero(3);
	MatrixXd Emat_A = MatrixXd::Zero(3,3);
	VectorXd Evec_xy_tmp = VectorXd::Zero(3);
	
	VectorXd Evec_RGB = VectorXd::Zero(3);
	VectorXd Evec_XYZ = VectorXd::Zero(3);
	VectorXd Evec_xyY = VectorXd::Zero(3);
	
	MatrixXd Emat_RGB2XYZ = MatrixXd::Zero(3,3);
	
	//input
	Evec_RGB(0) = 0.0;
	Evec_RGB(1) = 0.0;
	Evec_RGB(2) = 1.0;
	
	clip(Evec_RGB, 0.0, 1.0);
	
	//colorimetry = sRGB
	Emat_xy_rgb(0,0) = 0.64;	//x_red
	Emat_xy_rgb(1,0) = 0.33;	//y_red
	Emat_xy_rgb(2,0) = 1.0 - Emat_xy_rgb(0,0) - Emat_xy_rgb(1,0);	//z_red
	
	Emat_xy_rgb(0,1) = 0.3;	//x_green
	Emat_xy_rgb(1,1) = 0.6;	//y_green
	Emat_xy_rgb(2,1) = 1.0 - Emat_xy_rgb(0,1) - Emat_xy_rgb(1,1);	//z_green
	
	Emat_xy_rgb(0,2) = 0.15;	//x_blue
	Emat_xy_rgb(1,2) = 0.06;	//y_blue
	Emat_xy_rgb(2,2) = 1.0 - Emat_xy_rgb(0,2) - Emat_xy_rgb(1,2);	//z_blue
	
	Evec_xy_white(0) = 0.3127;
	Evec_xy_white(1) = 0.3290;
	
	//tmp valiable
	Evec_xy_tmp(0) = Evec_xy_white(0) / Evec_xy_white(1);
	Evec_xy_tmp(1) = 1.0;
	Evec_xy_tmp(2) = (1.0 - Evec_xy_white(0) - Evec_xy_white(1)) / Evec_xy_white(1);
	
	//A
	Evec_A = Emat_xy_rgb.inverse() * Evec_xy_tmp;
	for(int i = 0;i < 3;i++){
		for(int j = 0;j < 3;j++){
			if( i == j ){
				Emat_A(i,j) = Evec_A(i);
			}
			else{
				Emat_A(i,j) = 0.0;
			}
		}
	}
	
	//XYZ
	Emat_RGB2XYZ = Emat_xy_rgb * Emat_A;
	Evec_XYZ = Emat_RGB2XYZ * Evec_RGB;
	
	//xyY
	Evec_xyY(0) = Evec_XYZ(0) / ( Evec_XYZ(0) + Evec_XYZ(1) + Evec_XYZ(2) );
	Evec_xyY(1) = Evec_XYZ(1) / ( Evec_XYZ(0) + Evec_XYZ(1) + Evec_XYZ(2) );
	Evec_xyY(2) = Evec_XYZ(1);
		
	return 0;
	
}
```

## 参考文献

[デジタル色彩工学](https://www.kyoritsu-pub.co.jp/bookdetail/9784320123298)
ディスプレイに表示することを前提に、色の基礎から色空間、色の補正技術など詳しく記載されている。

[ITU-R BT.2020](https://www.itu.int/rec/R-REC-BT.2020/en)
BT2020の規格書。

## 補足

- 実際のディスプレイはガンマ特性があるため、入力のRGBを2.2乗したものをxyYに変換したものが、ディスプレイ出力に近くなる。
- 色空間によってガンマ特性が異なるため、注意が必要。