YUYV 转 RGB 24

直入正题吧,

关于YUYV编码流的官方介绍:

http://linuxtv.org/downloads/v4l-dvb-apis/V4L2-PIX-FMT-YUYV.html


我们一起看看,

YUYV 这种编码

In this format each four bytes is two pixels. Each four bytes is two Y's, a Cb and a Cr. Each Y goes to one of the pixels, and the Cb and Cr belong to both pixels. As you can see, the Cr and Cb components have half the horizontal resolution of the Y component. V4L2_PIX_FMT_YUYV is known in the Windows environment as YUY2.

每四字节表示两个像素,每四字节有两个Y,一个CB和CR。每一个Y分别属于一个像素,CB和CR共同属于这两个点。这种格式在WINDOWS环境下叫YUY2

字节顺序. 表格中每个单元一个字节

start + 0:Y'00Cb00Y'01Cr00Y'02Cb01Y'03Cr01
start + 8:Y'10Cb10Y'11Cr10Y'12Cb11Y'13Cr11
start + 16:Y'20Cb20Y'21Cr20Y'22Cb21Y'23Cr21
start + 24:Y'30Cb30Y'31Cr30Y'32Cb31Y'33Cr31

实际分布. 


0
1
2
3
0YCY
YCY
1YCY
YCY
2YCY
YCY
3YCY
YCY


根据这个,用每个点下的值乘换算公式,就可以得到对应RGB下的点,换算公式我就不多说了,讲到这里,直接贴代码把:

//YUV像素 转 RGB像素的函数
static void yuv_to_rgb_24(unsigned char y, unsigned char u, unsigned char v,
			unsigned char* r, unsigned char* g, unsigned char* b)
{
	int amp=255;
	double R,G,B;
	
	//conversion equations
	B=amp*(0.004565*y+0.000001*u+0.006250*v-0.872);
	G=amp*(0.004565*y-0.001542*u-0.003183*v+0.531);
	R=amp*(0.004565*y+0.007935*u-1.088);

	//R, G and B must be in the range from 0 to 255    
	if (R < 0)
		R=0;
	if (G < 0)
		G=0;
	if (B < 0)
		B=0;
	
	if (R > 255)
		R=255;
	if (G > 255)
		G=255;
	if (B > 255)
		B=255;

	*r=(unsigned char)(R);
	*g=(unsigned char)(G);
	*b=(unsigned char)(B);

}


	//TODO: width*height这个是图像的长宽,这里默认是24位色深,16位的话,原理一样,不懂留言问我吧。
	uint8_t * imageLine1;
	int    xx,yy;
	int    x,y;
	int bpl,Bpp,amp;
	double r,g,b;
	unsigned char Y,U,V;
	unsigned char R,G,B,RG,GB;
	imageLine1 = (uint8_t *)malloc(width*height*3);
	bpl=width*3;//bytes per line,
	Bpp=3;//bytes per pixel,
	/*TODO: 这里把图像像素组读到videoFrame里,根据自己的情况,从网络,从管道还是从其他地方	
	int ret;
	
	ret = read(STDIN_FILENO, videoFrame , width*height*2);
	*/
	
	for (yy = 0; yy < (height); yy++)
	{
		for (xx =0; xx < (width/2); xx++)
		{	
			x=4*xx;
			y=yy;
			U = videoFrame[width*2*y+x+3];				
			V = videoFrame[width*2*y+x+1];

			Y = videoFrame[width*2*y+x];
			yuv_to_rgb_24(Y, U, V, &R,&G,&B);
			imageLine1[(bpl*y)+(Bpp*x/2)]=B;
			imageLine1[(bpl*y)+(Bpp*x/2)+1]=G;
			imageLine1[(bpl*y)+(Bpp*x/2)+2]=R;
						
			Y = videoFrame[width*2*y+x+2];

			yuv_to_rgb_24(Y, U, V, &R,&G,&B);
			imageLine1[(bpl*y)+(Bpp*(x/2+1))]=B;
			mageLine1[(bpl*y)+(Bpp*(x/2+1))+1]=G;
			imageLine1[(bpl*y)+(Bpp*(x/2+1))+2]=R;
		}
	}
				
		



这代码是我从v4l2 sample code改过来的,他们只支持YUV420,不支持YUYV,于是我作了修改。

其他YUV格式的转换思路差不多,有时间的话感觉应该弄个lib,每个刚去接触视频编码的人都要看这个,挺浪费时间的。

  • 0
    点赞
  • 4
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值