yuv转RGB

先区分一下YUV和YCbCr

YUV色彩模型来源于RGB模型,

该模型的特点是将亮度和色度分离开,从而适合于图像处理领域。

应用:模拟领域

Y'= 0.299*R' + 0.587*G' + 0.114*B'

U'= -0.147*R' - 0.289*G' + 0.436*B' = 0.492*(B'- Y')

V'= 0.615*R' - 0.515*G' - 0.100*B' = 0.877*(R'- Y')

R' = Y' + 1.140*V'

G' = Y' - 0.394*U' - 0.581*V'

B' = Y' + 2.032*U'

YCbCr模型来源于YUV模型。YCbCr是 YUV 颜色空间的偏移版本.

应用:数字视频,ITU-R BT.601建议

Y’ = 0.257*R' + 0.504*G' + 0.098*B' + 16

Cb' = -0.148*R' - 0.291*G' + 0.439*B' + 128

Cr' = 0.439*R' - 0.368*G' - 0.071*B' + 128

static int yuv_tbl_ready=0;
static int y1192_tbl[256];
static int v1634_tbl[256];
static int v833_tbl[256];
static int u400_tbl[256];
static int u2066_tbl[256];
int yuyv422_to_abgr(char *dst,char *src,int height,int width)
{
    int i;
    int frame_size = width*height*2;

    if(!dst){
        return -1;
    }
    int *lrgb = (int *)dst;

    if(yuv_tbl_ready==0){
        for(i=0 ; i<256 ; i++){
            y1192_tbl[i] = 1192*(i-16);
            if(y1192_tbl[i]<0){
                y1192_tbl[i]=0;
            }

            v1634_tbl[i] = 1634*(i-128);
            v833_tbl[i] = 833*(i-128);
            u400_tbl[i] = 400*(i-128);
            u2066_tbl[i] = 2066*(i-128);
        }
        yuv_tbl_ready=1;
    }

    for(i=0 ; i<frame_size ; i+=4){
        unsigned char y1, y2, u, v;
        y1 = src[i];
        u = src[i+1];
        y2 = src[i+2];
        v = src[i+3];

        int y1192_1=y1192_tbl[y1];
        int r1 = (y1192_1 + v1634_tbl[v])>>10;
        int g1 = (y1192_1 - v833_tbl[v] - u400_tbl[u])>>10;
        int b1 = (y1192_1 + u2066_tbl[u])>>10;

        int y1192_2=y1192_tbl[y2];
        int r2 = (y1192_2 + v1634_tbl[v])>>10;
        int g2 = (y1192_2 - v833_tbl[v] - u400_tbl[u])>>10;
        int b2 = (y1192_2 + u2066_tbl[u])>>10;

        r1 = r1>255 ? 255 : r1<0 ? 0 : r1;
        g1 = g1>255 ? 255 : g1<0 ? 0 : g1;
        b1 = b1>255 ? 255 : b1<0 ? 0 : b1;
        r2 = r2>255 ? 255 : r2<0 ? 0 : r2;
        g2 = g2>255 ? 255 : g2<0 ? 0 : g2;
        b2 = b2>255 ? 255 : b2<0 ? 0 : b2;

        *lrgb++ = 0xff000000 | b1<<16 | g1<<8 | r1;
        *lrgb++ = 0xff000000 | b2<<16 | g2<<8 | r2;

    }
    return 0;
}

R' = 1.164*(Y’-16) + 1.596*(Cr'-128)

G' = 1.164*(Y’-16) - 0.813*(Cr'-128) - 0.392*(Cb'-128)

B' = 1.164*(Y’-16) + 2.017*(Cb'-128)

PS: 上面各个符号都带了一撇,表示该符号在原值基础上进行了伽马校正,伽马校正有助于弥补在抗锯齿的过程中,线性分配伽马值所带来的细节损失,使图像细节更加丰富。在没有采用伽马校正的情况下,暗部细节不容易显现出来,而采用了这一图像增强技术以后,图像的层次更加明晰了。

所以说H264里面的YUV应属于YCbCr, 也可以点这里获得其他一些信息.

 

下面在仔细谈谈YUV格式, YUV格式通常有两大类:打包(packed)格式和平面(planar)格式。前者将YUV分量存放在同一个数组中,通常是几个相邻的像素组成一个宏像素(macro-pixel);而后者使用三个数组分开存放YUV三个分量,就像是一个三维平面一样。

我们常说得YUV420属于planar格式的YUV, 颜色比例如下:

Y0U0V0             Y1                 Y2U2V2                          Y3

Y4                      Y5                 Y6                                   Y7

Y8U8V8             Y9                 Y10U10V10                   Y11

Y12           Y13          Y14                   Y15

其他格式YUV可以点这里查看详细内容, 而在YUV文件中YUV420又是怎么存储的呢? 在常见H264测试的YUV序列中,例如CIF图像大小的YUV序列(352*288),在文件开始并没有文件头,直接就是YUV数据,先存第一帧的Y信息,长度为352*288个byte,然后是第一帧U信息长度是352*288/4个byte, 最后是第一帧的V信息,长度是352*288/4个byte, 因此可以算出第一帧数据总长度是352*288*1.5,即152064个byte, 如果这个序列是300帧的话, 那么序列总长度即为152064*300=44550KB,这也就是为什么常见的300帧CIF序列总是44M的原因.

猜你喜欢

转载自blog.csdn.net/fuhanga123/article/details/51593794
今日推荐