YUV / RGB 格式及快速转换算法

前言

自然界的颜色千变万化,为了给颜色一个量化的衡量标准,就需要建立色彩空间模型来描述各种各样的颜色,由于人对色彩的感知是一个复杂的生理和心理联合作用的过程,所以在不同的应用领域中为了更好更准确的满足各自的需求,就出现了各种各样的色彩空间模型来量化的描述颜色。我们比较常接触到的就包括 RGB / CMYK / YIQ / YUV / HSI等等。

        对于数字电子多媒体领域来说,我们经常接触到的色彩空间的概念,主要是RGB , YUV这两种(实际上,这两种体系包含了许多种具体的颜色表达方式和模型,如sRGB, Adobe RGB, YUV422, YUV420 …, RGB是按三基色加光系统的原理来描述颜色,而YUV则是按照 亮度,色差的原理来描述颜色。

        即使只是 RGB YUV 这两大类色彩空间,所涉及到的知识也是十分丰富复杂的,自知不具备足够的相关专业知识,所以本文主要针对工程领域的应用及算法进行讨论。
2 YUV相关色彩空间模型

2.1 YUV YIQ YcrCb

        对于YUV模型,实际上很多时候,我们是把它和YIQ / YCrCb模型混为一谈的。

        实际上,YUV模型用于PAL制式的电视系统,Y表示亮度,UV并非任何单词的缩写。

        YIQ模型与YUV模型类似,用于NTSC制式的电视系统。YIQ颜色空间中的IQ分量相当于将YUV空间中的UV分量做了一个33度的旋转。

        YCbCr颜色空间是由YUV颜色空间派生的一种颜色空间,主要用于数字电视系统中。从RGBYCbCr的转换中,输入、输出都是8位二进制格式。

        三者与RGB的转换方程如下:

        RGB -> YUV

         

        实际上也就是:

Y=0.30R+ 0.59G +0.11B U=0.493(BY) V=0.877(RY)

        RGB -> YIQ

         

        RGB -> YCrCb

         

        从公式中,我们关键要理解的一点是,UV / CbCr信号实际上就是蓝色差信号和红色差信号,进而言之,实际上一定程度上间接的代表了蓝色和红色的强度,理解这一点对于我们理解各种颜色变换处理的过程会有很大的帮助。

        我们在数字电子多媒体领域所谈到的YUV格式,实际上准确的说,是以YcrCb色彩空间模型为基础的具有多种存储格式的一类颜色模型的家族(包括YUV444 / YUV422 / YUV420 / YUV420P等等)。并不是传统意义上用于PAL制模拟电视的YUV模型。这些YUV模型的区别主要在于UV数据的采样方式和存储方式,这里就不详述。

        而在 Camera Sensor 中,最常用的 YUV 模型是 YUV422 格式,因为它采用 4 个字节描述两个像素,能和 RGB565 模型比较好的兼容。有利于 Camera Sensor Camera controller 的软硬件接口设计。
3 YUV2RGB快速算法分析

这里指的YUV实际是YcrCb 8  ) YUV2RGB的转换公式本身是很简单的,但是牵涉到浮点运算,所以,如果要实现快速算法,算法结构本身没什么好研究的了,主要是采用整型运算或者查表来加快计算速度。
首先可以推导得到转换公式为:

        R = Y + 1.4075 *V-128
        G = Y – 0.3455 *U –128 – 0.7169 *V –128
        B = Y + 1.779 *U – 128

3.1 整型算法

       要用整型运算代替浮点运算,当然是要用移位的办法了,我们可以很容易得到下列算法:

        u = YUVdata[UPOS] - 128;
        v = YUVdata[VPOS] - 128;

        rdif = v + ((v * 103) >> 8);
        invgdif = ((u * 88) >> 8) +((v * 183) >> 8);
        bdif = u +( (u*198) >> 8);

        r = YUVdata[YPOS] + rdif;
        g = YUVdata[YPOS] - invgdif;
        b = YUVdata[YPOS] + bdif;

为了防止出现溢出,还需要判错计算的结果是否在0-255范围内,做类似下面的判断。

        if (r>255)
            r=255;
        if (r<0)
            r=0;

        要从RGB24转换成RGB565数据还要做移位和或运算:

        RGBdata[1] =( (r & 0xF8)  | ( g >> 5) );
        RGBdata[0] =( ((g & 0x 1C ) << 3) | ( b >> 3) );

