概要
RGBで表される色をxyYに変換する。
まず、各変数等を定義する。つぎにRGBからXYZへの変換行列を導出し、xyYへ変換する。最後に代表的な色空間での変換行列を記載する。
前提条件
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への変換を
\boldsymbol{C}_{\rm xyY} = f_{\rm xyY}(\boldsymbol{C}_{\rm RGB})
とする。
色域は、xy平面上のつぎの座標を頂点とする三角形で表される。
\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}
また、白色点はつぎのとおりである。
\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への変換を
\boldsymbol{C}_{\rm XYZ} = f_{\rm XYZ}(\boldsymbol{C}_{\rm RGB})
とする。
\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での色はつぎのとおりとなる。
\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の関係から、
\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}$はつぎのとおりとなる。
\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}.
さらに整理して、
\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つに減る。これらを求めれば良い。
白色点から、つぎの関係が得られる。
\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}$はつぎのとおり求められる。
\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となる前提を置くと、
\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}$について解くとつぎのとおりとなる。
\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への変換は、
\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,
および
\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,
$$
で得られる。
変換行列まとめ
主な色空間の色域・白色点と変換行列をまとめる。変換行列はつぎのとおり。
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 |
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 |
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 |
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 |
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].
実装
#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;
}
参考文献
デジタル色彩工学
ディスプレイに表示することを前提に、色の基礎から色空間、色の補正技術など詳しく記載されている。
ITU-R BT.2020
BT2020の規格書。
補足
- 実際のディスプレイはガンマ特性があるため、入力のRGBを2.2乗したものをxyYに変換したものが、ディスプレイ出力に近くなる。
- 色空間によってガンマ特性が異なるため、注意が必要。