YUV(即YCbCr) 格式
解释常用的YUV422, YUV420, YUV411,YUV444(即YCbCr422, YCbCr420, YCbCr411,YCbCr444)所代表的含义:
三个数字分别表示两个比率:水平,竖直的比例下降。
例如444表示水平竖直全一样,不降低采样。—— 开放、互助) r8 c/ f, H3 T/ /& P r& z
422表示水平降低2:1,竖直不降低(因为2-2=0)
420表示水平降低2:1,竖直也降低2:1(因为2-0=2)
YUV 采样
YUV 的优点之一是,色度频道的采样率可比 Y 频道低,同时不会明显降低视觉质量。有一种表示法可用来描述 U 和 V 与 Y 的采样频率比例,这个表示法称为 A:B:C 表示法: EEPhone-EE手机研发论坛9 u; }$ Q; /: _: K1 M! N) F
图 1 显示了 4:4:4 图片中使用的采样网格。灯光样例用叉来表示,色度样例则用圈表示。 —— 开放、互助2 Q) S5 I" o8 [. |/ J: {- H4 s; m
www.eephone.com# q6 y% /( q# N
图 1. YUV 4:4:4 样例位置
4:2:2 采样的这种主要形式在 ITU-R Recommendation BT.601 中进行了定义。
图 2 显示了此标准定义的采样网格。EEPhone-EE手机研发论坛" M: f0 _9 a7 Z% ?2 U
图 2. YUV 4:2:2 样例位置
4:2:0 采样有两种常见的变化形式。其中一种形式用于 MPEG-2 视频,另一种形式用于 MPEG-1 以及 ITU-T recommendations H.261 和 H.263。图 3 显示了 MPEG-1 方案中使用的采样网格,图 4 显示了 MPEG-2 方案中使用的采样网格。 www.eephone.com% V. Y# m. N( S
图 3. YUV 4:2:0 样例位置(MPEG-1 方案)EEPhone-EE手机研发论坛! ?% j6 /& k* S2 F/ ]) |
图 4. YUV 4:2:0 样例位置(MPEG-2 方案)
与 MPEG-1 方案相比,在 MPEG-2 方案与为 4:2:2 和 4:4:4 格式定义的采样网格之间进行转换更简单一些。因此,在 Windows 中首选 MPEG-2 方案,应该考虑将其作为 4:2:0 格式的默认转换方案。
三个数字分别表示两个比率:水平,竖直的比例下降。
例如444表示水平竖直全一样,不降低采样。—— 开放、互助) r8 c/ f, H3 T/ /& P r& z
422表示水平降低2:1,竖直不降低(因为2-2=0)
420表示水平降低2:1,竖直也降低2:1(因为2-0=2)
YUV 采样
YUV 的优点之一是,色度频道的采样率可比 Y 频道低,同时不会明显降低视觉质量。有一种表示法可用来描述 U 和 V 与 Y 的采样频率比例,这个表示法称为 A:B:C 表示法: EEPhone-EE手机研发论坛9 u; }$ Q; /: _: K1 M! N) F
- 4:4:4 表示色度频道没有下采样。
- 4:2:2 表示 2:1 的水平下采样,没有垂直下采样。对于每两个 U 样例或 V 样例,每个扫描行都包含四个 Y 样例。
- 4:2:0 表示 2:1 的水平下采样,2:1 的垂直下采样。
- 4:1:1 表示 4:1 的水平下采样,没有垂直下采样。对于每个 U 样例或 V 样例,每个扫描行都包含四个 Y 样例。与其他格式相比,4:1:1 采样不太常用,本文不对其进行详细讨论。
图 1 显示了 4:4:4 图片中使用的采样网格。灯光样例用叉来表示,色度样例则用圈表示。 —— 开放、互助2 Q) S5 I" o8 [. |/ J: {- H4 s; m

图 1. YUV 4:4:4 样例位置
4:2:2 采样的这种主要形式在 ITU-R Recommendation BT.601 中进行了定义。
图 2 显示了此标准定义的采样网格。EEPhone-EE手机研发论坛" M: f0 _9 a7 Z% ?2 U

图 2. YUV 4:2:2 样例位置
4:2:0 采样有两种常见的变化形式。其中一种形式用于 MPEG-2 视频,另一种形式用于 MPEG-1 以及 ITU-T recommendations H.261 和 H.263。图 3 显示了 MPEG-1 方案中使用的采样网格,图 4 显示了 MPEG-2 方案中使用的采样网格。 www.eephone.com% V. Y# m. N( S

图 3. YUV 4:2:0 样例位置(MPEG-1 方案)EEPhone-EE手机研发论坛! ?% j6 /& k* S2 F/ ]) |

