zoukankan      html  css  js  c++  java
  • 论YUV422(YUYV)与YUV420相互转换

    Example 2.13. V4L2_PIX_FMT_YUYV 4 × 4 pixelimage

    start + 0:

    Y'00

    Cb00

    Y'01

    Cr00

    Y'02

    Cb01

    Y'03

    Cr01

    start + 8:

    Y'10

    Cb10

    Y'11

    Cr10

    Y'12

    Cb11

    Y'13

    Cr11

    start + 16:

    Y'20

    Cb20

    Y'21

    Cr20

    Y'22

    Cb21

    Y'23

    Cr21

    start + 24:

    Y'30

    Cb30

    Y'31

    Cr30

    Y'32

    Cb31

    Y'33

    Cr31

    YUV422码流存放位置

    (转自http://www.chineselinuxuniversity.net/kerneldocs/media/V4L2-PIX-FMT-YUYV.html)

    Example 2.18. V4L2_PIX_FMT_YUV420 4 × 4 pixelimage

    start + 0:

    Y'00

    Y'01

    Y'02

    Y'03

    start + 4:

    Y'10

    Y'11

    Y'12

    Y'13

    start + 8:

    Y'20

    Y'21

    Y'22

    Y'23

    start + 12:

    Y'30

    Y'31

    Y'32

    Y'33

    start + 16:

    Cb00

    Cb01

     

     

    start + 18:

    Cb10

    Cb11

     

     

    start + 20:

    Cr00

    Cr01

     

     

    start + 22:

    Cr10

    Cr11

     

     

     

     

     

     

    YUV420码流存放位置

    (转自http://www.chineselinuxuniversity.net/kerneldocs/media/re18.html该处是YVU420)

    这里要顺带提一下YUV444,既无损YUV色彩空间.一个Y带一个Cb一个Cr,即YCbCr.

    YUV422采样即从YUV444基础上,从第一个Y开始只保留Cb,剔去Cr,第二个Y只保留Cr剔去Cb…...这样交替采样,长度大小为width*height*2,Y:U:V=4:2:2,一个色彩分量占一个字节.

    而YUV420即从YUV422基础上进行隔行采样,例如第一行只保留Cb,第二行只保留Cr……这样交替进行,Y:U:V=4:2:0并不是没有V分量,也可以是Y:U:V=4:0:2.相信这样大家容易理解.最后在这个基础上,把Y,U,V三种分量打包排列,即如上图,长度大小为width*height*3/2.

    说了这么多,是时候贴上具体代码.

    [cpp] view plain copy
     
    1. <span style="font-size:14px;">#include <stdio.h>  
    2. #include <string.h>  
    3.   
    4.   
    5. #define     READ_WRITE_FILE_SIZE    176*144*2  //YUV422 图像分辨率为177x144  
    6.   
    7. unsigned char filebuf[38017] = {0};  
    8.   
    9. int YUV422To420(unsigned char yuv422[], unsigned char yuv420[], int width, int height)  
    10. {          
    11.   
    12.        int ynum=width*height;  
    13.        int i,j,k=0;  
    14.     //得到Y分量  
    15.        for(i=0;i<ynum;i++){  
    16.            yuv420[i]=yuv422[i*2];  
    17.        }  
    18.     //得到U分量  
    19.        for(i=0;i<height;i++){  
    20.            if((i%2)!=0)continue;  
    21.            for(j=0;j<(width/2);j++){  
    22.                if((4*j+1)>(2*width))break;  
    23.                yuv420[ynum+k*2*width/4+j]=yuv422[i*2*width+4*j+1];  
    24.                        }  
    25.             k++;  
    26.        }  
    27.        k=0;  
    28.     //得到V分量  
    29.        for(i=0;i<height;i++){  
    30.            if((i%2)==0)continue;  
    31.            for(j=0;j<(width/2);j++){  
    32.                if((4*j+3)>(2*width))break;  
    33.                yuv420[ynum+ynum/4+k*2*width/4+j]=yuv422[i*2*width+4*j+3];  
    34.                 
    35.            }  
    36.             k++;  
    37.        }  
    38.          
    39.          
    40.        return 1;  
    41. }  
    42.   
    43. int main(void)  
    44. {  
    45.     int len = 0;  
    46.     FILE *fpr, *fpw;  
    47.     unsigned char buf[READ_WRITE_FILE_SIZE];  
    48.     fpr = fopen( "WEBCAM-00012.YUV", "rb" );  
    49.     fpw = fopen( "yuyv_2_yy_u_v.yuv", "wb" );  
    50.     if( fpr == NULL || fpw == NULL )  
    51.     {  
    52.         printf("can not read or write file ");  
    53.         fcloseall();  
    54.         return 1;  
    55.     }  
    56.     fread( buf, READ_WRITE_FILE_SIZE, 1, fpr );  
    57.     if(YUV422To420(buf,filebuf,176,144))printf("ok ");  
    58.     printf("size:%d",sizeof(filebuf));  
    59.     fwrite( &filebuf, sizeof(filebuf), 1, fpw );  
    60.     fcloseall();  
    61.     return 0;  
    62. }  
    63. </span>  
    [cpp] view plain copy
     
    1. <span style="font-size:14px;">#include <stdio.h>  
    2. #include <string.h>  
    3.   
    4.   
    5. #define     READ_WRITE_FILE_SIZE    176*144*2  //YUV422 图像分辨率为177x144  
    6.   
    7. unsigned char filebuf[38017] = {0};  
    8.   
    9. int YUV422To420(unsigned char yuv422[], unsigned char yuv420[], int width, int height)  
    10. {          
    11.   
    12.        int ynum=width*height;  
    13.        int i,j,k=0;  
    14.     //得到Y分量  
    15.        for(i=0;i<ynum;i++){  
    16.            yuv420[i]=yuv422[i*2];  
    17.        }  
    18.     //得到U分量  
    19.        for(i=0;i<height;i++){  
    20.            if((i%2)!=0)continue;  
    21.            for(j=0;j<(width/2);j++){  
    22.                if((4*j+1)>(2*width))break;  
    23.                yuv420[ynum+k*2*width/4+j]=yuv422[i*2*width+4*j+1];  
    24.                        }  
    25.             k++;  
    26.        }  
    27.        k=0;  
    28.     //得到V分量  
    29.        for(i=0;i<height;i++){  
    30.            if((i%2)==0)continue;  
    31.            for(j=0;j<(width/2);j++){  
    32.                if((4*j+3)>(2*width))break;  
    33.                yuv420[ynum+ynum/4+k*2*width/4+j]=yuv422[i*2*width+4*j+3];  
    34.                 
    35.            }  
    36.             k++;  
    37.        }  
    38.          
    39.          
    40.        return 1;  
    41. }  
    42.   
    43. int main(void)  
    44. {  
    45.     int len = 0;  
    46.     FILE *fpr, *fpw;  
    47.     unsigned char buf[READ_WRITE_FILE_SIZE];  
    48.     fpr = fopen( "WEBCAM-00012.YUV", "rb" );  
    49.     fpw = fopen( "yuyv_2_yy_u_v.yuv", "wb" );  
    50.     if( fpr == NULL || fpw == NULL )  
    51.     {  
    52.         printf("can not read or write file ");  
    53.         fcloseall();  
    54.         return 1;  
    55.     }  
    56.     fread( buf, READ_WRITE_FILE_SIZE, 1, fpr );  
    57.     if(YUV422To420(buf,filebuf,176,144))printf("ok ");  
    58.     printf("size:%d",sizeof(filebuf));  
    59.     fwrite( &filebuf, sizeof(filebuf), 1, fpw );  
    60.     fcloseall();  
    61.     return 0;  
  • 相关阅读:
    启动hadoop 2.6遇到的datanode启动不了
    .net开发遇到的一个问题
    there are 0 datanode.....
    更改HDFS权限
    VMware提示:已将该虚拟机配置为使用 64 位客户机操作系统。但是,无法执行 64 位操作。解决方案
    Hive学习
    linux下mysql安装
    (5.2)mysql高可用系列——测试环境部署
    【转】mysql索引的探究
    【3.1】【mysql基本实验】mysql复制(主从复制/异步复制/半同步复制,一主一从)
  • 原文地址:https://www.cnblogs.com/liangxiaofeng/p/6943594.html
Copyright © 2011-2022 走看看