现在的位置: 首页 > 综合 > 正文

YUV_and_RGB

2013年12月13日 ⁄ 综合 ⁄ 共 3023字 ⁄ 字号 评论关闭

 

作者:王劲男,华清远见嵌入式培训中心讲师。

计算机彩色显示器显示色彩的原理与彩色电视机一样,都是采用 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之间的转换关系

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

RGB 图像为例

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

在C语言中可以组合使用屏蔽字和移位操作来得到 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);

RGB555 是另一种16位的RGB格式,RGB分量都用5位表示(留下1位不使用)。使用一个字读出一个像素后,这个字的各位意思如下:

        高字节                        低字节
        XRRRRRGG                GGGBBBBB (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通道的)注意在内存中RGB各分量的排列顺序为:BGRA,,,BGRA,,RGBQUAD数据结构来操作一个像素,

typedef struct tagRGBQUAD {
                BYTE rgbBlue; // 蓝色分量
                BYTE rgbGreen; // 绿色分量
                BYTE rgbRed; // 红色分量
                BYTE rgbReserved; // 保留字节(用作 Alpha 通道或忽略)
        } RGBQUAD;

上面介绍的是常见的RGB格式图像的分类。

下面介绍YUV图像

YUV格式的图像数据也是比较常见的。它主要有打包格式和平面格式,前者将YUV分量存在同一个数组中,通常是几个相邻的像素组成一个宏像素;后者是将YUV分量分别存储在三个数组中,其中YUY2,YUYV,YVYU,UYVY,AYUV,Y41P,Y411,Y211都是打包格式,IF09,IYUV,YV12,YVU9都是平面格式。

YUY2(YUYV)格式为每个像素保留Y分量,UV分量在水平方向上每两个像素采样一次。

一个宏像素是4个字节,实际上表示两个像素点的信息。(4:2:2的含义是一个宏像素中,4个Y分量,2个U分量,2个V分量)

YUV2(YUYV)格式如下:
        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 ...

YUV411、YUV420 格式多见于 DV 数据中,前者用于 NTSC 制,后者用于 PAL制。YUV411 为每个像素都提取 Y 分量,而 UV 分量在水平方向上每 4 个像素采样一次。YUV420 并非 V 分量采样为 0,而是跟 YUV411 相比,在水平方向上提高一倍色差采样频率,在垂直方向上以 U/V 间隔的方式减小一半色差采样。
嵌入式及3G相关资源及学习请点击:嵌入式开发视频 android开发视频 android培训 3G培训 QT培训 QT开发视频 物联网培训 物联网技术视频 嵌入式学习   

抱歉!评论已关闭.