实验一 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的存储方式如下图所示:
可以看出每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 = (