颜色空间转换CSConvert:YUV420转YUV444

  1. 1、YUV的三种采样方式
  2. 2、YUV的存储格式
  3. 3、YUV420转YUV444主要思路
  4. 4、算法实现(YUV420toYUV444)
  5. THE END!

1、YUV的三种采样方式

YUV三种采样格式

  • YUV444:对于每一个像素都对应一个Y分量、一个U分量、一个V分量。

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

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

2、YUV的存储格式

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

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

以1920x1080分辨率为例,总数据量来看,YUV444需要存储1920x1080x3个值,YUV422需要存储1920x1080x2个值,YUV420需要存储192x1080x3/2个值。

3、YUV420转YUV444主要思路

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

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

U分量示意

对U进行插值,每个田字格四个位置使用一个U值。
U分量填充示意

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

对V分量的操作相同。

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

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

4、算法实现(YUV420toYUV444)

自己实现的C代码如下:

#include <stdio.h>
#include <stdlib.h>
#include <string.h>

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;
}

THE END!


本博文只能阅读,谢绝转载,欢迎指出任何有错误或不够清晰的表达。可以在下面评论区评论,也可以邮件至 2963033731@qq.com

文章标题:颜色空间转换CSConvert:YUV420转YUV444

字数:667

本文作者:Soaring Lee

发布时间:2019-07-13, 21:45:47

最后更新:2021-06-14, 12:13:44

原始链接:https://soaringleefighting.github.io/2019/07/13/【Codecs系列】颜色空间转换CSConvert:YUV420转YUV444/

版权声明: "署名-非商用-相同方式共享 4.0" 转载请保留原文链接及作者。

×

喜欢就点赞,疼爱就打赏

相册