3.2 部分查表法

        查表法首先可以想到的就是用查表替代上述整型算法中的乘法运算。

        rdif = fac_1_4075[u];
        invgdif = fac_m_0_3455[u] + fac_m_0_7169[v];
        bdif = fac_1_779[u];

        这里一共需要41维数组,下标从0开始到255,表格共占用约1K的内存空间。uv可以不需要做减128的操作了。在事先计算对应的数组元素的值的时候计算在内就好了。

        对于每个像素,部分查表法用查表替代了2次减法运算和4次乘法运算,4次移位运算。但是,依然需要多次加法运算和6次比较运算和可能存在的赋值操作,相对第一种方法运算速度提高并不明显。

3.3 完全查表法

        那么是否可以由YUV直接查表得到对应的RGB值呢?乍一看似乎不太可能,以最复杂的G的运算为例,因为GYUV三者都相关,所以类似 G=YUV 2G [Y][U][V]这样的算法,一个三维下标尺寸都为256的数组就需要占用224次方约16兆空间,绝对是没法接受的。所以目前多数都是采用部分查表法。

        但是,如果我们仔细分析就可以发现,对于G我们实际上完全没有必要采用三维数组,因为Y只与UV运算的结果相关,与UV的个体无关,所以我们可以采用二次查表的方法将G的运算简化为对两个二维数组的查表操作,如下:

        G = yig 2g _table[ y ][ uv2ig_table[ u ][ v ] ]

        RB本身就只和YUYV相关,所以这样我们一共需要48*8的二维表格,需要占用4216次方共256K内存。基本可以接受。但是对于手机这样的嵌入式运用来说,还是略有些大了。

        进一步分析,我们可以看到,因为在手机等嵌入式运用上我们最终是要把数据转换成RGB565格式送到LCD屏上显示的,所以,对于RGB三分量来说,我们根本不需要8bit这么高的精度,为了简单和运算的统一起见,对每个分量我们其实只需要高6bit的数据就足够了,所以我们可以进一步把表格改为46*6的二维表格,这样一共只需要占用16K内存!在计算表格元素值的时候还可以把最终的溢出判断也事先做完。最后的算法如下:

        y = (YUVdata[Y1POS] >> 2);
        u = (YUVdata[UPOS] >> 2);
        v = (YUVdata[VPOS] >> 2);

        r = yv2r_table[ y ][ v ];
        g = yig 2g _table[ y ][ uv2ig_table[ u ][ v ] ];
        b = yu2b_table[ y ][ u ];
 
        RGBdata[1] =( (r & 0xF8)  | ( g >> 5) );
        RGBdata[0] =( ((g & 0x 1C ) << 3) | ( b >> 3) );

        这样相对部分查表法,我们增加了3次移位运算,而进一步减少了4次加法运算和6次比较赋值操作。

        在计算表格元素数值的时候,要考虑舍入和偏移等因数使得计算的中间结果满足数组下标非负的要求,需要一定的技巧。

        采用完全查表法,相对于第一种算法,最终运算速度可以有比较明显的提高,具体性能能提高多少,要看所在平台的CPU运算速度和内存存取速度的相对比例。内存存取速度越快,用查表法带来的性能改善越明显。在我的PC上测试的结果性能大约能提高35%。而在某ARM平台上测试只提高了约15%

3.4 进一步的思考

        实际上,上述算法:

        RGBdata[1] =( (r & 0xF8)  | ( g >> 5) );
        RGBdata[0] =( ((g & 0x 1C ) << 3) | ( b >> 3) );

        中的 (r & 0xF8) ( b >> 3) 等运算也完全可以在表格中事先计算出来。另外,YU / YV的取值实际上不可能覆盖满6*6的范围,中间有些点是永远取不到的无输入,RB的运算也可以考虑用5*5的表格。这些都可能进一步提高运算的速度,减小表格的尺寸。

        另外,在嵌入式运用中,如果可能尽量将表格放在高速内存如 SRAM 中应该比放在 SDRAM 中更加能发挥查表法的优势。
评论 1
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值