彩色空间转换(修订之后)

首先开辟一个缓存区。

int w=256;
int h=256;//程序初始化(打开两个文件、定义变量和缓冲区等)
FILE* rgbFile=NULL;
FILE* yuvFile = NULL;
unsigned char*R,*G,*B,*pf,*Y,*U,*V,*u,*v;
//打开rgb文件
rgbFile = fopen("D:\\dsx\\sjys\\down.rgb", "rb");
//开辟缓存区

彩色空间转换公式
(1) YUV2RGB的转换公式
由电视原理可知,亮度和色差信号的构成如下:
Y=0.2990R+0.5870G+0.1140B
R-Y=0.7010R-0.5870G-0.1140B
B-Y=-0.2990R-0.5870G+0.8860B

为了使色差信号的动态范围控制在0.5之间,需要进行归一化,对色差信号引入压缩系数。归一化后的色差信号为:
U=-0.1684R-0.3316G+0.5B
V=0.5R-0.4187G-0.0813B

(2) YUV2RGB空间的转换公式
R = Y+(R-Y) = Y+1.14075(V-128)
G = Y+(G-Y) = Y-0.7169(V-128)-0.3455(U-128)
B = Y+(B-Y) = Y+1.779(U-128)

pf = (unsigned char *)malloc(sizeof(char)*(w*h*3));
R = (unsigned char *)malloc(sizeof(char)*(w*h));
G = (unsigned char *)malloc(sizeof(char)*(w*h));
B = (unsigned char *)malloc(sizeof(char)*(w*h));
Y = (unsigned char *)malloc(sizeof(char)*(w*h));
U = (unsigned char *)malloc(sizeof(char)*(w*h));
V = (unsigned char *)malloc(sizeof(char)*(w*h));
u=(unsigned char *)malloc(sizeof(char)*(w*h/4));
v=(unsigned char *)malloc(sizeof(char)*(w*h/4));
fread(pf,1,w*h*3,rgbFile);
int i,j,k=0;
//提取RGB分量
for(i=0,j=0;i<w*h*3;i=i+3,j++)
	{
	R[j]=pf[i+2];
	G[j]=pf[i+1];
	B[j]=pf[i];
	}
//计算YUV分量
for(i=0,j=0;i<w*h;i++,j++)
{
	Y[j]=0.2990*R[i]+0.5870*G[i]+0.1140*B[i];
	U[j]=-0.1684*R[i]-0.3316*G[i]+0.5*B[i]+128;
	V[j]=0.5*R[i]-0.4187*G[i]-0.0813*B[i]+128;
}
//对UV下采样

3.码电平分配及数字表达式
亮电平信号量化后码电平分配与色差信号量化后码电平分配:

   for(i=0;i<h;i=i+2)
{
	for(j=0;j<w;j=j+2)
	{
	u[k]=(U[w*i+j]+U[w*i+j+1]+U[(i+1)*w+j]+U[(i+1)*w+j+1])/4;
	v[k]=(V[w*i+j]+V[w*i+j+1]+V[(i+1)*w+j]+V[(i+1)*w+j+1])/4;
	
	k++;
	}
}
//YUV量化后码电平分配
for(k=0;k<w*h;k++)
{
	if(Y[k]>235)
		Y[k]=235;
	 if(Y[k]<16)
		Y[k]=16;
}
for(k=0;k<w*h/4;k++)
{
	if(u[k]>240)
		u[k]=240;
	if(u[k]<16)
		u[k]=16;
	if(v[k]>240)
		v[k]=240;
	if(v[k]<16)
		v[k]=16;
}
yuvFile = fopen("D:\\dsx\\sjys\\down.yuv", "wb");

fwrite(pf,1,w*h*3,yuvFile);
fwrite(Y,1,w*h,yuvFile);
fwrite(u,1,w*h/4,yuvFile);
fwrite(v,1,w*h/4,yuvFile);
	free(pf);
	free(R);
	free(G);
	free(B);
	free(Y);
	free(U);
	free(V);
	free(u);
	free(v);
	fclose(rgbFile);
	fclose(yuvFile);
return 0;
}

在这里插入图片描述
YUV转RGB

#include <malloc.h>
#include <stdio.h>
#include <stdlib.h>
int main(int argc,char* argv[])
{
	int w=256;
	int h=256;
	//程序初始化(打开两个文件、定义变量和缓冲区等)
	FILE* rgbFile=NULL;
	FILE* yuvFile = NULL;
	unsigned char*R,*G,*B,*pf,*Y,*U,*V,*u,*v;
	//打开yuv文件
	yuvFile = fopen(argv[1], "rb");
	//开辟缓存区
    pf = (unsigned char *)malloc(sizeof(char)*(w*h*3));
	R = (unsigned char *)malloc(sizeof(char)*(w*h));
	G = (unsigned char *)malloc(sizeof(char)*(w*h));
	B = (unsigned char *)malloc(sizeof(char)*(w*h));
	Y = (unsigned char *)malloc(sizeof(char)*(w*h));
	U = (unsigned char *)malloc(sizeof(char)*(w*h));
	V = (unsigned char *)malloc(sizeof(char)*(w*h));
	u=(unsigned char *)malloc(sizeof(char)*(w*h/4));
	v=(unsigned char *)malloc(sizeof(char)*(w*h/4));
	fread(Y,1,w*h,yuvFile);
	fread(u,1,w*h/4,yuvFile);
	fread(v,1,w*h/4,yuvFile);
	int i,j,k=0;
	//上采样
	for(i=0;i<h;i=i+2)
	{
		for(j=0;j<w;j=j+2)
		{
		U[w*i+j]=U[w*i+j+1]=U[(i+1)*w+j]=U[(i+1)*w+j+1]=u[k];
		V[w*i+j]=V[w*i+j+1]=V[(i+1)*w+j]=V[(i+1)*w+j+1]=v[k];
		k++;
		}
	}
	//计算RGB
	for(i=0,j=0;i<w*h;i++,j++)
	{
		R[j]=Y[i]+1.14075*(V[i]-128);
		G[j]=Y[i]-0.7169*(V[i]-128)-0.3455*(U[i]-128);
		B[j]=Y[i]+1.779*(U[i]-128);
	}
	rgbFile = fopen(argv[2], "wb");
	for(i=0,j=0;i<w*h*3;i=i+3,j++)
		{
		pf[i+2]=R[j];
		pf[i+1]=G[j];
		pf[i]=B[j];
		}
	fwrite(pf,1,w*h*3,rgbFile);
		free(pf);
		free(R);
		free(G);
		free(B);
		free(Y);
		free(U);
		free(V);
		free(u);
		free(v);
		fclose(rgbFile);
		fclose(yuvFile);
	return 0;
}

在这里插入图片描述
目测不太明显,但实际上下采样和量化后码电平分配会造成部分数据丢失。

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

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

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值