toruのブログ

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

YCbCr変換の係数誤り検出テストパターンの作成(一部成功)

目的

  • YCbCrの係数誤り()が発生した場合、その誤りに気づけるテストパターンを作成する。
  • 作成したテストパターンを用いて実際にYCbCrの係数誤りを検出してみる

詳細は前回の記事を参照

結論

YCbCrの係数誤りを判別するテストパターン作成に成功した。作成したテストパターンを図1(オリジナル)に、全てのYCbCrの係数組み合わせで試した例を図2に示す。なお表示スペースの都合で図2はテストパターンの右半分のみを表示している。

このテストパターンには Gray, Red および Cyan のタイル状パターンが描かれている。ビデオレベルの低い方の具体的な値は、Red が (255, 0, 78), (247, 0, 78), (239, 0, 78), ... 、Cyan が (0, 255, 255), (0, 247, 247), (0, 239, 239), ... である。

このテストパターンは YCbCrの係数誤りがあった場合に Red または Cyan の タイル状パターンが高階調側で消える性質を持っている。YCbCrの係数が正しい場合はタイル状パターンが消えずに表示される。

なお、残念ながら本テストパターンには制約事項が存在しており誰もが簡単に利用できるものでは無い。 従って本テストパターンの利用は推奨しない(大変残念だが)。制約事項の詳細は本記事の後半を参照。

f:id:takuver4:20190331163136p:plain

図1. YCbCr係数誤り検出テストパターン。

BT.601 BT.709 BT.2020
BT.601 f:id:takuver4:20190331164121p:plain f:id:takuver4:20190331164138p:plain f:id:takuver4:20190331164148p:plain
BT.709 f:id:takuver4:20190331164206p:plain f:id:takuver4:20190331164218p:plain f:id:takuver4:20190331164230p:plain
BT.2020 f:id:takuver4:20190331164241p:plain f:id:takuver4:20190331164252p:plain f:id:takuver4:20190331164302p:plain
図2. RGB to YCbCr と YCbCr to RGB の係数組み合わせでの表示例。高階調側のみトリミングして表示。

原理

YCbCr係数誤りの発生時に特定階調の信号が最大階調でクリップされる性質を利用している。例として RGB to YCbCr に BT.709 の係数が、YCbCr to RGB に BT.2020 の係数が使われた場合を取り上げる。ソースのRGB値を R, G, B、YCbCr係数誤りにより誤変換された RGB値を R', G', B' と置くと R', G', B' は以下の式で計算できる[1]。

 \displaystyle
\begin{aligned}
  \begin{bmatrix} R' \\ G' \\ B' \end{bmatrix} =
 \begin{bmatrix}
       1.00000 & -0.01697 & 0.09631 \\
      0.00000 & 0.99531 & -0.05119 \\
      0.00000 & 0.01151 & 1.00264
    \end{bmatrix}
    \begin{bmatrix} R \\ G \\ B \end{bmatrix}
\end{aligned}

ここで、(R, G, B) = (247, 0, 78) の場合の R', G', B' を求めてみる。

 \displaystyle
\begin{aligned}
  \begin{bmatrix} R' \\ G' \\ B' \end{bmatrix} =
 \begin{bmatrix}
       1.00000 \times 247 -0.01697 \times 0 + 0.09631 \times 78 \\
      0.00000 \times 247 + 0.99531 \times 0 -0.05119  \times 78 \\
      0.00000 \times 247 + 0.01151 \times 0 + 1.00264 \times 78
 \end{bmatrix} = 
    \begin{bmatrix} 254.5 \\ 0 \\  78.2 \end{bmatrix}
\end{aligned}

