RGB与YUV----摘自《DirectShow实务精选》

小知识: RGB YUV
---- 摘自《 DirectShow 实务精选》 作者:陆其明

计算机彩色显示器显示色彩的原理与彩色电视机一样,都是采用 R Red )、 G Green )、 B Blue )相加混色的原理:通过发射出三种不同强度的电子束,使屏幕内侧覆盖的红、绿、蓝磷光材料发光而产生色彩。这种色彩的表示方法称为 RGB 色彩空间表示(它也是多媒体计算机技术中用得最多的一种色彩空间表示方法)。
根据三基色原理,任意一种色光 F 都可以用不同分量的 R G B 三色相加混合而成。

F = r [ R ] + g [ G ] + b [ B ]

其中, r g b 分别为三基色参与混合的系数。当三基色分量都为 0 (最弱)时混合为黑色光;而当三基色分量都为 k (最强)时混合为白色光。调整 r g b 三个系数的值,可以混合出介于黑色光和白色光之间的各种各样的色光。
那么 YUV 又从何而来呢?在现代彩色电视系统中,通常采用三管彩色摄像机或彩色 CCD 摄像机进行摄像,然后把摄得的彩色图像信号经分色、分别放大校正后得到 RGB ,再经过矩阵变换电路得到亮度信号 Y 和两个色差信号 R Y (即 U )、 B Y (即 V ),最后发送端将亮度和色差三个信号分别进行编码,用同一信道发送出去。这种色彩的表示方法就是所谓的 YUV 色彩空间表示。
采用 YUV 色彩空间的重要性是它的亮度信号 Y 和色度信号 U V 是分离的。如果只有 Y 信号分量而没有 U V 分量,那么这样表示的图像就是黑白灰度图像。彩色电视采用 YUV 空间正是为了用亮度信号 Y 解决彩色电视机与黑白电视机的兼容问题,使黑白电视机也能接收彩色电视信号。
YUV RGB 相互转换的公式如下( RGB 取值范围均为 0-255 ):

Y = 0.299R + 0.587G + 0.114B
U = -0.147R - 0.289G + 0.436B
V = 0.615R - 0.515G - 0.100B

R = Y + 1.14V
G = Y - 0.39U - 0.58V
B = Y + 2.03U

DirectShow 中,常见的 RGB 格式有 RGB1 RGB4 RGB8 RGB565 RGB555 RGB24 RGB32 ARGB32 等;常见的 YUV 格式有 YUY2 YUYV YVYU UYVY AYUV Y41P Y411 Y211 IF09 IYUV YV12 YVU9 YUV411 YUV420 等。 作为视频媒体类型的辅助说明类型( Subtype ),它们对应的 GUID 见表 2.3

2.3 常见的 RGB YUV 格式

GUID    
格式描述
MEDIASUBTYPE_RGB1    2
色,每个像素用 1 位表示,需要调色板
MEDIASUBTYPE_RGB4    16
色,每个像素用 4 位表示,需要调色板
MEDIASUBTYPE_RGB8    256
色,每个像素用 8 位表示,需要调色板
MEDIASUBTYPE_RGB565    
每个像素用 16 位表示, RGB 分量分别使用 5 位、 6 位、 5
MEDIASUBTYPE_RGB555    
每个像素用 16 位表示, RGB 分量都使用 5 位(剩下的 1 位不用)
MEDIASUBTYPE_RGB24    
每个像素用 24 位表示, RGB 分量各使用 8
MEDIASUBTYPE_RGB32    
每个像素用 32 位表示, RGB 分量各使用 8 位(剩下的 8 位不用)
MEDIASUBTYPE_ARGB32    
每个像素用 32 位表示, RGB 分量各使用 8 位(剩下的 8 位用于表示 Alpha 通道值)
MEDIASUBTYPE_YUY2    YUY2
格式,以 4:2:2 方式打包
MEDIASUBTYPE_YUYV    YUYV
格式(实际格式与 YUY2 相同)
MEDIASUBTYPE_YVYU    YVYU
格式,以 4:2:2 方式打包
MEDIASUBTYPE_UYVY    UYVY
格式,以 4:2:2 方式打包
MEDIASUBTYPE_AYUV    
Alpha 通道的 4:4:4 YUV 格式
MEDIASUBTYPE_Y41P    Y41P
格式,以 4:1:1 方式打包
MEDIASUBTYPE_Y411    Y411
格式(实际格式与 Y41P 相同)
MEDIASUBTYPE_Y211    Y211
格式
MEDIASUBTYPE_IF09    IF09
格式
MEDIASUBTYPE_IYUV    IYUV
格式
MEDIASUBTYPE_YV12    YV12
格式
MEDIASUBTYPE_YVU9    YVU9
格式
下面分别介绍各种 RGB 格式。

   ¨ RGB1
