YUV420徹底解説:4:2:0の仕組み・レンジ・メモリレイアウト(I420/NV12/NV21)とRGB変換の実務ガイド

YUV420とは(要約)

YUV420(一般には「YUV 4:2:0」や「YUV420p」と表記されることが多い)は、動画や映像処理で広く使われるピクセル表現/サブサンプリング方式の一種です。輝度(Y)と色差(U/Cb、V/Cr)を分けて扱い、色差成分の解像度を水平方向・垂直方向ともに半分にすることで、データ量を抑えながら人間の視覚特性に合わせた効率的な圧縮・転送を可能にします。ここでは仕組み・バリエーション・メモリレイアウト・RGB変換などを詳しく解説します。

まず用語整理:YUV と Y'CbCr の違い

  • Y(輝度):画面の明るさ(luma)を表します。通常はガンマ補正(R'、G'、B')された値に基づくため厳密には Y'(Yプライム)と表記されることが多いです。
  • U/V(または Cb/Cr):色差信号(chroma)。U/Cb は青成分の差、V/Cr は赤成分の差を表します。
  • YUV vs Y'CbCr:アナログ的な「YUV」とデジタル映像で使う規格化された「Y'CbCr」はしばしば混同されます。デジタル処理で扱うのは実質的に Y'CbCr(ガンマ補正済みの luma と標準化された chroma)です。

「4:2:0」の意味 ― クロマサブサンプリングの説明

クロマサンプリングの表記 4:4:4、4:2:2、4:2:0 は水平方向・垂直方向のサンプリング比を示します。4:2:0 の解釈(一般的な理解)は次のとおりです。

  • 先頭の「4」は、基準とする水平方向のサンプル幅を表す(参照単位)。
  • 真ん中と最後の数は、同じ参照領域内での輝度(Y)と色差(Cb/Cr)のサンプリング比を示します。4:2:0 では水平方向に色差が半分、垂直方向にも半分しか取られない(つまり色差は横に2分の1、縦に2分の1、面積で1/4)ことを意味します。
  • 結果として、幅 W × 高さ H の画像に対して、Y は W×H サンプルを持ち、U と V はそれぞれ (W/2)×(H/2) サンプルになります。

典型的なメモリサイズとレイアウト

8ビットサンプルを仮定すると、YUV420 フォーマットの総バイト数は 1.5 × W × H になります(Y が W×H、U が W×H/4、V が W×H/4)。ただし実際の「YUV420」と呼ばれるものには複数のメモリレイアウト(サブフォーマット)が存在します。

  • I420(YUV420p, YU12):平面(planar)形式。メモリ順は Y plane、U plane、V plane(各 plane は連続)。多くのライブラリで I420 として扱われます。
  • YV12:I420 と似ているが U と V の順序が逆(Y、V、U)。古い Windows 系 API 等で見かけます。
  • NV12:セミプランar(semi-planar)形式。Y plane の後に UV が交互に並ぶ(UV UV UV ...、つまり U と V がインターリーブ)。多くのハードウェアデコーダや DirectX / VAAPI で標準的に使われます。
  • NV21:NV12 と同様だがインターリーブ順が VU(V then U)になります。Android カメラデータなどで見かけます。
  • P010 / P016 等(高ビット深度):10/16 ビット深度向けに、NV12 に類似した平面・半平面形式で格納する仕様。ビット深度分のワード(16 ビット単位)で格納されることが多いです。

サンプル配置(Chroma siting)についての注意

4:2:0 では色差の位置(どの輝度サンプルに対してその色差が意味を持つか)が実装によって異なる場合があります。代表的な「chroma siting」の違いは次の通りです。

  • 中心(centered):4つの隣接 Y サンプルの中心に Cb/Cr を配置する方式(多くのビデオコーデックで採用)。
  • コサイテッド(cosited):ある方向に寄せた位置に配置する方式。JPEG(YCbCr 4:2:0)とテレビ放送での扱いが異なる例がある。
  • この違いを無視して単純にアップサンプリングすると、色のずれや縁のにじみ(色ずれアーティファクト)が出ることがあります。コーデックやハードウェアが期待する chroma siting を把握することが重要です。

RGB ⇄ Y'CbCr の変換(一般式と注意点)

デジタル映像での Y は通常ガンマ補正(R'、G'、B')後の値を使うため Y' と表記されます。一般的な正規化された式は次のようになります(0..1 の正規化された R',G',B' を前提)。

  • Y' = Kr * R' + (1 - Kr - Kb) * G' + Kb * B'
  • Cb = 0.5 * (B' - Y') / (1 - Kb)
  • Cr = 0.5 * (R' - Y') / (1 - Kr)

ここで Kr と Kb は規格(例えば ITU-R BT.601、BT.709、BT.2020)によって異なります。代表値:

  • BT.601 (SD): Kr ≈ 0.299, Kb ≈ 0.114
  • BT.709 (HD): Kr ≈ 0.2126, Kb ≈ 0.0722
  • BT.2020 (UHD): Kr ≈ 0.2627, Kb ≈ 0.0593

8ビットの有限レンジ(テレビ・放送で一般的な限定レンジ)へ変換する際はスケーリングとオフセットを使います。典型的には次のようになります(概念式):

  • Y_8 = round(16 + 219 * Y') → Y の値はおおむね 16..235 の範囲
  • Cb_8 = round(128 + 224 * Cb) → Cb/Cr はおおむね 16..240 の範囲

フルレンジ(PC 監視用途など)では Y は 0..255、Cb/Cr は 0..255 の範囲で扱います。どのレンジ・係数を使うかはソース(カメラ、コーデック設定、デコーダ)に依存するため、ミスマッチに注意する必要があります。

実務上の注意点・落とし穴

  • 偶数幅・高さの要求:多くの YUV420 実装は幅・高さが偶数であることを要求します。奇数の解像度ではパディングやクロッピングが必要になります。
  • ストライドとパディング:行ごとのバイト幅(stride)はピクセル幅と一致しないことが多い。画像をコピー・表示する際は stride を考慮してください。
  • 色レンジの不一致:ソースがフルレンジか限定レンジかを誤認すると、コントラストや色が不自然になります(暗くなる、白飛び/黒つぶれが強く出る等)。
  • チャネル順序の違い:I420 / YV12 / NV12 / NV21 の違いを間違えると、色がひっくり返ったり、色帯域がめちゃくちゃになります。
  • アップサンプリングの方式:最近のデコード・スケーリングでは線形補間、双立方補間、クロマ適応補間などが使われる。単純な最近傍を使うと細線や縁で色ズレが目立ちます。

用途と互換性

  • ほとんどのビデオコーデック(H.264/AVC、H.265/HEVC、VP8/VP9 など)は Y'CbCr 4:2:0 をデフォルトで扱います。
  • ハードウェアエンコーダ/デコーダ(GPU、専用チップ)は NV12 を好むことが多い(効率よく DMA・色変換ができるため)。
  • カメラ出力やライブ配信、WebRTC、ビデオ編集など実務で最も一般的に使われるのが YUV420 系です。

実例:メモリサイズの計算(8bit)

幅 W、高さ H のフレーム(W,H が偶数)で:

  • Y plane = W × H バイト
  • U plane = W/2 × H/2 = W×H/4 バイト
  • V plane = W×H/4 バイト
  • 合計 = W×H × (1 + 1/4 + 1/4) = 1.5 × W × H バイト

まとめ

YUV420(Y'CbCr 4:2:0)は、輝度と色差を分離し、色差を 1/4 にサンプリングすることでデータ量を節約する実用的なフォーマットです。複数のメモリレイアウト(I420、YV12、NV12、NV21 等)や色空間(BT.601/709/2020)、レンジ(フル/限定)、チャネルサイトの違いが存在し、これらを正しく理解して処理しないと色や画質に問題が生じます。映像処理やコーデック実装の際は、どの仕様(係数・レンジ・サンプリング配置)に合わせるべきかを明確にし、ストライドやパディング、偶数解像度といった実装上の要点に注意してください。

参考文献