四捨五入すると (R', G', B') = (255, 0, 78) となる。この性質を利用して係数誤りが発生した際にタイル状パターンが潰れるようにした。実際に該当するタイル状パターン(図2の最下段の中央)を見てみると、Red のタイル状パターンがクリップにより見えなくなっている。

使用例

「こんな状況は起こらねーよ」と突っ込みが来そうですが、使用例を挙げたいので無理やり YCbCr 係数誤りを発生させます。 逆に言うと、普通にソフトや機材を使っていれば YCbCr の係数誤りが発生する例は非常に少ないと言えます。

使用例1. ffmpeg で色関連のオプションが不足していた

PNGの連番ファイルを以下のコマンドでエンコードした。

$ ffmpeg -framerate 60 -i src_img_%4d.png -c:v h264 -crf 18 -pix_fmt yuv420p ng_colorspace.mp4

作成した mp4 ファイルを再生プレイヤーで確認すると図3のようにYCbCr係数誤りが確認された。 これは ffmpegBT.601 の係数で RGB to YCbCr 変換し、再生ソフトが BT.709 の係数で YCbCr to RGB 変換しているのが原因である。

f:id:takuver4:20190331171527p:plain

図3. 動画再生プレイヤーでYCbCr係数誤りが起きている様子

YCbCrの係数誤りを無くすには以下のようにパラメータを設定してエンコードすれば良い。

$ ffmpeg -framerate 60 -i src_img_%4d.png -c:v h264 -crf 18 \
-colorspace bt709 -color_trc bt709 -color_primaries bt709 \
-vf setparams=field_mode=prog:range=tv:color_primaries=bt709:color_trc=bt709:colorspace=bt709 \
-pix_fmt yuv420p ok_colorspace.mp4

使用例2. Davinci Resolve での設定ミス

Davinci Resolve で BT.709 のコンテンツを作る予定だったのだが、最近は BT..2020のコンテンツばかり作っていたので、うっかり Color Management 設定を Rec.2020 Gamma 2.4 にしてしまった(図4)。 f:id:takuver4:20190331175132p:plain

図4. Davinci Resolve の設定を間違えた例

しかし、素材は全て BT.709色域のものであったし、Windows上で BT.709のモニターを使っていたので特に違和感を覚えることなく最後まで作業して mov で出力した。 その後、色々あり Premiere Pro でその mov ファイルを編集することになった。しかし、Premiere は基本的に YCbCr の変換係数は BT.709 を期待しているのでYCbCr係数誤りが発生した(図5)。

f:id:takuver4:20190331174013p:plain

図5. 係数誤りによって Premiere Pro で正しく表示できなかった例

これを修正するには Davinci Resolve で当該ファイルを開き直し、Color Management 設定を Rec.709 Gamma 2.4 に変更して改めてファイルを出力すれば良い。

(実際はこんなシチュエーションはありえないと思うが)。

テストパターンの制約事項

テストパターンの利用に関して現時点で判明している制約事項を示す。なお、他にも制約事項がある可能性は十分にある。

1. 表示デバイス側の色域設定がBT.2020の場合は使えない

2019年3月現在、量産されている表示デバイスで BT.2020色域を100%表示可能なものは存在しない。本テストパターンは彩度が極めて高いRGB値を使用しているため、表示デバイス側の色域設定が BT.2020 だと、YCbCr係数の正誤に関わらずパターンがクリップされてしまう。確認には手動で表示デバイス側の色域設定を BT.2020 --> BT.709 に変更する必要がある(手動で設定できない場合もある)。

2. PQカーブでは使えない

2019年3月現在、量産されている表示デバイスで PQカーブ(SMPTE ST2084) で定義する 10000nits を表示可能なものは存在しない。よって表示デバイス側の EOTF設定が ST2084 だと、YCbCr係数の正誤に関わらずパターンがクリップされてしまう。確認には手動で表示デバイス側のEOTF設定を ST2084 --> 2.4 に変更する必要がある(手動で設定できない場合もある)。

3. 業務用のビデオモニターでYCbCr表示している場合は使えない

RGB空間で暮らしていると、表示デバイスは 0~1023(10bit)、0~100% のレンジを表示するのが当然だと思うのが普通である。 しかし YCbCr空間には Narrow Range[2] および Super-white[3] という概念があり、ビデオモニターでは 0~100% ではなく 0~109% のレンジが表示される。本テストパターンは 100% でクリップされるように設計してあるため、109% まで表示されるとクリップが発生せず、YCbCr係数誤りが判別できない(なお、手元にそんな高価なモニターは無いので実機確認は出来てない)。

感想

念願の YCbCr係数誤り検出パターンがついに完成した。

今後は SDR/HDR が混在することとなり、YCbCr変換係数は BT.709とBT.2020 の双方が使われることとなる。今のところ身の回りで事故が起こったことはないが、事故の危険性は高くなると予想している。 本パターンを使い、新規に使用する機材やソフトに関しては入念なチェックを行うようにしたい。

参考文献

[1] toruのブログ, "YCbCr変換による画質劣化の可能性について", http://trev16.hatenablog.com/entry/2019/03/23/223834 (2019/03/31 参照)

[2] ITU-R BT.2100-2, "Image parameter values for high dynamic range television for use in production and international programme exchange", https://www.itu.int/rec/R-REC-BT.2100 (2019/03/31 参照)

[3] EBU, "USER REQUIREMENTS FOR VIDEO MONITORS IN TELEVISION PRODUCTION", https://tech.ebu.ch/docs/tech/tech3320.pdf (2019/03/31 参照)