关于YUV的存储格式

来源:互联网 发布:广东人长相知乎 编辑:程序博客网 时间:2024/05/23 23:22

关于YUV图像的处理

本文主要讲解一下YUV420的存储,是博主在接触YUV图像时候总结出来的一些经验。多为自己的理解和认识,欢迎大家批评指正。

  • YUV420的介绍
    yuv420是yuv的一种采样格式
    y是代表像素的灰阶值,uv是表示色度的。4:2:0是采样的比例,4个y共用一组uv值。隔行采样。
  • YUV的图像存储
    上面说到的隔行采样是指如下:
    这里写图片描述    
    上图这样同色的Y值共用同一组U,V值。隔行采一次样。像素数据也按照图中格式储存。
  • RGB2YUV
      RGB图像的大小是同尺寸YUV图像的两倍大小。
      因为RGB图像中的每个像素值都需要用R,G,B三个值表示。
    这里写图片描述

故将rgb转yuv有以下代码:

void RgbWriteYuv(int& ywidth,int& yheight,char* image){   //image is rgb's value    FILE *inputYUV = fopen("yuv420.yuv", "wb");    int size_total = yheight*ywidth*3;    int size = size_total/2;    int* YUV_matrix = (int*)malloc(size*sizeof(int));    memset(YUV_matrix, 0, size_total);    int* RGB_matrix = (int*)malloc(size_total *sizeof(int));    if (inputYUV == NULL) {        printf("open yuv file failed\n");    }    for (int j = 0; j < size_total; j++) {        RGB_matrix[j] = image[j];    }    int* bufY = YUV_matrix;    int* bufU = YUV_matrix + size;    int* bufV = bufU + size*1/4;    int *RGB;    int k = 0;    unsigned char y, u, v, r, g, b;    //RGB[0,255]--->YUV[0,255]    for (int j = 0; j < yheight; j++) {        for (int i = 0; i < ywidth; i++) {            r = RGB_matrix[k++];            g = RGB_matrix[k++];            b = RGB_matrix[k++];            y = (unsigned char)((299*r + 587*g + 114*b)/1000);            v = (unsigned char)((500*r - 419*g - 81*b)/1000)+128;            u = (unsigned char)((-169*r - 331*g + 500*b)/1000)+128;            if (y > 255)                y = 255;            if (y < 0)                y = 0;            *(bufY++) = y;            if (j%2 == 0 && i%2 == 0)             {                if (u > 255)                    u = 255;                if (u < 0)                    u = 0;                *(bufU++) = u;                 if (v > 255)                    v = 255;                if (v < 0)                    v = 0;                *(bufV++) = v;            }        }    }    for (int i = 0; i < size; i++)    {    fputc (YUV_matrix[i], inputYUV);    }            fclose(inputYUV);    free(RGB_matrix);    free(YUV_matrix);}
  • 灰度图(pgm)2YUV
           pgm格式图片转到yuv中间需要经过rgb这个转折点。也就是说先要把pgm转为rgb。
           这里写图片描述      
    图为pgm的存储格式。
    读出pgm的像素值得到一个image:
char* pgmRead (char* pgmname, int& cols,int& rows){    FILE *filePointer;    char line[MAXLENGTH];     int maximumValue = 0;     bool binary;             int numberRead = 0;     int i,j;                 int test,temp;       if ((filePointer = fopen(pgmname,"r")) == NULL)     {        printf ("ERROR: cannot open file\n\n");    }    fgets (line,MAXLENGTH,filePointer);    while (line[0]=='#' || line[0]=='\n')     {        fgets (line,MAXLENGTH,filePointer);    }        if (line[0]=='P' && (line[1]=='5'))     {        binary = 1;    }    else     {        printf ("ERROR: incorrect file format\n\n");    }              fgets (line,MAXLENGTH,filePointer);    while (line[0]=='#' || line[0]=='\n')         fgets (line,MAXLENGTH,filePointer);    sscanf (line,"%d %d",&cols,&rows);    printf ("width:%d  height:%d\n\n", cols,rows);    fgets (line,MAXLENGTH,filePointer);    while (line[0]=='#' || line[0]=='\n')           fgets(line,MAXLENGTH,filePointer);    sscanf (line,"%d",&maximumValue);    int size= rows*cols;    char* image = (char*)malloc(sizeof(char)*size);    if (binary)     {            printf("binary is 1\n");        for (i = 0; i < rows; i++)         {            numberRead += fread((void *)&(image[i*cols]),1,cols,filePointer);             if (feof(filePoi    nter))                 break;        }    }   if (numberRead < rows*cols) {        printf ("ERROR: fewer pixels than rows*cols indicates\n\n");    }    fclose (filePointer);    return image;}

r[i]=g[i]=b[i]=image[i];
转为rgb后代入上一节RGB2YUV中转成YUV图像。

原创粉丝点击