YUV4:2:0格式与RGB格式的图片转化

实验目的

一、课上老师已给出RGB转YUV格式的示例程序,阅读并理解该程序。
二、编写将YUV转换为RGB的程序。将给定的实验数据用该程序转换为RGB文件。并与原RGB文件进行比较,如果有误差,分析误差形成的原因。

算法基本原理

该实验中,我使用的图像值域是[0,255]。值域为[0,255]常用的转换公式如下。

RGB转YUV的公式:

Y = 0.2990R + 0.5870G + 0.1140B

U = - 0.1684R - 0.3316G + 0.5B + 128

V = 0.5R - 0.4187G - 0.0813B + 128

对应YUV转RGB:

R = Y + 1.403(V - 128)

G = Y - 0.343(U - 128)- 0.714(V - 128)

B = Y + 1.770(U - 128)
YUV流的采样方式

YUV码流的存储格式其实与其采样的方式密切相关,主流的采样方式有三种:

  • YUV4:4:4:表示一个Y分量对应一组UV分量。
  • YUV4:2:2:表示两个Y分量共用一组UV分量。
  • YUV4:1:1: 是在水平方向上对色度进行4:1抽样。
  • YUV4:2:0:表示四个Y分量共用一组UV分量。

下面是四种采样方式的示意图在这里插入图片描述

本实验是:YUV4:2:0 采样方式为: U分量和V分量隔行采样, 同时UV分量在其采样行也是隔行采样。
rgb存储方式是
在这里插入图片描述
每个像素对应bgr三个unsigned char。
为考虑算法简便,这里采用的是按照u,v递增顺序取值
先取yuv,再取(y+256)uv,然后y++,再取yuv,再取(y+256)uv,然后y++,u++,v++。这样四个为一组,形成循环。

代码部分

程序功能函数部分:

void YUV2RGB(FILE* yuv,FILE* rgb,int width,int height)
{
   
	Init();
	int i = 0, j = 0;
	long shape = width * height;
	unsigned char* y, * u, * v, * rgb1, * auxrgb, * start;
	y = (unsigned char*)malloc(sizeof(unsigned char*) * shape);
	u = (unsigned char*)malloc(sizeof(unsigned char*) * shape / 4);
	v = (unsigned char*)malloc(sizeof(unsigned char*) * shape / 4);
	rgb1 = (unsigned char*)malloc(sizeof(unsigned char*) * shape * 3);//没必要将rgb分开,*3即可
	start = rgb1;//rgb1首指针
	fread(y, shape, sizeof(unsigned char), yuv);
	fread(u, shape / 4, sizeof(unsigned char), yuv);
	fread(v, shape / 4, sizeof(unsigned char), yuv);
	for (j = 0; j < height/2; j++)
	{
   
		auxrgb = rgb1 + 3 * width;//偶数行
		for(i=0;i<width/2;i++)
		{
   
			*rgb1++ = Rgu(*y + YUVRGB1403[*u]);
			*rgb1++ = Rgu(*y - YUVRGB0343[*u] - YUVRGB0714[*v])
  • 3
    点赞
  • 3
    收藏
    觉得还不错? 一键收藏
  • 7
    评论

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

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值