RGB4 RGB8 都是调色板类型的 RGB 格式,在描述这些媒体类型的格式细节时,通常会在 BITMAPINFOHEADER 数据结构后面跟着一个调色板(定义一系列颜色)。它们的图像数据并不是真正的颜色值,而是当前像素颜色值在调色板中的索引。以 RGB1 2 色位图)为例,比如它的调色板中定义的两种颜色值依次为 0x000000 (黑色)和 0xFFFFFF (白色),那么图像数据 001101010111 …(每个像素用 1 位表示)表示对应各像素的颜色为:黑黑白白黑白黑白黑白白白…。

  ¨ RGB565
使用 16 位表示一个像素,这 16 位中的 5 位用于 R 6 位用于 G 5 位用于 B 。程序中通常使用一个字( WORD ,一个字等于两个字节)来操作一个像素。当读出一个像素后,这个字的各个位意义如下:
    
高字节                低字节
R R R R R G G G     G G G B B B B B
可以组合使用屏蔽字和移位操作来得到 RGB 各分量的值:

#define RGB565_MASK_RED    0xF800
#define RGB565_MASK_GREEN  0x07E0
#define RGB565_MASK_BLUE   0x001F
R = (wPixel & RGB565_MASK_RED) >> 11;   //
取值范围 0-31
G = (wPixel & RGB565_MASK_GREEN) >> 5;  //
取值范围 0-63
B =  wPixel & RGB565_MASK_BLUE;         //
取值范围 0-31

¨ RGB555
是另一种 16 位的 RGB 格式, RGB 分量都用 5 位表示(剩下的 1 位不用)。使用一个字读出一个像素后,这个字的各个位意义如下:
    
高字节              低字节
X R R R R G G       G G G B B B B B      
X 表示不用,可以忽略)
可以组合使用屏蔽字和移位操作来得到 RGB 各分量的值:

#define RGB555_MASK_RED    0x7C00
#define RGB555_MASK_GREEN  0x03E0
#define RGB555_MASK_BLUE   0x001F
R = (wPixel & RGB555_MASK_RED) >> 10;   //
取值范围 0-31
G = (wPixel & RGB555_MASK_GREEN) >> 5;  //
取值范围 0-31
B =  wPixel & RGB555_MASK_BLUE;         //
取值范围 0-31
¨ RGB24 使用 24 位来表示一个像素, RGB 分量都用 8 位表示,取值范围为 0-255 。注意在内存中 RGB 各分量的排列顺序为: BGR BGR BGR …。通常可以使用 RGBTRIPLE 数据结构来操作一个像素,它的定义为:

typedef struct tagRGBTRIPLE {
  BYTE rgbtBlue;    //
蓝色分量
  BYTE rgbtGreen;   //
绿色分量
  BYTE rgbtRed;     //
红色分量
} RGBTRIPLE;

¨ RGB32
使用 32 位来表示一个像素, RGB 分量各用去 8 位,剩下的 8 位用作 Alpha 通道或者不用。( ARGB32 就是带 Alpha 通道的 RGB32 。)注意在内存中 RGB 各分量的排列顺序为: BGRA BGRA BGRA …。通常可以使用 RGBQUAD 数据结构来操作一个像素,它的定义为:

