リンク
・
画像の変換(目次ページ)
YCbCr関連
・
画像フォーマットの「RGB⇔YCbCr変換」
久しぶりに画像ネタを
世の中には RGB だとか、YCbCr だとかという色空間があって、
その相互変換について。
変換式については ITU-T BT.601 や BT.709 という規格書で定義されています。
(色空間については、これ以外にも規格があります。)
正確には、画像フォーマットの YCbCr ではなく、ビデオ信号の YCbCr の話です。
D端子ケーブルとか、Composite(NTSC)ケーブルとかを流れるデータ信号の事です。
その Bt.601には次のように書かれています。
ITU-R BT.609 |
Y = 0.299R + 0.587G + 0.114B |
CB = 0.564(B - Y) |
CR = 0.713(R - Y) |
CB
| = 0.564(B - Y) |
| = 0.564(B - (0.299R + 0.587G + 0.114B)) |
| = -0.169R - 0.331G + 0.500B |
の様に計算すると
RGB→YCbCr行列式が得られる。
| Y |
| =
|
| 0.299 | 0.587 | 0.114 |
| ×
|
| R |
|
CB |
-0.169 | -0.331 | 0.500 |
G |
CR |
0.500 | -0.419 | 0.081 |
B |
実は、この C
B = 0.564(B - Y) の
0.564という数値、
次の計算式により与えられます。
0.564 ≒
| 0.500 |
(1.000 - 0.114) |
| 0.299 | 0.587 | 0.114 |
|
-0.169 | -0.331 | 0.500 |
0.500 | -0.419 | 0.081 |
つまり、0.564 は計算誤差を含んだ値です。
この
Y = 0.299R + 0.587G + 0.114B
という式、0.299 などの係数値がどこから来たのかよく知りませんが、
仮に、0.299 が 0.29900000 のように、小数点第4位以下がゼロだと仮定すると
以下の行列 A と A
-1 の
青文字は理論的に小数点第4位以下がゼロとなる部分です。
A =
|
| 0.299 | 0.587 | 0.114 |
|
-0.169 | -0.331 | 0.500 |
0.500 | -0.419 | 0.081 |
A-1 =
|
| 1.000 | 0.000 | 1.402 |
|
1.000 | -0.344 | -0.714 |
1.000 | 1.772 | 0.000 |
実際には、
BT.601 規格の中に (R,G,B)→(Y,Cb,Cr) の変換係数が
小数点第3位までの値として明記されていますから、
(※逆変換(Y,Cb,Cr)→(R,G,B)は書かれていない。)
A =
|
| 0.299 | 0.587 | 0.114 |
|
-0.169 | -0.331 | 0.500 |
0.500 | -0.419 | 0.081 |
A-1 =
|
| 1.000 | 0.000 | 1.402 |
|
1.000 | -0.344 | -0.714 |
1.000 | 1.772 | 0.000 |
青文字と
緑文字: BT.601 に記述がある(or 自明な)係数値
赤文字: BT.601 に記述が無い係数値
となります。
たとえば A
-1 の 1.402 は次の式から計算できます。
Cr=(0.5/(1-0.299))(R-Y)
赤文字の係数は小数第3位で切ってしまうと、誤差があるかもしれない部分です。
とは言え『記述の係数値が第3位なら、記述が無い数値も第3位』と考えるのが普通でしょう。
実際、A
-1×A の値を計算すると、
| 1.000 | 0.000 | 1.402 |
| ×
|
| 0.299 | 0.587 | 0.114 |
|
1.000 | -0.344 | -0.714 |
-0.169 | -0.331 | 0.500 |
1.000 | 1.772 | 0.000 |
0.500 | -0.419 | 0.081 |
=
|
| 1.000 | -0.00044 | 0.000438 |
|
0.000136 | 1.00003 | -0.00017 |
-0.00047 | 0.000468 | 1.000 |
となるので、これらの係数値を用いても、
行列の積は小数第3位の計算精度が得られる事になります。
(一般に、有効桁数は掛け算によって少なくなりますから、
この係数は、たまたま良い値だった、と言えるでしょう。)
別の規格書
BT.709 には次のような RGB→YCbCr 計算式が載っています。
ITU-R BT.709 |
1250/50/2:1 |
Y = 0.299R + 0.587G + 0.114B |
CB = 0.564(B - Y) |
CR = 0.713(R - Y) |
|
1125/60/2:1 |
Y = 0.2126R + 0.7152G + 0.0722B |
CB = 0.5389(B - Y) |
CR = 0.6350(R - Y) |
上側の計算式は
BT.601と同じ係数です。
下側の計算式はそれとは違います。
係数値が違いますが、桁数も3桁から4桁になっています。
SDサイズは上側の係数
HDサイズは下側の係数
と考えて良いです。
SD(Standard Definition)というのは720x480や720x576サイズ、
HD(High Definision)は1280x720,1920x1080サイズ、
と考えて良いです。
ここでは次のように書くことにしましょう。
(SD)Y = 0.299R + 0.587G + 0.114B
(HD)Y = 0.2126R + 0.7152G + 0.0722B
困った事に、
BT.709 にはこの計算式しか記述がありません。
(HD)A =
|
| 0.2126 | 0.7152 | 0.0722 |
|
? | ? | 0.5000 |
0.5000 | ? | ? |
(HD)A-1 =
|
| 1.0000 | 0.0000 | 1.5748 |
|
1.0000 | ? | ? |
1.0000 | 1.8556 | 0.0000 |
赤文字の
?は行間を読むしかありません。
BT.601と同じ考え方で RGB→(HD)YCbCrの係数値を計算すると、
(HD)A =
|
| 0.2126 | 0.7152 | 0.0722 |
|
-0.1146 | -0.3854 | 0.5000 |
0.5000 | -0.4542 | -0.0458 |
となります。(小数第4位までで四捨五入しています。)
では、逆行列はどう計算すればよいのでしょうか?
そのまま計算すると期待値と違う結果になります。
| 0.2126 | 0.7152 | 0.0722 |
| -1 |
-0.1146 | -0.3854 | 0.5000 |
|
0.5000 | -0.4542 | -0.0458 |
|
=
|
| 1 | -0.000151501 | 1.574765276 |
|
1 | -0.187280216 | -0.468124625 |
1 | 1.855609686 | 0.00010574 |
※Microsoft Excel の "MINVERSE" という機能で計算した逆行列です。
なので、BT.601の時に計算した様に、
0.5389 ≒
| 0.5000 |
(1.0000 - 0.0722) |
0.6350 ≒
| 0.5000 |
(1.0000 - 0.2126) |
という所に立ち戻って逆行列を計算しなければなりません。
Microsoft Excel で逆行列を計算すると次のようになりました。
| 1 | -2.28E-17 | 1.5748 |
|
1 | -0.187324273 | -0.468124273 |
1 | 1.8556 | 0 |
小数第4位まで四捨五入して次の逆行列を得ます。
(HD)A-1 =
|
| 1.0000 | 0.0000 | 1.5748 |
|
1.0000 | -0.1873 | -0.4681 |
1.0000 | 1.8556 | 0.0000 |
念のため、(HD)A
-1×(HD)A の値を計算すると、
| 1.0000 | 0.0000 | 1.5748 |
| ×
|
| 0.2126 | 0.7152 | 0.0722 |
|
1.0000 | -0.1873 | -0.4681 |
-0.1146 | -0.3854 | 0.5000 |
1.0000 | 1.8556 | 0.0000 |
0.5000 | -0.4542 | -0.0458 |
=
|
| 1 | -7.42E-5 | 7.42E-5 |
|
1.46E-5 | 0.99999644 | -1.10E-5 |
-5.18E-5 | 5.18E-5 | 1 |
と小数第4位までの精度が保たれているので、この係数で確定して良さそうです。
さて、ここで1つお知らせがあります。
BT.601や
BT.709には、上記の変換式の他に
次の様な記述があります。
8-bit coding時の Range |
Y
| 16~235
|
CB,CR
| 16~240
|
これは「8bitのフルレンジ(0~255)ではなく上記の値に縮小しなさい」と言っています。
BT.601やBT.709はビデオ信号の規格なので、
ブランキング区間などの関係でフルレンジは使えないのです。
これを加味した計算式は次のようになります。
(SD)Y = (0.299R + 0.587G + 0.114B)×219.0 / 255.0 + 16.0;
(SD)Cb = (-0.169R - 0.331G + 0.500B)×224.0 / 255.0 + 128.0;
(SD)Cr = (0.500R - 0.419G - 0.081B)×224.0 / 255.0 + 128.0;
ただし、Y,Cb,Crが Range に納まるように飽和演算(丸め処理)すること。
Y' = ((SD)Y - 16.0)×255.0 / 219.0;
Cb' = ((SD)Cb - 128.0)×255.0 / 224.0;
Cr' = ((SD)Cr - 128.0)×255.0 / 224.0;
R = 1.000Y' + 1.402Cr';
G = 1.000Y' - 0.344Cb' - 0.714Cr';
B = 1.000Y' + 1.772Cb';
ただし、R,G,Bが 1~255 のRange に納まるように飽和演算すること。
(HD)Y = (0.2126R + 0.7152G + 0.0722B)×219.0 / 255.0 + 16.0;
(HD)Cb = (-0.1146R - 0.3854G + 0.5000B)×224.0 / 255.0 + 128.0;
(HD)Cr = (0.5000R - 0.4542G - 0.0458B)×224.0 / 255.0 + 128.0;
ただし、Y,Cb,Crが Range に納まるように飽和演算すること。
Y' = ((HD)Y - 16.0)×255.0 / 219.0;
Cb' = ((HD)Cb - 128.0)×255.0 / 224.0;
Cr' = ((HD)Cr - 128.0)×255.0 / 224.0;
R = 1.0000Y' + 1.5748Cr';
G = 1.0000Y' - 0.1873Cb' - 0.4681Cr';
B = 1.0000Y' + 1.8556Cb';
ただし、R,G,Bが 1~255 のRange に納まるように飽和演算すること。
さて、世の中には YCbCr の他に YPbPr という色空間の呼び方があります。
この違いは何でしょうか?
とあるウィキペディアに「SDTVがYCbCrでHDTVはYPbPr」と書かれていました。
BT.709にはそんな事は書かれていません。
別の規格でしょうか?
世の中には諸説飛び交っています。
Tektronix の "A Guide to Standard and High-Definition Digital Video Measurements"
という資料によれば、
デジタル信号は YCbCr で、アナログComponent信号が YPbPr のようです。
1125/60/2:1 (SMPTE 240M) |
Y = 0.212R + 0.701G + 0.087B |
|
1920x1080 (SMPTE 274M) 1280x720 (SMPTE 296M) |
Y = 0.2126R + 0.7152G + 0.0722B |
|
525/59.94/2:1 625/50/2:1 1250/50/2:1 |
Y = 0.299R + 0.587G + 0.114B |