C实现彩色空间转换:YUV(4:2:0) 转 RGB

实验目的

将取样结构为4:2:0的yuv文件通过C语言转成rgb文件

方法解释

存储格式

我们用W和H来表示图像的宽和高

(4:2:0)YUV存储格式

4:2:0取样结构的yuv文件数据存储方式为WH个亮度信号Y顺序存放,尾部连接0.25WH个色差信号U顺序存放,再尾部连接0.25W*H个色差信号V顺序存放。

RGB存储格式

构成同一像素的三种彩色信号,按照GBR顺序依次存放,重复W*H次。

算法说明

4:2:0 yuv信号构成像素方式,如下图
图1
一个2x2正方形像素由同样的U、Y信号构成,所以在转换成RGB格式时,也要让一个2x2正方形像素由同样的U、Y信号转换成RGB信号。因此需要将W*H/4的U、V进行如下图的扩充
在这里插入图片描述
代码实现如下

for (j = 0; j < y_dim / 2; j ++) //y_dim为图像高度
	{
   
		psu = sub_u_buf + j * x_dim / 2;//sub_u_buf为原U信号序列
		psv = sub_v_buf + j * x_dim / 2;//sub_v_buf为原V信号序列
		pu1 = u + 2 * j * x_dim;//u为扩充后U信号序列
		pu2 = u + (2 * j + 1) * x_dim;
		pv1 = v + 2 * j * x_dim;//v为扩充后V信号序列
		pv2 = v + (2 * j + 1) * x_dim;
		for (i = 0; i < x_dim/2; i ++)//x_dim为图像宽度
		{
   
			*pu1 = *(pu1 + 1) = *pu2 = *(pu2 + 1) = *psu;
			*pv1 = *(pv1 + 1) = *pv2 = *(pv2 + 1) = *psv;
			psu ++;
			psv ++;
			pu1 += 2;
			pu2 += 2;
			pv1 += 2;
			pv2 += 2;
		}
	}

扩充后的U、Y信号数量等于Y信号,而且顺序关系一一对应。此时可以通过转换公式

//  R = 1.164 *(Y - 16) + 1.596 *(V- 128)                    //

//  G = 1.164 *(Y - 16) - 0.392 *(U - 128) - 0.812 *(V - 128)//

//  B = 1.164 *(Y - 16) + 2.016 *(U - 128)                    //

进行依次带入扩充后的YUV信序列转换,如下

for (i = 0; i < size ; i ++)
		{
   
			
			inter_var = ( YUVRGB1164_16[*py] - YUVRGB0392_128[*cb] - YUVRGB0812_128[*cr]);
			FixPixel(inter_var);//防止向unsigned char型指针赋值时
			/*void FixPixel(float &inter_var) 由于超出0-255,而乱码
			{
				if(inter_var < 0) 
				inter_var = 0;
				else if(inter_var > 255)
				inter_var = 255;
			}*/                    
			*g = (unsigned char)inter_var;

			inter_var = ( YUVRGB1164_16[*py] + YUVRGB2016_128[*cb] );
			FixPixel(inter_var);
			*b = (unsigned char)inter_var;

			inter_var = ( YUVRGB1164_16[*py] + YUVRGB1596_128[*cr] );
			FixPixel(inter_var);
			*r = (unsigned char)inter_var;
			
			py ++;
			cb ++;
			cr ++;
			g ++;
			b ++;
			r ++;
		}

为了防止信号变动造成过载,在256级上下端各留16级作为保护带

for (i = 0; i < frameWidth*frameHeight; i++)
		{
   
			if (gBuf[i] < 16) gBuf[i] = 16;
			if (gBuf[i] > 240) gBuf[i] = 240;
		}

		for (i = 0; i < frameWidth*frameHeight; i++)
		{
   
			if (bBuf[i] < 16) bBuf[i] = 16;
			if (bBuf[i] > 240) bBuf[i] = 240;

			if (rBuf[i] < 16) rBuf[i] = 16;
			if (rBuf[i] > 
  • 0
    点赞
  • 2
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

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

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值