yuv和rgb的转换

YUV和RGB格式的转化

1.二者的转化关系

由配色方程我们可以知道其转化关系如下
R = Y + 1.4075 * (V-128);
G = Y - 0.3455 * (U-128) - 0.7169*(V-128);
B = Y + 1.779 * (U-128);

Y = 0.299R + 0.587G + 0.114*B;

U = (B-Y)/1.772;

V = (R-Y)/1.402; (U~(-128-127))

或写为:
Y = 0.299R + 0.587G + 0.114*B;

U = -0.169R - 0.331G + 0.5 *B ;

V = 0.5 R - 0.419G - 0.081*B;

在进行量化并将0电平调制128后我们将方程转化为
Y=0.299R+0.5870G+0.1140B

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

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

2.代码实现

//
#include "stdafx.h"
#include<stdio.h>
#include<stdlib.h>
const int width = 256;
const int height = 256;
int main(int argc, char *argv[])
{
	FILE* rgb = NULL;
	FILE* yuv = NULL;
	rgb = fopen("C:\\Users\\Jack\\Desktop\\新建文件夹 (2)\\rgb2yuv\\down.rgb", "rb");
	yuv = fopen("C:\\Users\\Jack\\Desktop\\新建文件夹 (2)\\rgb2yuv\\down.yuv", "wb");
	//建立缓冲区
	unsigned char* buffer_rgb = (unsigned char*)malloc(sizeof(unsigned char) * 3 * width * height);
	unsigned char* buffer_y = (unsigned char*)malloc(sizeof(unsigned char) * width * height);
	unsigned char* buffer_u = (unsigned char*)malloc(sizeof(unsigned char) * width * height / 4);
	unsigned char* buffer_v = (unsigned char*)malloc(sizeof(unsigned char) * width * height / 4);
	fread(buffer_rgb, sizeof(unsigned char), 3 * width * height, rgb);
	//y分量
	for (int i = 0; i < width * height; i++)
	{
		buffer_y[i] = 0.299 * buffer_rgb[3 * i + 2] + 0.587 * buffer_rgb[3 * i + 1] + 0.114 * buffer_rgb[3 * i];
		if (buffer_y[i] > 235)
			buffer_y[i] = 235;
		else if (buffer_y[i] < 16)
			buffer_y[i] = 16;
	}
	//u分量
	int k = 0;
	for (int i = 0; i < height; i++)
		for (int j = 0; j < width; j++)
		{
			if (i % 2 == 0 && j % 2 == 0)
			{
				buffer_u[k] = -0.1684 * buffer_rgb[3 * (i * width + j) + 2] - 0.3316 * buffer_rgb[3 * (i * width + j) + 1] + 0.5 * buffer_rgb[3 * (i * width + j)] + 128;
				if (buffer_u[k] > 240)
					buffer_u[k] = 240;
				else if (buffer_u[k] < 16)
					buffer_u[k] = 16;
				k++;
			}
		}
	//v分量
	k = 0;
	for (int i = 0; i < height; i++)
		for (int j = 0; j < width; j++)
		{
			if (i % 2 == 0 && j % 2 == 0)
			{
				buffer_v[k] = 0.5 * buffer_rgb[3 * (i * width + j) + 2] - 0.4187 * buffer_rgb[3 * (i * width + j) + 1] - 0.0813 * buffer_rgb[3 * (i * width + j)] + 128;
				if (buffer_v[k] > 240)
					buffer_v[k] = 240;
				else if (buffer_v[k] < 16)
					buffer_v[k] = 16;
				k++;
			}
		}
	//写文件
	fwrite(buffer_y, sizeof(unsigned char), width * height, yuv);
	fwrite(buffer_u, sizeof(unsigned char), width * height / 4, yuv);
	fwrite(buffer_v, sizeof(unsigned char), width * height / 4, yuv);
	//释放
	if (buffer_rgb != NULL)
		free(buffer_rgb);
	if (buffer_y != NULL)
		free(buffer_y);
	if (buffer_u != NULL)
		free(buffer_u);
	if (buffer_v != NULL)
		free(buffer_v);
	if (rgb != NULL)
		fclose(rgb);
	if (yuv != NULL)
		fclose(yuv);
	return 0;
}

将结果用yuv打开效果如下
在这里插入图片描述
将yuv转化为rgb


#include "stdafx.h"


#include<stdio.h>
#include<stdlib.h>
const int width = 256;
const int height = 256;
int main(int argc, char *argv[])
{
	FILE* rgb = NULL;
	FILE* yuv = NULL;
	rgb = fopen("C:\\Users\\Jack\\Desktop\\新建文件夹 (2)\\yuv2rgb\\down.rgb", "wb");
	yuv = fopen("C:\\Users\\Jack\\Desktop\\新建文件夹 (2)\\yuv2rgb\\down.yuv", "rb");

	//建立缓冲区
	unsigned char* buffer_rgb = (unsigned char*)malloc(sizeof(unsigned char) * 3 * width * height);
	unsigned char* buffer_y = (unsigned char*)malloc(sizeof(unsigned char) * width * height);
	unsigned char* buffer_u = (unsigned char*)malloc(sizeof(unsigned char) * width * height / 4);
	unsigned char* buffer_v = (unsigned char*)malloc(sizeof(unsigned char) * width * height / 4);
	fread(buffer_y, sizeof(unsigned char), width * height, yuv);
	fread(buffer_u, sizeof(unsigned char), width * height / 4, yuv);
	fread(buffer_v, sizeof(unsigned char), width * height / 4, yuv);
	unsigned char y[width][height] = { 0 };
	for (int i = 0; i < height; i++)
		for (int j = 0; j < width; j++)
			y[i][j] = buffer_y[i * width + j];
	unsigned char u[width][height] = { 0 };
	unsigned char v[width][height] = { 0 };
	int k = 0;
	for (int i = 0; i<height; i++)
		for (int j = 0; j < width; j++)
		{
			if (i % 2 == 0 && j % 2 == 0)
			{
				u[i][j] = buffer_u[k];
				v[i][j] = buffer_v[k];
				k++;
			}
			else if (i % 2 == 0 && j % 2 == 1)
			{
				u[i][j] = u[i][j - 1];
				v[i][j] = v[i][j - 1];
			}
			else if (i % 2 == 1 && j % 2 == 0)
			{
				u[i][j] = u[i - 1][j];
				v[i][j] = v[i - 1][j];
			}
			else if (i % 2 == 1 && j % 2 == 1)
			{
				u[i][j] = u[i - 1][j - 1];
				v[i][j] = v[i - 1][j - 1];
			}
		}
	for (int i = 0; i<height; i++)
		for (int j = 0; j < width; j++)
		{
			buffer_rgb[3 * (i * width + j)] = y[i][j] + 1.7718 * (u[i][j] - 128) - 0.0013 * (v[i][j] - 128);
			buffer_rgb[3 * (i * width + j) + 1] = y[i][j] - 0.3441 * (u[i][j] - 128) - 0.7139 * (v[i][j] - 128);
			buffer_rgb[3 * (i * width + j) + 2] = y[i][j] + 1.4020 * (v[i][j] - 128);
		}
	fwrite(buffer_rgb, sizeof(unsigned char), 3 * width * height, rgb);
	if (buffer_rgb != NULL)
		free(buffer_rgb);
	if (buffer_y != NULL)
		free(buffer_y);
	if (buffer_u != NULL)
		free(buffer_u);
	if (buffer_v != NULL)
		free(buffer_v);
	if (rgb != NULL)
		fclose(rgb);
	if (yuv != NULL)
		fclose(yuv);
	return 0;
}


  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值