toruのブログ

月1くらいで記事書きたい。

YCbCr変換による色数の減少

目的

  • RGB --> YCbCr --> RGB の変換で色数がどれだけ減るかを調べる。

背景

YCbCr変換[1]、および Chroma Subsampling[2] による情報圧縮は大変素晴らしい技術である。視覚的な情報のロスを抑えた上でデータを大幅に削減することが出来るため、我々は様々な場面でその恩恵を受けている。

その一方で、YCbCr変換によって生じる情報欠損への理解を深めることも重要である。 この記事では RGB --> YCbCr --> RGB の変換で具体的にどの程度の情報欠損が生じるかを調査する。

結論

  1. RGB --> YCbCr --> RGB の変換を行うことで色数が減少する。Full Range は約25%、Narrow Range() は約16% まで減る。

  2. RGB --> YCbCr --> RGB の変換で生じる誤差は量子化誤差であり、Code Value値で1変化するだけである。従って色数の減少による画質劣化は人間の目では視認が困難。

  3. 彩度が高い色は色数が減少しやすい傾向にある。

一般的な YCbCr 信号で使われるレンジ[3]。Full Range が 0~1023(10bit) なのに対して、Narrow Range は 64~940(10bit)。

調査手順

定式化

データのbit深度をnとする。この時、RGB空間で表現できる色数N_nは以下の式で計算できる。

 \displaystyle N_n = 2^{3n}

続いて RGB --> YCbCr --> RGB 変換後の色数N_n'について考える。オリジナルのRGB値を (R_i, G_j, B_k)、変換後のRGB値を (R_i^{'}, G_j^{'}, B_k^{'}) とする。 すると N_n'

{\displaystyle
(R_i, G_j, B_k) = (R_i^{'}, G_j^{'}, B_k^{'})
}

が成立する個数の合計値として計算できる。i, j, k はそれぞれ 0, 1, ..., n-2, n-1 の整数を意味する。

本記事では計算で得られた N_n'N_n を使って可逆変換可能なRGB値の比率 \frac{N'_n}{N_n} を求める。

コーディング

例によって Color Science for Python に頑張ってもらう。ソースコードコレcalc_invertible_rate_with_various_combinations()

結果

複数のパラメータで検証した結果を表1に示す。一番右側の invertible rate が\frac{N'_n}{N_n}である。結論で述べた通り、Full Range は約25%、Narrow Range は約16% まで色数が減少する。

表1.各種パラメータでの invertible rate.

gamut bit depth range invertible rate[%]
ITU-R BT.709 8bit Full 24.9
ITU-R BT.709 10bit Full 24.6
ITU-R BT.2020 8bit Full 24.8
ITU-R BT.2020 10bit Full 24.5
ITU-R BT.709 8bit Narrow 16.4
ITU-R BT.709 10bit Narrow 16.1
ITU-R BT.2020 8bit Narrow 16.4
ITU-R BT.2020 10bit Narrow 16.1

考察

誤差の大きさの調査

表1. よりYCbCr変換で色数が減少することは分かった。では Code Value として具体的にどのくらいズレるのか調べてみよう。

まず、変換前の RGB値と変換後のRGB値との誤差 D(i, j, k) を求める。

{\displaystyle
D(i, j, k) = (R_i, G_j, B_k) - (R_i^{'}, G_j^{'}, B_k^{'})
}

次に D(i, j, k)ヒストグラムを作成する。R, G, B単色についてプロットした結果を図1に、R, G, B の差分の絶対値の合計をプロットした結果を図2に示す。なお、今回は BT.709, 8bit, Full Range の組み合わせで検証した。

図1. R, G, B 単色の誤差のヒストグラム 図2. R, G, B の誤差の絶対値の合計のヒストグラム
f:id:takuver4:20190310194711p:plain f:id:takuver4:20190310194719p:plain

この結果より、生じている誤差のほぼ全て()が\pm{1}であり単なる量子化誤差だと分かる。 量子化誤差レベルであることから、YCbCr変換による画質劣化は視認が困難なレベルに収まっていると考える(もちろんシーンによっては画質劣化は視認可能となる)。

Red で4点、Blue で1点だけ誤差が+2となっている点について補足しておく。これは RGB --> YCbCr で +1、 YCbCr --> RGB で +1、合計+2の誤差が生じた結果である。値は少々大きいものの量子化誤差である。

誤差が生じやすい色の調査

最後に、誤差が生じやすい色の調査を行う。図2. でプロットした誤差が3以上であるRGB値を xy色度図上にプロットした。結果を図3に示す。なお今回も BT.709, 8bit, Full Range の組み合わせで検証した。

f:id:takuver4:20190310194737p:plain

図3. R, G, B の各色で誤差が生じていたRGB値

図3より D65付近の彩度が低い領域では殆ど誤差は生じておらず、彩度の高い領域で誤差が生じやすい傾向にあることが分かった。

なぜこのような分布となるのか個人的には更に考察を続けたいが、他にもやりたいことがあるので本記事での考察はここまでとする。

感想

経験的に、R, G, B, M, Y, C の色と YCbCr 変換の相性が悪いことは知っていたが、図3のように全ての組み合わせについて誤差が大きいところをプロットした経験は無かったので大変勉強になった。

私は「彩度が極端に高い色でしか誤差は発生しない」という謎の思い込みをしていたのだが完全な誤解だった。YCbCr変換は単なる行列変換であるため、(傾向はあるものの)単純に量子化誤差が発生しているだけである。従って彩度が低い色でも運悪くR, G, Bの各色で量子化誤差が生じる可能性は十分にある。これが分かったのが今回の一番の収穫だったと考える。

その他

YCbCr変換に関してはあと2本記事を書く予定。今のところの暫定タイトルは以下。

  • YCbCr変換による致命的な画質劣化の可能性について
    • ヒューマンエラーにより BT.601, BT.709, BT.2020 の係数を取り違えた場合の誤差調査
  • YCbCr変換の係数間違えを抑止するテストパターン
    • 自作のテストパターンに YCbCr 変換の係数誤りを「目視」で見破れるパターンを追加したい

参考文献

[1] Wikipedia. "YCbCr". https://en.wikipedia.org/wiki/YCbCr (2019/03/04 参照).

[2] Wikipedia. "Chroma subsampling". https://en.wikipedia.org/wiki/Chroma_subsampling (2019/03/04 参照).

[3] ITU. "ITU-R BT.2100-2". p.9.