yuv422 java_论YUV422(YUYV)与YUV420相互转换

博客介绍了YUV422、YUV420和YUV444码流存放位置,阐述了YUV422和YUV420的采样方式。YUV422从YUV444基础上交替采样,YUV420从YUV422基础上隔行采样。还给出了将YUV422转换为YUV420的具体代码及使用示例。

摘要生成于 C知道 ,由 DeepSeek-R1 满血版支持, 前往体验 >

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码流存放位置

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码流存放位置

这里要顺带提一下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.

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

#include 

#include 

#define     READ_WRITE_FILE_SIZE    176*144*2  //YUV422 图像分辨率为177x144

unsigned char filebuf[38017] = {0};

int YUV422To420(unsigned char yuv422[], unsigned char yuv420[], int width, int height)

{

int ynum=width*height;

int i,j,k=0;

//得到Y分量

for(i=0;i

yuv420[i]=yuv422[i*2];

}

//得到U分量

for(i=0;i

if((i%2)!=0)continue;

for(j=0;j

if((4*j+1)>(2*width))break;

yuv420[ynum+k*2*width/4+j]=yuv422[i*2*width+4*j+1];

}

k++;

}

k=0;

//得到V分量

for(i=0;i

if((i%2)==0)continue;

for(j=0;j

if((4*j+3)>(2*width))break;

yuv420[ynum+ynum/4+k*2*width/4+j]=yuv422[i*2*width+4*j+3];

}

k++;

}

return 1;

}

int main(void)

{

int len = 0;

FILE *fpr, *fpw;

unsigned char buf[READ_WRITE_FILE_SIZE];

fpr = fopen( "WEBCAM-00012.YUV", "rb" );

fpw = fopen( "yuyv_2_yy_u_v.yuv", "wb" );

if( fpr == NULL || fpw == NULL )

{

printf("can not read or write file\n");

fcloseall();

return 1;

}

fread( buf, READ_WRITE_FILE_SIZE, 1, fpr );

if(YUV422To420(buf,filebuf,176,144))printf("ok\n");

printf("size:%d",sizeof(filebuf));

fwrite( &filebuf, sizeof(filebuf), 1, fpw );

fcloseall();

return 0;

}

#include 

#include 

#define     READ_WRITE_FILE_SIZE    176*144*2  //YUV422 图像分辨率为177x144

unsigned char filebuf[38017] = {0};

int YUV422To420(unsigned char yuv422[], unsigned char yuv420[], int width, int height)

{

int ynum=width*height;

int i,j,k=0;

//得到Y分量

for(i=0;i

yuv420[i]=yuv422[i*2];

}

//得到U分量

for(i=0;i

if((i%2)!=0)continue;

for(j=0;j

if((4*j+1)>(2*width))break;

yuv420[ynum+k*2*width/4+j]=yuv422[i*2*width+4*j+1];

}

k++;

}

k=0;

//得到V分量

for(i=0;i

if((i%2)==0)continue;

for(j=0;j

if((4*j+3)>(2*width))break;

yuv420[ynum+ynum/4+k*2*width/4+j]=yuv422[i*2*width+4*j+3];

}

k++;

}

return 1;

}

int main(void)

{

int len = 0;

FILE *fpr, *fpw;

unsigned char buf[READ_WRITE_FILE_SIZE];

fpr = fopen( "WEBCAM-00012.YUV", "rb" );

fpw = fopen( "yuyv_2_yy_u_v.yuv", "wb" );

if( fpr == NULL || fpw == NULL )

{

printf("can not read or write file\n");

fcloseall();

return 1;

}

fread( buf, READ_WRITE_FILE_SIZE, 1, fpr );

if(YUV422To420(buf,filebuf,176,144))printf("ok\n");

printf("size:%d",sizeof(filebuf));

fwrite( &filebuf, sizeof(filebuf), 1, fpw );

fcloseall();

return 0;

}

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值