【Codecs】颜色空间转换CSconvert:YUV420转YUV444

Date: 2018.5.31


1、YUV分三种采样方式:

【Codecs】颜色空间转换CSconvert:YUV420转YUV444_第1张图片
YUV444:对于每一个像素都对应一个Y分量、一个U分量、一个V分量。

YUV422:对于一个像素都对应一个Y分量,但是每两个像素(或者说Y分量)对应一个U分量和一个V分量。

YUV420:对于一个像素都对应一个Y分量,但是每四个像素(或者说Y分量)对应一个U分量和一个V分量。

2、YUV的存储格式:

YUV在存储时是以数组的形式存储的,可以看做连续的三个数组。三个数组分别单独存储Y、U、V分量。

同理对于YUV420和YUV422,只是U和V的数组大小的不同而已。

总数据量来看,YUV444需要存储1920*1080*3个值,YUV422需要存储1920*1080*2个值,YUV420需要存储1920*1080*3/2个值。

3、YUV420转YUV444主要思路:

YUV420转YUV444,实际就是对色度进行上采样,最为简单的实现思路是直接填充。

以U分量为例,其序列如下

这里写图片描述

对U进行插值,每个田字格四个位置使用一个U值。
【Codecs】颜色空间转换CSconvert:YUV420转YUV444_第2张图片

在代码中,可以直接通过对数组循环赋值即可完成。

对V分量的操作相同。

填充方式实现简单,效果较差,可以通过插值来完成上采样。

参考:https://blog.csdn.net/lin453701006/article/details/53053185

自己实现的C代码如下:

#include 
#include 
#include 

int main(int argc, char** argv)
{
    int i, j, width, height, frame_size;
    FILE *fp_in, *fp_out;
    unsigned char *y1, *u1, *v1, *y2, *u2, *v2;
    int n = 0;

    printf("\nUsage:YUV420toYUV444.exe inputfile outputfile width height\n\n");

    for (i = 0; i < argc;i++)
    {
        printf("Input parameters: %s \n", argv[i]);
    }
    if (argc < 5)
    {
        return -1;
    }

    fp_in = fopen(argv[1], "rb");
    if (NULL == fp_in)
    {
        printf("ERROR: open %s fail\n", argv[1]);
        return -1;
    }
    fp_out = fopen(argv[2], "wb");
    if (NULL == fp_out)
    {
        printf("ERROR: open %s fail\n", argv[2]);
        return -1;
    }

    width = atoi(argv[3]);
    height = atoi(argv[4]);
    frame_size = width*height;

    y1 = (unsigned char *)malloc(frame_size*3/2);
    if ( NULL == y1 )
    {
        printf("malloc y1 fail\n");
        return -1;
    }
    u1 = y1 + width*height;
    v1 = u1 + width*height / 4;

    y2 = (char *)malloc(frame_size*3);
    if (NULL== y2 )
    {
        printf("malloc y2 fail\n");
        return -1;
    }
    u2 = y2 + width*height;
    v2 = u2 + width*height;

    while (fread(y1,1,frame_size*3/2,fp_in) == frame_size*3/2)
    {
        memcpy(y2, y1, frame_size);//Y

        for (j = 0; j < height; j++)//U,V
        {
            for (i = 0; i < width; i++)
            {
                u2[j*width + i] = u1[j / 2 * width / 2 + i / 2];
                v2[j*width + i] = v1[j / 2 * width / 2 + i / 2];
            }
        }

        fwrite(y2, 1, frame_size*3, fp_out);

        n++;
    }

    printf("YUV420toYUV444 successfully!!,total frames: %d\n",n);

    free(y1);
    y1 = NULL;
    free(y2);
    y2 = NULL;
    fclose(fp_in);
    fclose(fp_out);

    return 0;
}

转载于:https://www.cnblogs.com/SoaringLee/p/10532466.html

你可能感兴趣的:(【Codecs】颜色空间转换CSconvert:YUV420转YUV444)