YUV格式与RGB格式图片转换

本文介绍了一个实验,涉及将YUV格式转换为RGB格式的C语言程序。实验详细阐述了转换的算法原理,包括RGB转YUV和YUV转RGB的公式,并分析了4:2:0格式的YUV存储方式。通过编写代码,作者在Visual Studio 2019环境下实现了这一转换,并在实验中遇到了指针错误和RGB值超出范围的问题。最后,作者对比了原RGB图与转换后的图,发现色彩存在偏差,认为这可能源于转换精度和YUV格式下采样导致的信息丢失。
摘要由CSDN通过智能技术生成

实验一 YUV格式与RGB格式图片转换

一、实验内容

1.问题描述

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

2.实验环境

Visual Studio 2019 C语言

二、算法原理

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为4:2:0格式。以宽为256像素为例,4:2:0的存储方式如下图所示:
(自己用PS画的不太好看)
可以看出每4个Y值与1个U和V相对应。而RGB的存储方式如下图所示:
在这里插入图片描述
每个像素对应bgr三个unsigned char。

考虑更简便的算法,按u,v递增的顺序取值,即u1v1,u2v2,…

在这里插入图片描述
先取yuv,再取(y+256)uv,然后y++,再取yuv,再取(y+256)uv,然后y++,u++,v++。这样四个为一组,形成循环。

三、代码

main函数中

	if (argc == 5)
	{
   
		FILE* yuv = fopen(argv[1], "rb");
		FILE* rgb = fopen(argv[2], "wb");
		YUV2RGB(yuv, rgb, atoi(argv[3]), atoi(argv[4]));
		fclose(yuv);
		fclose(rgb);
	}
	else printf("needs 4 arguments");

文件路径和图片大小均由*argv[]传递

查找表
公式中U,V需要减128

static float YUVRGB1403[256], YUVRGB0343[256], YUVRGB0714[256], YUVRGB1770[256];

void Init()
{
   
	int i = 0;
	for (i; i < 256; i++)
	{
   
		YUVRGB1403[i] = 1.403 * (i - 128);
		YUVRGB0343[i] = 0.343 * (i - 128);
		YUVRGB0714[i] = 0.714 * (i - 128);
		YUVRGB1770[i] = 1.770 * (i - 128);
	}
}

定义一个函数保证RGB取值在[0,255]之间

unsigned char Regu(float a)
{
   
	if (a < 0)	return (unsigned char)0;
	else if (a > 255) return (unsigned char)255;
	else return (unsigned char)a;
}

指针的创建:

	unsigned char* y, * u, * v, * bgr, * auxbgr, * start;
	y = (
  • 0
    点赞
  • 1
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值