YUYV(YUY2)徹底解説:4:2:2パックドY'CbCrフォーマットのデータレイアウトとRGB変換
概要 — YUYVとは何か
YUYV(読み:ワイ・ユー・ワイ・ブイ、別名 YUY2 や YUV 4:2:2 packed)は、主にビデオキャプチャやストリーミングで使われるピクセルフォーマットの一つです。ピクセルごとに輝度(Y)と色差(U,V:Cb,Cr)を持ちますが、水平方向に隣接する2画素で色差成分を共有する「4:2:2(横方向2:縦方向1のサンプリング)」というサブサンプリング方式を採っています。
データレイアウト(パッキング方式)
YUYV は「パックド(packed)」形式で、メモリ上はバイト列で表現されます。通常の並びは以下の通りです(左から右へ、2画素単位で繰り返し):
- byte0 = Y0
- byte1 = U0 (Cb)
- byte2 = Y1
- byte3 = V0 (Cr)
つまり、2つの隣接画素 Y0 と Y1 が 1 組の U,V を共有します。ピクセルあたりのビット数は 16bit(2 バイト/画素)になり、幅 W、高さ H の画像データサイズは原則として W * H * 2 バイトです(幅が奇数の場合は通常パディングが行われます)。
用語の注意:YUV と Y'CbCr
実務では「YUV」と表記されることが多いですが、正確にはテレビ・ビデオで用いられる輝度は Y'(ガンマ補正がかかった輝度)であり、色差は Cb/Cr の形式を取るため「Y'CbCr」と表すのが適切です。YUYV フォーマットは一般的に Y'CbCr(規格例:ITU-R BT.601 や BT.709)のサンプリングとして扱われます。
規格(色空間/レンジ)
- 色空間:SD(標準画質)では ITU-R BT.601、HD 以降は BT.709 が多く使われます。どの色変換係数を使うかで RGB 変換結果が変わります。
- 信号レンジ:放送系では限定レンジ(Y 16–235、Cb/Cr 16–240)が標準的ですが、コンピュータ処理や一部の機器ではフルレンジ(0–255)を用いることがあります。YUYV を扱う際は入力がどちらのレンジかを確認する必要があります。
YUYV と類似フォーマットとの違い
- YUYV / YUY2:Y0 U0 Y1 V0 の順序。多くの Linux の V4L2、Windows の一部 API で見かけます。
- UYVY:U0 Y0 V0 Y1 の順序で、バイトオーダが異なります。ソフトウェアやハードウェアの期待する順序を確認しないと色が崩れます。
- I420 / YV12(プラナ形式):Y, U, V が別々の平面に格納される 4:2:0 フォーマット。メモリ配置やアクセスパターンが異なるため変換コストが発生します。
- NV12:Y 平面+UV がインタリーブされた半分解像度の平面(4:2:0)。GPU と親和性が高い。
- RGB24 / RGBA:各画素に直接 RGB 値を持つ。表示や画像処理ライブラリへ渡す時に Y'CbCr→RGB 変換が必要。
メモリサイズとストライドの計算
YUYV は 16bit/ピクセルなので理論上の必要バイト数は W × H × 2 です。ただし多くのデバイスやフレームバッファは行(stride)を 4 バイトや 16 バイト境界にアラインするため、実際のバッファサイズは stride × H になります。幅が奇数の場合は 1 ピクセル分のパディングが入ることがある点にも注意してください。
Y'CbCr → RGB の変換(代表的な式)
変換には色標準(BT.601/BT.709)およびレンジ(限定/フル)を考慮する必要があります。ここでは代表例を示します。
フルレンジ(0–255)の一般式(BT.601 の係数を使う場合、近似値):
- R = Y + 1.402 × (Cr − 128)
- G = Y − 0.344136 × (Cb − 128) − 0.714136 × (Cr − 128)
- B = Y + 1.772 × (Cb − 128)
限定レンジ(テレビ放送、Y:16–235, C:16–240)を扱う場合は Y を適切にスケーリングします(例:Y' = 1.164 × (Y − 16) など)。BT.601 の係数を使った限定レンジ式の代表例:
- R = 1.164*(Y − 16) + 1.596*(Cr − 128)
- G = 1.164*(Y − 16) − 0.391*(Cb − 128) − 0.813*(Cr − 128)
- B = 1.164*(Y − 16) + 2.018*(Cb − 128)
G の係数は実装により 0.392/0.391/0.403 等の丸め差がありますが、上記は一般的な近似です。変換後は 0–255 にクリップします。
サンプルの擬似コード(YUYV → RGB24)
簡易的な処理の流れ(概念説明):
- 入力バッファを 4 バイトずつ読み、Y0,U,Y1,V を取り出す。
- 上記の式で Y0→RGB, Y1→RGB をそれぞれ計算し、出力バッファに格納する。
擬似コード(概念):
- for each row:
- for x from 0 to width step 2:
- Y0 = buf[i++]; U = buf[i++]; Y1 = buf[i++]; V = buf[i++];
- RGB0 = YUV_to_RGB(Y0, U, V); write RGB0;
- RGB1 = YUV_to_RGB(Y1, U, V); write RGB1;
- for x from 0 to width step 2:
実際には整数演算で係数をスケール(係数×1024 等)してシフトで近似する、SSE/NEON 命令で並列処理する、ルックアップテーブルを使うなどの最適化が行われます。
実装上の注意点・最適化
- ハードウェアやドライバが出力する YUYV が限定レンジかフルレンジかを確認する。レンジの不一致は色が暗くなったり白飛びする原因になります。
- バイトオーダ:YUYV と UYVY の違いを見落とすと色が大きく崩れる。FourCC(例:'YUYV'、'YUY2'、'UYVY')で確認する。
- ストライド(行バイト数)により、一行ごとの余白がある場合は適切にスキップする。
- 性能:ソフトウェアでの YUV→RGB 変換はコストが高い。リアルタイム処理では SIMD(SSE/AVX/NEON)、GPU シェーダ、またはハードウェアデコーダ/スケーラを利用することが多い。
- サブサンプリングの影響:4:2:2 は 4:4:4 より水平方向の色分解能が半分。高精細な色エッジでは色収差やモアレが出ることがある。
ユースケース(どこで使われるか)
- USB/web カメラやキャプチャデバイスの生データ(多くのデバイスが YUYV をサポート)。
- 放送用またはプロ向けの映像ワークフローでは 4:2:2 が好まれる(色表現の精度と帯域のバランス)。
- ビデオ会議やストリーミングの取得段階で効率良く取り扱える中間フォーマットとして。
- 組み込み機器やリアルタイム処理が重要なアプリケーションでは、ハードウェアが直接 YUYV を扱い GPU に転送してシェーダで変換することがある。
制限事項と注意点
- 色の精度:4:2:2 のため色差は水平方向に低周波成分のみを保持。細かい色の変化は失われる。
- 互換性:ソフトウェアやライブラリによって YUYV を YUY2 と表現する場合があるため、API ドキュメントを確認すること。
- HDR・色深度:YUYV は通常 8bit チャネルで、HDR や高ビット深度(10/12bit)には対応しないため、より高精度が必要なワークフローでは別フォーマットが必要。
まとめ
YUYV(YUY2)は、2画素で1組の色差を共有する 4:2:22 のパックド Y'CbCr フォーマットで、ビデオキャプチャや放送系で広く使われています。扱う際はデータレイアウト(Y0 U Y1 V)・色空間(BT.601/709)・レンジ(限定/フル)といったメタ情報を正しく認識することが重要です。リアルタイム処理では変換コストやストライドを踏まえた最適化(SIMD、GPU など)を検討してください。
参考文献
- V4L2 Pixel Formats(Linux kernel documentation)
- Wikipedia: YUV
- Wikipedia: FourCC
- ITU-R BT.601: Studio encoding parameters of digital television for standard 4:3 and 16:9 aspect ratios
- ITU-R BT.709: Parameter values for the HDTV standard
- FFmpeg pixel formats(pixfmt definitions)
- YCbCr color models and conversions(解説記事)


