RGB24转yuv420 高效率 且颜色没有失真

前面使用dshow获取到的屏幕截图是一段rgb24的数据,需要将其转换成yuv420格式才能进行编码等操作。

网上找了很多资料,发现能用的并不多,这里总结一下。


1.雷大神写的 bmp转yuv:

http://blog.csdn.net/leixiaohua1020/article/details/13506099

这个是读取bmp文件然后转换成Yuv的,经过简单修改就可以将输入换成我们前面获得的rbg数据,运行后发现转换的效果很好,但是效率实在太低了,非常耗时。

由于本人对图片的组成和原理方面不懂,想要优化这个似乎太难了,只能继续上网找别的算法。


2.

http://blog.csdn.net/wishfly/article/details/50766370

这个效率挺高的,可惜转换出的图片颜色偏黄。。。

代码就几行 很简单。。  然而并不知道怎么改。。


3.

http://blog.csdn.net/wuzongman/article/details/8126012

果然功夫不负有心人,这个可以用。


转换完之后发现图像居然是垂直倒立的,于是参考了雷大神的代码,从中找到了倒转的代码,将2者结合结果非常完美。

整合后的代码代码如下:

#include "rgb2yuv.h"

Rgb2YUV::Rgb2YUV()
{
    table_init();
}

//表的初始化
void Rgb2YUV::table_init()
{
    int i;
    for(i = 0; i < COLORSIZE; i++)
    {
        Y_R[i] = (i * 1224) >> 12; //Y对应的查表数组0.2988
        Y_G[i] = (i * 2404) >> 12;  //0.5869
        Y_B[i] = (i * 469)  >> 12; //0.1162
        U_R[i] = (i * 692)  >> 12; //U对应的查表数组0.1688
        U_G[i] = (i * 1356) >> 12;  //0.3312
        U_B[i] = i /*(* 2048) */>> 1; //0.5
     //   V_R[i] = (i * 2048) >> 12; ///V对应的查表数组
        V_G[i] = (i * 1731) >> 12;  //0.4184
        V_B[i] = (i * 334)  >> 12; //0.0816
    }
}

void Rgb2YUV::RGB2YUV420(uint8_t *rgbBufIn, uint8_t *yuvBufOut , int nWidth, int nHeight)
{
    int pix = 0;
    int pixP4;

    RGB *in = (RGB *)rgbBufIn; //需要计算的原始数据
//    unsigned char out[XSIZE*YSIZE * 3/2]; //计算后的结果

    int IMGSIZE = nWidth * nHeight;

    for(int y = 0; y < nHeight; y++) //line
    {
        for(int x=0;x < nWidth;x++)//pixf
        {

//           RGB rgbByte = in[pix]; (这样取的数据经过转换后是一个垂直倒立的图像)
            RGB rgbByte = in[(nHeight-y-1)*nWidth+x]; //取得垂直方向上镜像的位置即可解决倒立问题

           //首先执行颜色互换 -- 没有这个的话  得到的YUV图像颜色不对
           uint8_t temp = rgbByte.r; //顺序调整
           rgbByte.r = rgbByte.b;
           rgbByte.b = temp;

            int     i = Y_R[rgbByte.r] + Y_G[rgbByte.g] + Y_B[rgbByte.b];
            yuvBufOut[pix]= i; //Y
            if((x%2==1)&&(y%2==1))
            {
                pixP4=(nWidth>>1) *(y>>1) + (x>>1);
                i=U_B[rgbByte.b] - U_R[rgbByte.r] - U_G[rgbByte.g]+128;

                yuvBufOut[pixP4+IMGSIZE]     = i;
                /*+  U_B[in[pix+1].b] - U_R[in[pix+1].r] - U_G[in[pix+1].g]
                +U_B[in[pix+XSIZE].b] - U_R[in[pix+XSIZE].r] - U_G[in[pix+XSIZE].g]
                +U_B[in[pix+1+XSIZE].b] - U_R[in[pix+1+XSIZE].r] - U_G[in[pix+1+XSIZE].g] )/4*/
                //U
                i=U_B[rgbByte.r] - V_G[rgbByte.g] - V_B[rgbByte.b]+128;

                yuvBufOut[pixP4 + 5 * IMGSIZE /4] = i;
                /*+U_B[in[pix+1].r] - V_G[in[pix+1].g] - V_B[in[pix+1].b]
                +U_B[in[pix+XSIZE].r] - V_G[in[pix+XSIZE].g] - V_B[in[pix+XSIZE].b]
                +U_B[in[pix+1+XSIZE].r] - V_G[in[pix+1+XSIZE].g] - V_B[in[pix+1+XSIZE].b])/4*/
                //V
            }

            pix++;
        }

    }
}


完整代码下载地址:

http://download.csdn.net/detail/qq214517703/9612782





  • 3
    点赞
  • 16
    收藏
    觉得还不错? 一键收藏
  • 5
    评论

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

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值