typedef struct tagRGBQUAD {
  BYTE    rgbBlue;      //
蓝色分量
  BYTE    rgbGreen;     //
绿色分量
  BYTE    rgbRed;       //
红色分量
  BYTE    rgbReserved;  //
保留字节(用作 Alpha 通道或忽略)
} RGBQUAD;
下面介绍各种 YUV 格式。 YUV 格式通常有两大类:打包( packed )格式和平面( planar )格式。前者将 YUV 分量存放在同一个数组中,通常是几个相邻的像素组成一个宏像素( macro-pixel );而后者使用三个数组分开存放 YUV 三个分量,就像是一个三维平面一样。表 2.3 中的 YUY2 Y211 都是打包格式,而 IF09 YVU9 都是平面格式。(注意:在介绍各种具体格式时, YUV 各分量都会带有下标,如 Y0 U0 V0 表示第一个像素的 YUV 分量, Y1 U1 V1 表示第二个像素的 YUV 分量,以此类推。)

¨ YUY2
(和 YUYV )格式为每个像素保留 Y 分量,而 UV 分量在水平方向上每两个像素采样一次。一个宏像素为 4 个字节,实际表示 2 个像素。( 4:2:2 的意思为一个宏像素中有 4 Y 分量、 2 U 分量和 2 V 分量。)图像数据中 YUV 分量排列顺序如下:
Y0 U0 Y1 V0    Y2 U2 Y3 V2 …

¨ YVYU 格式跟 YUY2 类似,只是图像数据中 YUV 分量的排列顺序有所不同:
Y0 V0 Y1 U0    Y2 V2 Y3 U2 …

¨ UYVY 格式跟 YUY2 类似,只是图像数据中 YUV 分量的排列顺序有所不同:
U0 Y0 V0 Y1    U2 Y2 V2 Y3 …

¨ AYUV 格式带有一个 Alpha 通道,并且为每个像素都提取 YUV 分量,图像数据格式如下:
A0 Y0 U0 V0    A1 Y1 U1 V1 …

¨ Y41P
(和 Y411 )格式为每个像素保留 Y 分量,而 UV 分量在水平方向上每 4 个像素采样一次。一个宏像素为 12 个字节,实际表示 8 个像素。图像数据中 YUV 分量排列顺序如下:
U0 Y0 V0 Y1    U4 Y2 V4 Y3    Y4 Y5 Y6 Y8 …

¨ Y211
格式在水平方向上 Y 分量每 2 个像素采样一次,而 UV 分量每 4 个像素采样一次。一个宏像素为 4 个字节,实际表示 4 个像素。图像数据中 YUV 分量排列顺序如下:
Y0 U0 Y2 V0    Y4 U4 Y6 V4 …

¨ YVU9 格式为每个像素都提取 Y 分量,而在 UV 分量的提取时,首先将图像分成若干个 4 x 4 的宏块,然后每个宏块提取一个 U 分量和一个 V 分量。图像数据存储时,首先是整幅图像的 Y 分量数组,然后就跟着 U 分量数组,以及 V 分量数组。 IF09 格式与 YVU9 类似。

¨ IYUV
格式为每个像素都提取 Y 分量,而在 UV 分量的提取时,首先将图像分成若干个 2 x 2 的宏块,然后每个宏块提取一个 U 分量和一个 V 分量。 YV12 格式与 IYUV 类似。

¨ YUV411
YUV420 格式多见于 DV 数据中,前者用于 NTSC 制,后者用于 PAL 制。 YUV411 为每个像素都提取 Y 分量,而 UV 分量在水平方向上每 4 个像素采样一次。 YUV420 并非 V 分量采样为 0 ,而是跟 YUV411 相比,在水平方向上提高一倍色差采样频率,在垂直方向上以 U/V 间隔的方式减小一半色差采样,如图 2.12 所示。
  • 0
    点赞
  • 1
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值