数据压缩 实验一 YUV与RGB彩色空间转换

YUV与RGB彩色空间转换

YUV与RGB转换公式

Y=0.2990R+0.5870G+0.1140B
U=-0.1684R-0.3316G+0.5B
V=0.5R-0.4187G-0.0813B

R = Y+1.4075V
G = Y-0.3455U-0.7169V
B = Y+1.7790U

YUV转RGB实现算法

主函数

分配缓冲区

	/* get an output buffer for a frame */
	rgbBuf = (u_int8_t*)malloc(frameWidth * frameHeight * 3);

	/* get the input buffers for a frame */
	yuvBuf = (u_int8_t*)malloc(frameWidth * frameHeight * 3 / 2);
	yBuf = yuvBuf;
	uBuf = yuvBuf + (frameWidth * frameHeight);
	vBuf = yuvBuf + (frameHeight * frameWidth * 5 / 4);

读出与写入图像

	while (fread(yuvBuf, 1, frameWidth * frameHeight * 3 / 2, yuvFile))
	{
		if(YUV2RGB(frameWidth, frameHeight, yBuf, uBuf, vBuf, rgbBuf, flip))
		{
			printf("error");
			return 0;
					}

		fwrite(rgbBuf, 1, frameWidth * frameHeight * 3, rgbFile);

		printf("\r...%d", ++videoFramesWritten);
	}

	printf("\n%u %ux%u video frames written\n", 
		videoFramesWritten, frameWidth, frameHeight);

部分查找表

static float YUVRGB14075[256], YUVRGB03455[256];
static float YUVRGB07169[256], YUVRGB17790[256];

void InitLookupTable()
{
	int i;

	for (i = 0; i < 256; i++) YUVRGB14075[i] = (float)1.4075 * (i - 128);
	for (i = 0; i < 256; i++) YUVRGB03455[i] = (float)0.3455 * (i - 128);
	for (i = 0; i < 256; i++) YUVRGB07169[i] = (float)0.7169 * (i - 128);
	for (i = 0; i < 256; i++) YUVRGB17790[i] = (float)1.7790 * (i - 128);
}

YUV到RGB转换函数

分配内存

	y_buffer = (unsigned char *)y_in;
	u_buffer = (unsigned char *)u_in;
	v_buffer = (unsigned char *)v_in;
	rgb = (unsigned char*)malloc(3 * size * sizeof(unsigned char));
	if (!(rgb))
	{
		free(rgb);
		return 2;
	}
	rgb_buffer = (unsigned char *)rgb_out;

YUV转换为RGB,分别求出B、G、R的值,求得的电平低于0时为0,高于255时为255,以此作为保护