图 4. YUV 4:2:0 样例位置(MPEG-2 方案)
与 MPEG-1 方案相比,在 MPEG-2 方案与为 4:2:2 和 4:4:4 格式定义的采样网格之间进行转换更简单一些。因此,在 Windows 中首选 MPEG-2 方案,应该考虑将其作为 4:2:0 格式的默认转换方案。
方式一:
為了節省運算時間, 想改用整數來取代浮點數的話, 可以參考一下:
void RGBToYCbCr(unsigned char R, unsigned char G, unsigned char B,
unsigned char *YCc, unsigned char *YCb, unsigned char *YCr)
{
int Value;
Value = (77 * R + 150 * G + 29 * B + 128) >> 8;
if (Value > 255)
Value = 255;
*YCc = (unsigned char)Value;
Value = ((144 * (B - *YCc) + 128) >> 8) + 128;
if (Value < 0)
Value = 0;
else if (Value > 255)
Value = 255;
*YCb = (unsigned char)Value;
Value = ((183 * (R - *YCc) + 128) >> 8) + 128;
if (Value < 0)
Value = 0;
else if (Value > 255)
Value = 255;
*YCr = (unsigned char)Value;
}
void RGBToYCbCr(unsigned char R, unsigned char G, unsigned char B,
unsigned char *YCc, unsigned char *YCb, unsigned char *YCr)
{
int Value;
Value = (77 * R + 150 * G + 29 * B + 128) >> 8;
if (Value > 255)
Value = 255;
*YCc = (unsigned char)Value;
Value = ((144 * (B - *YCc) + 128) >> 8) + 128;
if (Value < 0)
Value = 0;
else if (Value > 255)
Value = 255;
*YCb = (unsigned char)Value;
Value = ((183 * (R - *YCc) + 128) >> 8) + 128;
if (Value < 0)
Value = 0;
else if (Value > 255)
Value = 255;
*YCr = (unsigned char)Value;
}
方式二:
其實依照 YCC 排列的位置不同, 會有420, 422, 444 等稱呼,
所以題目應該是 "如何轉換 YCC 與 RGB" 才是.
以下為二者相轉換的公式, 有興趣的可以參考一下.
(註: 因為浮點數運算後會轉為整數, 所以多多少少會有些誤差.)
/*-------------------------------------------------------------------------*/
void RGBToYCbCr(unsigned char R, unsigned char G, unsigned char B,
unsigned char *YCc, unsigned char *YCb, unsigned char *YCr)
{
*YCc = (unsigned char)( 0.2990 * R + 0.5870 * G + 0.1140 * B);
*YCb = (unsigned char)(-0.1686 * R - 0.3311 * G + 0.4997 * B) + 128;
*YCr = (unsigned char)( 0.4998 * R - 0.4185 * G - 0.0813 * B) + 128;
}
/*-------------------------------------------------------------------------*/
void YCbCrToRGB(unsigned char YCc, unsigned char YCb, unsigned char YCr,
unsigned char *R, unsigned char *G, unsigned char *B)
{
*R = (unsigned char)( 1.4026 * YCr + YCc + 0.0001 * YCb);
*G = (unsigned char)(-0.7144 * YCr + YCc - 0.3444 * YCb);
*B = (unsigned char)(-0.0001 * YCr + YCc + 1.7730 * YCb);
}
所以題目應該是 "如何轉換 YCC 與 RGB" 才是.
以下為二者相轉換的公式, 有興趣的可以參考一下.
(註: 因為浮點數運算後會轉為整數, 所以多多少少會有些誤差.)
/*-------------------------------------------------------------------------*/
void RGBToYCbCr(unsigned char R, unsigned char G, unsigned char B,
unsigned char *YCc, unsigned char *YCb, unsigned char *YCr)
{
*YCc = (unsigned char)( 0.2990 * R + 0.5870 * G + 0.1140 * B);
*YCb = (unsigned char)(-0.1686 * R - 0.3311 * G + 0.4997 * B) + 128;
*YCr = (unsigned char)( 0.4998 * R - 0.4185 * G - 0.0813 * B) + 128;
}
/*-------------------------------------------------------------------------*/
void YCbCrToRGB(unsigned char YCc, unsigned char YCb, unsigned char YCr,
unsigned char *R, unsigned char *G, unsigned char *B)
{
*R = (unsigned char)( 1.4026 * YCr + YCc + 0.0001 * YCb);
*G = (unsigned char)(-0.7144 * YCr + YCc - 0.3444 * YCb);
*B = (unsigned char)(-0.0001 * YCr + YCc + 1.7730 * YCb);
}