[数据压缩]RGB文件转换YUV420文件

目录

RGB文件与YUV文件格式

RGB到YUV的转换公式

c++代码实现

结果展示


RGB文件与YUV文件格式

  • RGB文件格式

RGB三个分量按照B、G、R的顺序储存(4:4:4)

[数据压缩]RGB文件转换YUV420文件_第1张图片

  • YUV文件格式

此次选用YUV420文件格式,每四个Y共用一组U、V分量(4:2:0)
 

[数据压缩]RGB文件转换YUV420文件_第2张图片

RGB到YUV的转换公式

Y = 0.299 R + 0.587 G + 0.114 B

U = - 0.1687 R - 0.3313 G + 0.5 B + 128

V = 0.5 R - 0.4187 G - 0.0813 B + 128

c++代码实现

#include 
#include 
#include 
using namespace std;
int main(int argc, char* argv[])
{
    FILE *fp = NULL;
    FILE *out_yuv = NULL;
    if (!(fp=fopen(argv[1], "rb")))
    {
        printf("输入rgb文件打开失败!\n");
    }
    if (!(out_yuv=fopen( argv[2], "wb") ))
    {
        printf("输出yuv文件打开失败!\n");
    }
    int w,h;
    w = atoi(argv[3]);
    h = atoi(argv[4]);

    unsigned char* buffer = (unsigned char *)malloc(sizeof(unsigned char)*w*h * 3);
    unsigned char* ybuf = (unsigned char *)malloc(sizeof(unsigned char)*w*h);
    unsigned char* ubuf = (unsigned char *)malloc(sizeof(unsigned char)*w*h/4);
    unsigned char* vbuf = (unsigned char *)malloc(sizeof(unsigned char)*w*h/4);
    fread(buffer, sizeof(unsigned char), 3 * w * h, fp);

    int uvnum=0;
    for (int i = 0; i < w*h; i++)
    {
        ybuf[i] = 0.299 * buffer[3 * i + 2] + 0.587 * buffer[3 * i + 1] + 0.114 * buffer[3 * i];
        if (ybuf[i] <= 15)
            ybuf[i] = 16;
        if (ybuf[i] >=236)
            ybuf[i] =235;
    }
    for(int i = 0;i < h;i++) {
        for (int j = 0; j < w; j++) {
            if (i % 2 == 0 && j % 2 == 0) {
                ubuf[uvnum] = -0.1684 * buffer[3 * (i * w + j) + 2] - 0.3316 * buffer[3 * (i * w + j) + 1]
                              + 0.5 * buffer[3 * (i * w + j)] + 128;
                if (ubuf[i] <= 15)
                    ubuf[i] = 16;
                if (ubuf[i] >= 241)
                    ubuf[i] = 240;
                vbuf[uvnum] = 0.5 * buffer[3 * (i * w + j) + 2] - 0.4187 * buffer[3 * (i * w + j) + 1]
                              - 0.0183 * buffer[3 * (i * w + j)] + 128;
                if (vbuf[uvnum] <= 15)
                    vbuf[uvnum] = 16;
                if (vbuf[uvnum] >= 241)
                    vbuf[uvnum] = 240;
                uvnum++;
            }
        }
    }
    fwrite(ybuf, sizeof(unsigned char), w*h, out_yuv);
    fwrite(ubuf, sizeof(unsigned char), w*h / 4, out_yuv);
    fwrite(vbuf, sizeof(unsigned char), w*h / 4, out_yuv);
    fclose(fp);
    fclose(out_yuv);
    free(buffer);
    free(ybuf);
    free(ubuf);
    free(vbuf);
    getchar();
    return 0;
}

并设置命令行参数

[数据压缩]RGB文件转换YUV420文件_第3张图片​​​​​​​ 

结果展示

[数据压缩]RGB文件转换YUV420文件_第4张图片

 

你可能感兴趣的:(数据压缩,c++,图像处理)