【图像处理】RGB转YUV 优化

最近在项目的过程中需要用到 YUV 的 Y通道数据,但是原始数据图像为RGB格式,所以自己写了一个RGB2YUV的程序,并且进行优化,对此总结如下。

RGB2YUV 原理

RGB及YUV是两种不同的颜色空间,具体可以换算关系如下:

这里写图片描述

根据该换算关系,我们直接可以得到Y通道数据。

程序1

void rgb2yuv2(unsigned char *R,unsigned char *G,unsigned char *B,unsigned char *Y,int len)
{
//这里应有对指针的有效性判断,此处略
    for(int i=len;i!=0;i--){
        *Y++ = *R*0.299 + *G*0.587 + *B*0.114;
        R++;B++;G++;
    }

}

优化思路

不过这里涉及大量的浮点数运算,使得程序运行十分缓慢,为了加速,我们可以采用查表法及定点运算进行优化。

1、查表法

因为R/G/B通道的系数都已经固定了,只要预先求出[0..255]这些数值乘以系数对应的数值,在读取到对应R通道数据时,可以通过查表形式获取。

2、定点运算

由于系数均为小数点3位数,我们可以 先乘以299再除以1000 达到 乘以0.299 的目的。
同时,为了简化乘法,采用移位操作,向右移位10bit,则表示除以1024,对应的,我们只要在生成 查表数值 的时候,乘以1024即可。

综合1、2,我们可以先将:

对于R通道,[0..255] 乘以 0.299,再乘以1024,得到 256个对应的数值。G/B通道也采取类似操作。
在计算Y通道时,取出R/G/B通道对应的数值,求和并右移10位,得到最终数据。

程序2

int array[256];
// 生成各个通道对应的数值,并保存至表格
void genArray(float factor){ // factor是对应通道的系数。
    int i=0;
    for(i=0;i<256;i++){
        array[i]=(int)(factor*i*1024+0.5); 
    }
}

// RGB转YUV
void rgb2yuv(unsigned char *R,unsigned char *G,unsigned char *B,unsigned char *Y,int len)
{
//这里应有对指针的有效性判断,此处略
         for(int i=len;i!=0;i--){
               *Y++ = (RT[*R++]+GT[*G++]+BT[*B++])>>10;
        }

}

经验证,实际得到的图像与程序1得到的图像类似,误差为±1

你可能感兴趣的:(【图像算法】)