3
0

More than 1 year has passed since last update.

RGBをxyYに変換

Last updated at Posted at 2020-08-09

概要

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に変換したものが、ディスプレイ出力に近くなる。
  • 色空間によってガンマ特性が異なるため、注意が必要。
3
0
0

Register as a new user and use Qiita more conveniently

  1. You get articles that match your needs
  2. You can efficiently read back useful information
  3. You can use dark theme
What you can do with signing up
3
0