for (j = 0; j < (y_dim / 2); j++)
		for (i = 0; i < (x_dim / 2); i++)
		{
			/* B */
			if ((y_buffer[2 * j * x_dim + 2 * i] + YUVRGB17790[*u_buffer]) > 255)
				rgb[2 * j * 3 * x_dim + 6 * i] = 255;
			else if ((y_buffer[2 * j * x_dim + 2 * i] + YUVRGB17790[*u_buffer]) < 0)
				rgb[2 * j * 3 * x_dim + 6 * i] = 0;
			else
				rgb[2 * j * 3 * x_dim + 6 * i] = (unsigned char)(y_buffer[2 * j * x_dim + 2 * i] + YUVRGB17790[*u_buffer]);
			
			if ((y_buffer[(2 * j + 1) * x_dim + 2 * i] + YUVRGB17790[*u_buffer]) > 255)
				rgb[(2 * j + 1) * 3 * x_dim + 6 * i] = 255;
			else if ((y_buffer[(2 * j + 1) * x_dim + 2 * i] + YUVRGB17790[*u_buffer]) < 0)
				rgb[(2 * j + 1) * 3 * x_dim + 6 * i] = 0;
			else
			    rgb[(2 * j + 1) * 3 * x_dim + 6 * i] = (unsigned char)(y_buffer[(2 * j + 1) * x_dim + 2 * i] + YUVRGB17790[*u_buffer]);

			if ((y_buffer[2 * j * x_dim + 2 * i + 1] + YUVRGB17790[*u_buffer]) > 255)
				rgb[2 * j * 3 * x_dim + 6 * i + 3] = 255;
			else if ((y_buffer[2 * j * x_dim + 2 * i + 1] + YUVRGB17790[*u_buffer]) < 0)
				rgb[2 * j * 3 * x_dim + 6 * i + 3] = 0;
			else
				rgb[2 * j * 3 * x_dim + 6 * i + 3] = (unsigned char)(y_buffer[2 * j * x_dim + 2 * i + 1] + YUVRGB17790[*u_buffer]);

			if ((y_buffer[(2 * j + 1) * x_dim + 2 * i + 1] + YUVRGB17790[*u_buffer]) > 255)
				rgb[(2 * j + 1) * 3 * x_dim + 6 * i + 3] = 255;
			else if ((y_buffer[(2 * j + 1) * x_dim + 2 * i + 1] + YUVRGB17790[*u_buffer]) < 0)
				rgb[(2 * j + 1) * 3 * x_dim + 6 * i + 3] = 0;
			else
			    rgb[(2 * j + 1) * 3 * x_dim + 6 * i + 3] = (unsigned char)(y_buffer[(2 * j + 1) * x_dim + 2 * i + 1] + YUVRGB17790[*u_buffer]);

			/* G */
			if ((y_buffer[2 * j * x_dim + 2 * i] - YUVRGB03455[*u_buffer] - YUVRGB07169[*v_buffer]) > 255)
				rgb[2 * j * 3 * x_dim + 6 * i + 1] = 255;
			else if ((y_buffer[2 * j * x_dim + 2 * i] - YUVRGB03455[*u_buffer] - YUVRGB07169[*v_buffer]) < 0)
				rgb[2 * j * 3 * x_dim + 6 * i + 1] = 0;
			else
			    rgb[2 * j * 3 * x_dim + 6 * i + 1] = (unsigned char)(y_buffer[2 * j * x_dim + 2 * i] - YUVRGB03455[*u_buffer] - YUVRGB07169[*v_buffer]);

			if ((y_buffer[(2 * j + 1) * x_dim + 2 * i] - YUVRGB03455[*u_buffer] - YUVRGB07169[*v_buffer]) > 255)
				rgb[(2 * j + 1) * 3 * x_dim + 6 * i + 1] = 255;
			else if ((y_buffer[(2 * j + 1) * x_dim + 2 * i] - YUVRGB03455[*u_buffer] - YUVRGB07169[*v_buffer]) < 0)
				rgb[(2 * j + 1) * 3 * x_dim + 6 * i + 1] = 0;
			else
			    rgb[(2 * j + 1) * 3 * x_dim + 6 * i + 1] = (unsigned char)(y_buffer[(2 * j + 1) * x_dim + 2 * i] - YUVRGB03455[*u_buffer] - YUVRGB07169[*v_buffer]);

			if ((y_buffer[2 * j * x_dim + 2 * i + 1] - YUVRGB03455[*u_buffer] - YUVRGB07169[*v_buffer]) > 255)
				rgb[2 * j * 3 * x_dim + 6 * i + 4] = 255;
			else if ((y_buffer[2 * j * x_dim + 2 * i + 1] - YUVRGB03455[*u_buffer] - YUVRGB07169[*v_buffer]) < 0)
				rgb[2 * j * 3 * x_dim + 6 * i + 4] = 0;
			else
			    rgb[2 * j * 3 * x_dim + 6 * i + 4] = (unsigned char)(y_buffer[2 * j * x_dim + 2 * i + 1] - YUVRGB03455[*u_buffer] - YUVRGB07169[*v_buffer]);

			if ((y_buffer[(2 * j + 1) * x_dim + 2 * i + 1] - YUVRGB03455[*u_buffer] - YUVRGB07169[*v_buffer]) > 255)
				rgb[(2 * j + 1) * 3 * x_dim + 6 * i + 4] = 255;
			else if ((y_buffer[(2 * j + 1) * x_dim + 2 * i + 1] - YUVRGB03455[*u_buffer] - YUVRGB07169[*v_buffer]) < 0)
				rgb[(2 * j + 1) * 3 * x_dim + 6 * i + 4] = 0;
			else
			    rgb[(2 * j + 1)* 3 * x_dim + 6 * i + 4] = (unsigned char)(y_buffer[(2 * j + 1) * x_dim + 2 * i + 1] - YUVRGB03455[*u_buffer] - YUVRGB07169[*v_buffer]);
			
			/* R */
			if ((y_buffer[2 * j * x_dim + 2 * i] + YUVRGB14075[*v_buffer]) > 255)
				rgb[2 * j * 3 * x_dim + 6 * i + 2] = 255;
			else if ((y_buffer[2 * j * x_dim + 2 * i] + YUVRGB14075[*v_buffer]) < 0)
				rgb[2 * j * 3 * x_dim + 6 * i + 2] = 0;
			else
			    rgb[2 * j * 3 * x_dim + 6 * i + 2] = (unsigned char)(y_buffer[2 * j * x_dim + 2 * i] + YUVRGB14075[*v_buffer]);

			if ((y_buffer[(2 * j + 1) * x_dim + 2 * i] + YUVRGB14075[*v_buffer]) > 255)
				rgb[(2 * j + 1) * 3 * x_dim + 6 * i + 2] = 255;
			else if ((y_buffer[(2 * j + 1) * x_dim + 2 * i] + YUVRGB14075[*v_buffer]) < 0)
				rgb[(2 * j + 1) * 3 * x_dim + 6 * i + 2] = 0;
			else
			    rgb[(2 * j + 1) * 3 * x_dim + 6 * i + 2] = (unsigned char)(y_buffer[(2 * j + 1) * x_dim + 2 * i] + YUVRGB14075[*v_buffer]);

			if ((y_buffer[2 * j * x_dim + 2 * i + 1] + YUVRGB14075[*v_buffer]) > 255)
				rgb[2 * j * 3 * x_dim + 6 * i + 5] = 255;
			else if ((y_buffer[2 * j * x_dim + 2 * i + 1] + YUVRGB14075[*v_buffer]) < 0)
				rgb[2 * j * 3 * x_dim + 6 * i + 5] = 0;
			else
			    rgb[2 * j * 3 * x_dim + 6 * i + 5] = (unsigned char)(y_buffer[2 * j * x_dim + 2 * i + 1] + YUVRGB14075[*v_buffer]);

			if ((y_buffer[(2 * j + 1) * x_dim + 2 * i + 1] + YUVRGB14075[*v_buffer]) > 255)
				rgb[(2 * j + 1) * 3 * x_dim + 6 * i + 5] = 255;
			else if ((y_buffer[(2 * j + 1) * x_dim + 2 * i + 1] + YUVRGB14075[*v_buffer]) < 0)
				rgb[(2 * j + 1) * 3 * x_dim + 6 * i + 5] = 0;
			else
			    rgb[(2 * j + 1) * 3 * x_dim + 6 * i + 5] = (unsigned char)(y_buffer[(2 * j + 1) * x_dim + 2 * i + 1] + YUVRGB14075[*v_buffer]);

			u_buffer++;
			v_buffer++;
		}

上下翻转图像

	if (flip) {
		for (j = 0; j < y_dim; j++)
			for (i = 0; i < x_dim * 3; i++) {
				*rgb_buffer = rgb[(y_dim - j - 1) * x_dim * 3 + i];
				rgb_buffer++;
			}
	}
	else {
		rgb_buffer=rgb;
	}

实验结果

在这里插入图片描述

用YUV Viewer播放器查看结果,与原始图像一致
在这里插入图片描述

评论 1
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值